Version 11.9

This commit is contained in:
Kylmakalle
2024-07-02 19:58:37 +03:00
parent 587ac7bf00
commit 833ecbc777
797 changed files with 40411 additions and 2895 deletions

View File

@@ -1,3 +1,6 @@
import SGStrings
import SGSimpleSettings
import PeerInfoUI
import Foundation
import UIKit
import Postbox
@@ -485,6 +488,16 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
if case .standard(.embedded) = chatPresentationInterfaceState.mode {
isEmbeddedMode = true
}
// MARK: Swiftgram
var canReveal = false
if !chatPresentationInterfaceState.copyProtectionEnabled {
outer: for message in messages {
if message.canRevealContent(contentSettings: context.currentContentSettings.with { $0 }) {
canReveal = true
break outer
}
}
}
if case let .customChatContents(customChatContents) = chatPresentationInterfaceState.subject, case .hashTagSearch = customChatContents.kind {
isEmbeddedMode = true
@@ -633,7 +646,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
messageEntities = attribute.entities
}
if let attribute = attribute as? RestrictedContentMessageAttribute {
restrictedText = attribute.platformText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) ?? ""
restrictedText = attribute.platformText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }, chatId: message.author?.id.id._internalGetInt64Value()) ?? ""
}
}
@@ -927,6 +940,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
let isPremium = accountPeer?.isPremium ?? false
var actions: [ContextMenuItem] = []
var sgActions: [ContextMenuItem] = []
var isPinnedMessages = false
if case .pinnedMessages = chatPresentationInterfaceState.subject {
@@ -1161,6 +1175,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
})
})
})))
if !SGSimpleSettings.shared.contextShowReply { sgActions.append(actions.removeLast()) }
}
if data.messageActions.options.contains(.sendScheduledNow) {
@@ -1268,7 +1283,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
messageEntities = attribute.entities
}
if let attribute = attribute as? RestrictedContentMessageAttribute {
restrictedText = attribute.platformText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) ?? ""
restrictedText = attribute.platformText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }, chatId: message.author?.id.id._internalGetInt64Value()) ?? ""
}
}
@@ -1385,6 +1400,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
})
f(.default)
})))
if !SGSimpleSettings.shared.contextShowSaveMedia { sgActions.append(actions.removeLast()) }
}
}
@@ -1430,6 +1446,18 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
})))
}
let showJsonAction: ContextMenuItem = .action(ContextMenuActionItem(text: "JSON", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Settings"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
showMessageJson(controllerInteraction: controllerInteraction, chatPresentationInterfaceState: chatPresentationInterfaceState, message: message, context: context)
f(.default)
}))
if SGSimpleSettings.shared.contextShowJson {
actions.append(showJsonAction)
} else {
sgActions.append(showJsonAction)
}
var threadId: Int64?
var threadMessageCount: Int = 0
if case .peer = chatPresentationInterfaceState.chatLocation, let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, case .group = channel.info {
@@ -1468,6 +1496,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
controllerInteraction.openMessageReplies(messages[0].id, true, true)
})
})))
if !SGSimpleSettings.shared.contextShowMessageReplies { sgActions.append(actions.removeLast()) }
}
let isMigrated: Bool
@@ -1545,6 +1574,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
interfaceInteraction.pinMessage(messages[0].id, c)
})))
}
if !SGSimpleSettings.shared.contextShowPin { sgActions.append(actions.removeLast()) }
}
if let activePoll = activePoll, messages[0].forwardInfo == nil {
@@ -1717,18 +1747,52 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuForward, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
interfaceInteraction.forwardMessages(selectAll || isImage ? messages : [message])
interfaceInteraction.forwardMessages(selectAll || isImage ? messages : [message], nil)
f(.dismissWithoutContent)
})))
if message.id.peerId != context.account.peerId {
let action: ContextMenuItem = .action(ContextMenuActionItem(text: i18n("ContextMenu.SaveToCloud", chatPresentationInterfaceState.strings.baseLanguageCode), icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Fave"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
interfaceInteraction.forwardMessages(selectAll || isImage ? messages : [message], "forwardMessagesToCloud")
f(.dismissWithoutContent)
}))
if SGSimpleSettings.shared.contextShowSaveToCloud {
actions.append(action)
} else {
sgActions.append(action)
}
}
let action: ContextMenuItem = .action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.NotificationSettings_Stories_CompactHideName, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
interfaceInteraction.forwardMessages(selectAll || isImage ? messages : [message], "forwardMessagesWithNoNames")
f(.dismissWithoutContent)
}))
if SGSimpleSettings.shared.contextShowHideForwardName {
actions.append(action)
} else {
sgActions.append(action)
}
}
}
if data.messageActions.options.contains(.report) {
if canReveal {
actions.insert(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Username_ActivateAlertShow, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Premium/Stories/Views" /*"Chat/Context Menu/Eye"*/ ), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
interfaceInteraction.forwardMessages(selectAll || isImage ? messages : [message], "forwardMessagesToCloudWithNoNamesAndOpen")
f(.dismissWithoutContent)
})), at: 0)
}
if data.messageActions.options.contains(.report) || context.account.testingEnvironment {
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuReport, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Report"), color: theme.actionSheet.primaryTextColor)
}, action: { controller, f in
interfaceInteraction.reportMessages(messages, controller)
})))
if !SGSimpleSettings.shared.contextShowReport { sgActions.append(actions.removeLast()) }
} else if message.id.peerId.isReplies {
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuBlock, textColor: .destructive, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Restrict"), color: theme.actionSheet.destructiveActionTextColor)
@@ -1737,6 +1801,54 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
})))
}
if let peer = chatPresentationInterfaceState.renderedPeer?.peer ?? message.peers[message.id.peerId] {
let hasRestrictPermission: Bool
if let channel = peer as? TelegramChannel {
hasRestrictPermission = channel.hasPermission(.banMembers)
} else if let group = peer as? TelegramGroup {
switch group.role {
case .creator:
hasRestrictPermission = true
case let .admin(adminRights, _):
hasRestrictPermission = adminRights.rights.contains(.canBanUsers)
case .member:
hasRestrictPermission = false
}
} else {
hasRestrictPermission = false
}
if let user = message.author as? TelegramUser {
if (user.id != context.account.peerId) && hasRestrictPermission {
let banDisposables = DisposableDict<PeerId>()
// TODO(swiftgram): Check is user an admin?
let action: ContextMenuItem = .action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuBan, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Restrict"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
let participantSignal: Signal<ChannelParticipant?, NoError>
if peer is TelegramChannel {
participantSignal = context.engine.peers.fetchChannelParticipant(peerId: peer.id, participantId: user.id)
} else if peer is TelegramGroup {
participantSignal = .single(.member(id: user.id, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil, subscriptionUntilDate: nil))
} else {
participantSignal = .single(nil)
}
banDisposables.set((participantSignal
|> deliverOnMainQueue).start(next: { participant in
controllerInteraction.presentController(channelBannedMemberController(context: context, peerId: peer.id, memberId: message.author!.id, initialParticipant: participant, updated: { _ in }, upgradedToSupergroup: { _, f in f() }), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
}), forKey: user.id)
f(.dismissWithoutContent)
}))
if SGSimpleSettings.shared.contextShowRestrict {
actions.append(action)
} else {
sgActions.append(action)
}
}
}
}
var clearCacheAsDelete = false
if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info, !isMigrated {
var views: Int = 0
@@ -1855,9 +1967,86 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
})))
}
}
var sgActionsIndex: Int? = nil
if !isPinnedMessages, !isReplyThreadHead, data.canSelect {
sgActionsIndex = actions.count
var didAddSeparator = false
// MARK: Swiftgram
if let authorId = message.author?.id {
let action: ContextMenuItem = .action(ContextMenuActionItem(text: i18n("ContextMenu.SelectFromUser", chatPresentationInterfaceState.strings.baseLanguageCode), icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/SelectAll"), color: theme.actionSheet.primaryTextColor)
}, action: { _, f in
let progressSignal = Signal<Never, NoError> { subscriber in
let overlayController = OverlayStatusController(theme: chatPresentationInterfaceState.theme, type: .loading(cancelled: nil))
controllerInteraction.presentGlobalOverlayController(overlayController, nil)
return ActionDisposable { [weak overlayController] in
Queue.mainQueue().async() {
overlayController?.dismiss()
}
}
}
|> runOn(Queue.mainQueue())
|> delay(0.2, queue: Queue.mainQueue())
let progressDisposable = progressSignal.start()
let _ = (context.account.postbox.transaction { transaction -> [MessageId] in
let limit = 500
var result: [MessageId] = []
let needThreadIdFilter: Bool
let searchThreadId: Int64?
switch chatPresentationInterfaceState.chatLocation {
case let .replyThread(replyThreadMessage):
needThreadIdFilter = true
searchThreadId = replyThreadMessage.threadId
default:
needThreadIdFilter = false
searchThreadId = nil
}
transaction.withAllMessages(peerId: message.id.peerId, reversed: true, { searchMessage in
if result.count >= limit {
return false
}
if searchMessage.author?.id == authorId {
// Only messages from current opened thread
// print("searchMessage.threadId:\(String(describing: searchMessage.threadId)) threadId:\(String(describing: threadId)) message.threadId:\(String(describing:message.threadId)) needThreadIdFilter:\(needThreadIdFilter) searchThreadId:\(String(describing:searchThreadId))")
if needThreadIdFilter && searchMessage.threadId != searchThreadId {
return true
}
// No service messages
if searchMessage.media.contains(where: { $0 is TelegramMediaAction }) {
return true
}
result.append(searchMessage.id)
}
return true
})
return result
}
|> deliverOnMainQueue)
.start(next: { ids in
interfaceInteraction.beginMessageSelection(ids, { transition in
f(.custom(transition))
})
Queue.mainQueue().async {
progressDisposable.dispose()
}
}, completed: {
Queue.mainQueue().async {
progressDisposable.dispose()
}
})
}))
if SGSimpleSettings.shared.contextShowSelectFromUser {
if !actions.isEmpty && !didAddSeparator {
didAddSeparator = true
actions.append(.separator)
}
actions.append(action)
} else {
sgActions.append(action)
}
}
if !selectAll || messages.count == 1 {
if !actions.isEmpty && !didAddSeparator {
didAddSeparator = true
@@ -1889,6 +2078,40 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
}
}
// MARK: Swiftgram
if !sgActions.isEmpty {
if !actions.isEmpty {
if let sgActionsIndex = sgActionsIndex {
actions.insert(.separator, at: sgActionsIndex)
} else {
actions.append(.separator)
}
}
var popSGItems: (() -> Void)? = nil
sgActions.insert(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Common_Back, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Back"), color: theme.actionSheet.primaryTextColor)
}, iconPosition: .left, action: { _, _ in
popSGItems?()
})), at: 0)
sgActions.insert(.separator, at: 1)
let swiftgramSubMenu: ContextMenuItem = .action(ContextMenuActionItem(text: "Swiftgram", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "SwiftgramContextMenu"), color: theme.actionSheet.primaryTextColor)
}, action: { c, f in
popSGItems = { [weak c] in
c?.popItems()
}
c?.pushItems(items: .single(ContextController.Items(content: .list(sgActions))))
}))
if let sgActionsIndex = sgActionsIndex {
actions.insert(swiftgramSubMenu, at: sgActionsIndex + 1)
} else {
actions.append(swiftgramSubMenu)
}
}
let canViewStats: Bool
if let messageReadStatsAreHidden = infoSummaryData.messageReadStatsAreHidden, !messageReadStatsAreHidden {
canViewStats = canViewReadStats(message: message, participantCount: infoSummaryData.participantCount, isMessageRead: isMessageRead, isPremium: isPremium, appConfig: appConfig)
@@ -2055,7 +2278,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
messageEntities = attribute.entities
}
if let attribute = attribute as? RestrictedContentMessageAttribute {
restrictedText = attribute.platformText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) ?? ""
restrictedText = attribute.platformText(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }, chatId: message.author?.id.id._internalGetInt64Value()) ?? ""
}
}