# Conflicts:
#	submodules/TelegramApi/Sources/Api15.swift
#	submodules/TelegramApi/Sources/Api28.swift
#	submodules/TelegramApi/Sources/Api4.swift
This commit is contained in:
Isaac 2026-02-19 21:20:55 +01:00
commit 0aae6101a3
9 changed files with 83 additions and 30 deletions

View file

@ -15801,3 +15801,15 @@ Error: %8$@";
"FormattedDate.LongDate_m10" = "October %1$@, %2$@";
"FormattedDate.LongDate_m11" = "November %1$@, %2$@";
"FormattedDate.LongDate_m12" = "December %1$@, %2$@";
"Gift.Sell.Confirm.Title" = "Confirm Sale";
"Gift.Sell.Confirm.Text" = "Do you want to list **%1$@** for sale at %2$@?";
"Gift.Sell.Confirm.ListFor_1" = "List for %@ Star";
"Gift.Sell.Confirm.ListFor_any" = "List for %@ Stars";
"Gift.Sell.Confirm.ListForTon" = "List for %@ TON";
"Notification.CopyProtection.Enabled" = "%1$@ disabled sharing in this chat";
"Notification.CopyProtection.EnabledYou" = "You disabled sharing in this chat";
"Notification.CopyProtection.Disabled" = "%1$@ enabled sharing in this chat";
"Notification.CopyProtection.DisabledYou" = "You enabled sharing in this chat";
"Notification.CopyProtection.StillEnabled" = "Sharing in this chat is still disabled";

View file

@ -215,7 +215,7 @@ extension ChannelParticipant {
let (flags, userId, restrictedBy, date, bannedRights) = (channelParticipantBannedData.flags, channelParticipantBannedData.peer, channelParticipantBannedData.kickedBy, channelParticipantBannedData.date, channelParticipantBannedData.bannedRights)
let hasLeft = (flags & (1 << 0)) != 0
let banInfo = ChannelParticipantBannedInfo(rights: TelegramChatBannedRights(apiBannedRights: bannedRights), restrictedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(restrictedBy)), timestamp: date, isMember: !hasLeft)
self = .member(id: userId.peerId, invitedAt: date, adminInfo: nil, banInfo: banInfo, rank: nil, subscriptionUntilDate: nil)
self = .member(id: userId.peerId, invitedAt: date, adminInfo: nil, banInfo: banInfo, rank: channelParticipantBannedData.rank, subscriptionUntilDate: nil)
case let .channelParticipantAdmin(channelParticipantAdminData):
let (flags, userId, _, promotedBy, date, adminRights, rank) = (channelParticipantAdminData.flags, channelParticipantAdminData.userId, channelParticipantAdminData.inviterId, channelParticipantAdminData.promotedBy, channelParticipantAdminData.date, channelParticipantAdminData.adminRights, channelParticipantAdminData.rank)
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(promotedBy)), canBeEditedByAccountPeer: (flags & (1 << 0)) != 0), banInfo: nil, rank: rank, subscriptionUntilDate: nil)

View file

@ -240,7 +240,7 @@ func apiMessagePeerIds(_ message: Api.Message) -> [PeerId] {
}
switch action {
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks, .messageActionSuggestedPostApproval, .messageActionGiftTon, .messageActionSuggestedPostSuccess, .messageActionSuggestedPostRefund, .messageActionSuggestBirthday, .messageActionStarGiftPurchaseOffer, .messageActionStarGiftPurchaseOfferDeclined:
case .messageActionChannelCreate, .messageActionChatDeletePhoto, .messageActionChatEditPhoto, .messageActionChatEditTitle, .messageActionEmpty, .messageActionPinMessage, .messageActionHistoryClear, .messageActionGameScore, .messageActionPaymentSent, .messageActionPaymentSentMe, .messageActionPhoneCall, .messageActionScreenshotTaken, .messageActionCustomAction, .messageActionBotAllowed, .messageActionSecureValuesSent, .messageActionSecureValuesSentMe, .messageActionContactSignUp, .messageActionGroupCall, .messageActionSetMessagesTTL, .messageActionGroupCallScheduled, .messageActionSetChatTheme, .messageActionChatJoinedByRequest, .messageActionWebViewDataSent, .messageActionWebViewDataSentMe, .messageActionGiftPremium, .messageActionGiftStars, .messageActionTopicCreate, .messageActionTopicEdit, .messageActionSuggestProfilePhoto, .messageActionSetChatWallPaper, .messageActionGiveawayLaunch, .messageActionGiveawayResults, .messageActionBoostApply, .messageActionRequestedPeerSentMe, .messageActionStarGift, .messageActionStarGiftUnique, .messageActionPaidMessagesRefunded, .messageActionPaidMessagesPrice, .messageActionTodoCompletions, .messageActionTodoAppendTasks, .messageActionSuggestedPostApproval, .messageActionGiftTon, .messageActionSuggestedPostSuccess, .messageActionSuggestedPostRefund, .messageActionSuggestBirthday, .messageActionStarGiftPurchaseOffer, .messageActionStarGiftPurchaseOfferDeclined, .messageActionNoForwardsToggle, .messageActionNoForwardsRequest:
break
case let .messageActionChannelMigrateFrom(messageActionChannelMigrateFromData):
let chatId = messageActionChannelMigrateFromData.chatId

View file

@ -349,16 +349,20 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
return nil
}
return TelegramMediaAction(action: .starGiftPurchaseOfferDeclined(gift: gift, amount: CurrencyAmount(apiAmount: price), hasExpired: (flags & (1 << 0)) != 0))
case let .messageActionNewCreatorPending(messageActionNewCreatorPending):
case let .messageActionNewCreatorPending(messageActionNewCreatorPendingData):
return TelegramMediaAction(action: .groupCreatorChange(TelegramMediaActionType.GroupCreatorChange(
kind: .pending,
targetPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(messageActionNewCreatorPending.newCreatorId))
targetPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(messageActionNewCreatorPendingData.newCreatorId))
)))
case let .messageActionChangeCreator(messageActionChangeCreator):
case let .messageActionChangeCreator(messageActionChangeCreatorData):
return TelegramMediaAction(action: .groupCreatorChange(TelegramMediaActionType.GroupCreatorChange(
kind: .applied,
targetPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(messageActionChangeCreator.newCreatorId))
targetPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(messageActionChangeCreatorData.newCreatorId))
)))
case let .messageActionNoForwardsToggle(messageActionNoForwardsToggleData):
return TelegramMediaAction(action: .copyProtectionToggle(previousValue: messageActionNoForwardsToggleData.prevValue == .boolTrue, newValue: messageActionNoForwardsToggleData.newValue == .boolTrue))
case let .messageActionNoForwardsRequest(messageActionNoForwardsRequestData):
return TelegramMediaAction(action: .copyProtectionRequest(hasExpired: (messageActionNoForwardsRequestData.flags & (1 << 0)) != 0, previousValue: messageActionNoForwardsRequestData.prevValue == .boolTrue, newValue: messageActionNoForwardsRequestData.newValue == .boolTrue))
}
}

View file

@ -2025,26 +2025,6 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
updatedState.updateStarGiftAuctionMyState(giftId: giftId, state: GiftAuctionContext.State.MyState(apiAuctionUserState: userState))
case let .updateEmojiGameInfo(updateEmojiGameInfoData):
updatedState.updateEmojiGameInfo(info: EmojiGameInfo(apiEmojiGameInfo: updateEmojiGameInfoData.info))
case let .updatePeerHistoryNoForwards(updatePeerHistoryNoForwardsData):
let (flags, peer) = (updatePeerHistoryNoForwardsData.flags, updatePeerHistoryNoForwardsData.peer)
let peerId = peer.peerId
updatedState.updateCachedPeerData(peerId, { current in
if let previous = current as? CachedUserData {
var updatedFlags = previous.flags
if (flags & (1 << 0)) != 0 {
updatedFlags.insert(.myCopyProtectionEnabled)
} else {
updatedFlags.remove(.myCopyProtectionEnabled)
}
if (flags & (1 << 1)) != 0 {
updatedFlags.insert(.copyProtectionEnabled)
} else {
updatedFlags.remove(.copyProtectionEnabled)
}
return previous.withUpdatedFlags(updatedFlags)
}
return current
})
default:
break
}
@ -4321,6 +4301,19 @@ func replayFinalState(
}
})
}
case let .copyProtectionToggle(_, newValue):
transaction.updatePeerCachedData(peerIds: [message.id.peerId], update: { peerId, current in
if let previous = current as? CachedUserData {
var updatedFlags = previous.flags
if newValue {
updatedFlags.insert(.copyProtectionEnabled)
} else {
updatedFlags.remove(.copyProtectionEnabled)
}
return previous.withUpdatedFlags(updatedFlags)
}
return current
})
default:
break
}

View file

@ -302,6 +302,8 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
case starGiftPurchaseOffer(gift: StarGift, amount: CurrencyAmount, expireDate: Int32, isAccepted: Bool, isDeclined: Bool)
case starGiftPurchaseOfferDeclined(gift: StarGift, amount: CurrencyAmount, hasExpired: Bool)
case groupCreatorChange(GroupCreatorChange)
case copyProtectionToggle(previousValue: Bool, newValue: Bool)
case copyProtectionRequest(hasExpired: Bool, previousValue: Bool, newValue: Bool)
public init(decoder: PostboxDecoder) {
let rawValue: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
@ -475,6 +477,10 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
self = .starGiftPurchaseOfferDeclined(gift: decoder.decodeObjectForKey("gift", decoder: { StarGift(decoder: $0) }) as! StarGift, amount: decoder.decodeCodable(CurrencyAmount.self, forKey: "amount")!, hasExpired: decoder.decodeBoolForKey("hasExpired", orElse: false))
case 59:
self = .groupCreatorChange(decoder.decodeCodable(GroupCreatorChange.self, forKey: "d") ?? GroupCreatorChange(kind: .pending, targetPeerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(0))))
case 60:
self = .copyProtectionToggle(previousValue: decoder.decodeBoolForKey("previousValue", orElse: false), newValue: decoder.decodeBoolForKey("newValue", orElse: false))
case 61:
self = .copyProtectionRequest(hasExpired: decoder.decodeBoolForKey("hasExpired", orElse: false), previousValue: decoder.decodeBoolForKey("previousValue", orElse: false), newValue: decoder.decodeBoolForKey("newValue", orElse: false))
default:
self = .unknown
}
@ -969,6 +975,15 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
case let .groupCreatorChange(groupCreatorChange):
encoder.encodeInt32(59, forKey: "_rawValue")
encoder.encodeCodable(groupCreatorChange, forKey: "d")
case let .copyProtectionToggle(previousValue, newValue):
encoder.encodeInt32(60, forKey: "_rawValue")
encoder.encodeBool(previousValue, forKey: "previousValue")
encoder.encodeBool(newValue, forKey: "newValue")
case let .copyProtectionRequest(hasExpired, previousValue, newValue):
encoder.encodeInt32(61, forKey: "_rawValue")
encoder.encodeBool(hasExpired, forKey: "hasExpired")
encoder.encodeBool(previousValue, forKey: "previousValue")
encoder.encodeBool(newValue, forKey: "newValue")
}
}

View file

@ -4,10 +4,14 @@ import SwiftSignalKit
import TelegramApi
import MtProtoKit
func _internal_toggleMessageCopyProtection(account: Account, peerId: PeerId, enabled: Bool) -> Signal<Void, NoError> {
func _internal_toggleMessageCopyProtection(account: Account, peerId: PeerId, enabled: Bool, requestMessageId: EngineMessage.Id?) -> Signal<Void, NoError> {
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
return account.network.request(Api.functions.messages.toggleNoForwards(peer: inputPeer, enabled: enabled ? .boolTrue : .boolFalse)) |> `catch` { _ in .complete() } |> map { updates -> Void in
var flags: Int32 = 0
if let _ = requestMessageId {
flags = (1 << 0)
}
return account.network.request(Api.functions.messages.toggleNoForwards(flags: flags, peer: inputPeer, enabled: enabled ? .boolTrue : .boolFalse, requestMsgId: requestMessageId?.id)) |> `catch` { _ in .complete() } |> map { updates -> Void in
account.stateManager.addUpdates(updates)
}
} else {

View file

@ -505,8 +505,8 @@ public extension TelegramEngine {
return _internal_toggleShouldChannelMessagesSignatures(account: self.account, peerId: peerId, signaturesEnabled: signaturesEnabled, profilesEnabled: profilesEnabled)
}
public func toggleMessageCopyProtection(peerId: PeerId, enabled: Bool) -> Signal<Void, NoError> {
return _internal_toggleMessageCopyProtection(account: self.account, peerId: peerId, enabled: enabled)
public func toggleMessageCopyProtection(peerId: PeerId, enabled: Bool, requestMessageId: EngineMessage.Id? = nil) -> Signal<Void, NoError> {
return _internal_toggleMessageCopyProtection(account: self.account, peerId: peerId, enabled: enabled, requestMessageId: requestMessageId)
}
public func toggleChannelJoinToSend(peerId: PeerId, enabled: Bool) -> Signal<Never, UpdateChannelJoinToSendError> {

View file

@ -1754,6 +1754,31 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
case .applied:
attributedString = addAttributesToStringWithRanges(strings.Notification_GroupCreatorChangeApplied(authorName, targetName)._tuple, body: bodyAttributes, argumentAttributes: peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: [(0, message.author?.id), (1, groupCreatorChange.targetPeerId)]))
}
case let .copyProtectionToggle(previousValue, newValue):
//TODO:localize
if previousValue == newValue && newValue {
attributedString = NSAttributedString(string: strings.Notification_CopyProtection_StillEnabled, font: titleFont, textColor: primaryTextColor)
} else if message.author?.id == accountPeerId {
if newValue {
attributedString = NSAttributedString(string: strings.Notification_CopyProtection_EnabledYou, font: titleFont, textColor: primaryTextColor)
} else {
attributedString = NSAttributedString(string: strings.Notification_CopyProtection_DisabledYou, font: titleFont, textColor: primaryTextColor)
}
} else {
let peerName = message.peers[message.id.peerId].flatMap { EnginePeer($0) }?.compactDisplayTitle ?? ""
let peerIds: [(Int, EnginePeer.Id?)] = [(0, message.id.peerId)]
let attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
if newValue {
attributedString = addAttributesToStringWithRanges(strings.Notification_CopyProtection_Enabled(peerName)._tuple, body: bodyAttributes, argumentAttributes: attributes)
} else {
attributedString = addAttributesToStringWithRanges(strings.Notification_CopyProtection_Disabled(peerName)._tuple, body: bodyAttributes, argumentAttributes: attributes)
}
}
case let .copyProtectionRequest(hasExpired, previousValue, newValue):
let _ = hasExpired
let _ = previousValue
let _ = newValue
attributedString = nil
case .unknown:
attributedString = nil
}