mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-07-25 08:50:51 +02:00
chore: migrate to new version + fixed several critical bugs
- Migrated project to latest Telegram iOS base (v12.3.2+) - Fixed circular dependency between GhostModeManager and MiscSettingsManager - Fixed multiple Bazel build configuration errors (select() default conditions) - Fixed duplicate type definitions in PeerInfoScreen - Fixed swiftmodule directory resolution in build scripts - Added Ghostgram Settings tab in main Settings menu with all 5 features - Cleared sensitive credentials from config.json (template-only now) - Excluded bazel-cache from version control
This commit is contained in:
@@ -94,6 +94,7 @@ swift_library(
|
||||
"//submodules/TelegramStringFormatting",
|
||||
"//submodules/AvatarNode",
|
||||
"//submodules/TelegramUI/Components/Chat/ChatMessageSuggestedPostInfoNode",
|
||||
"//submodules/TelegramUI/Components/PremiumAlertController",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
||||
+160
-2
@@ -83,6 +83,7 @@ import TelegramAnimatedStickerNode
|
||||
import LottieMetal
|
||||
import AvatarNode
|
||||
import ChatMessageSuggestedPostInfoNode
|
||||
import PremiumAlertController
|
||||
|
||||
private struct BubbleItemAttributes {
|
||||
var index: Int?
|
||||
@@ -689,6 +690,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
private var unlockButtonNode: ChatMessageUnlockMediaNode?
|
||||
private var mediaInfoNode: ChatMessageStarsMediaInfoNode?
|
||||
|
||||
private var summarizeButtonNode: ChatMessageShareButton?
|
||||
private var shareButtonNode: ChatMessageShareButton?
|
||||
|
||||
private let messageAccessibilityArea: AccessibilityAreaNode
|
||||
@@ -1222,6 +1224,10 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
}
|
||||
}
|
||||
|
||||
if let summarizeButtonNode = strongSelf.summarizeButtonNode, summarizeButtonNode.frame.contains(point) {
|
||||
return .fail
|
||||
}
|
||||
|
||||
if let shareButtonNode = strongSelf.shareButtonNode, shareButtonNode.frame.contains(point) {
|
||||
return .fail
|
||||
}
|
||||
@@ -1724,6 +1730,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
let isFailed = item.content.firstMessage.effectivelyFailed(timestamp: item.context.account.network.getApproximateRemoteTimestamp())
|
||||
|
||||
var needsShareButton = false
|
||||
var needsSummarizeButton = false
|
||||
|
||||
if incoming, case let .customChatContents(contents) = item.associatedData.subject, case .hashTagSearch = contents.kind {
|
||||
needsShareButton = true
|
||||
@@ -1751,6 +1758,10 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
needsShareButton = true
|
||||
}
|
||||
|
||||
if let _ = item.message.attributes.first(where: { $0 is SummarizationMessageAttribute }) {
|
||||
needsSummarizeButton = true
|
||||
}
|
||||
|
||||
if let peer = item.message.peers[item.message.id.peerId] {
|
||||
if let channel = peer as? TelegramChannel {
|
||||
if case .broadcast = channel.info {
|
||||
@@ -1789,6 +1800,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
loop: for media in item.message.media {
|
||||
if media is TelegramMediaAction {
|
||||
needsShareButton = false
|
||||
needsSummarizeButton = false
|
||||
break loop
|
||||
} else if let media = media as? TelegramMediaFile, media.isInstantVideo {
|
||||
mayHaveSeparateCommentsButton = true
|
||||
@@ -1801,12 +1813,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
if mayHaveSeparateCommentsButton && hasCommentButton(item: item) {
|
||||
} else {
|
||||
needsShareButton = false
|
||||
needsSummarizeButton = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isPreview {
|
||||
needsShareButton = false
|
||||
needsSummarizeButton = false
|
||||
}
|
||||
let isAd = item.content.firstMessage.adAttribute != nil
|
||||
if isAd {
|
||||
@@ -1815,13 +1829,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
for attribute in item.content.firstMessage.attributes {
|
||||
if let attribute = attribute as? RestrictedContentMessageAttribute, attribute.platformText(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) != nil {
|
||||
needsShareButton = false
|
||||
needsSummarizeButton = false
|
||||
}
|
||||
}
|
||||
|
||||
if let subject = item.associatedData.subject, case .messageOptions = subject {
|
||||
needsShareButton = false
|
||||
}
|
||||
|
||||
|
||||
var tmpWidth: CGFloat
|
||||
if allowFullWidth {
|
||||
tmpWidth = baseWidth
|
||||
@@ -2312,6 +2327,17 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
}
|
||||
}
|
||||
|
||||
let translateToLanguage = item.associatedData.translateToLanguage
|
||||
var isSummarized = false
|
||||
if item.controllerInteraction.summarizedMessageIds.contains(item.message.id) {
|
||||
for attribute in item.message.attributes {
|
||||
if let attribute = attribute as? SummarizationMessageAttribute, attribute.summaryForLang(translateToLanguage) != nil {
|
||||
initialDisplayHeader = true
|
||||
isSummarized = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var displayHeader = false
|
||||
if initialDisplayHeader {
|
||||
if authorNameString != nil {
|
||||
@@ -2339,6 +2365,9 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
displayHeader = true
|
||||
}
|
||||
}
|
||||
if isSummarized {
|
||||
displayHeader = true
|
||||
}
|
||||
}
|
||||
|
||||
let firstNodeTopPosition: ChatMessageBubbleRelativePosition
|
||||
@@ -2717,7 +2746,11 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
hasReply = false
|
||||
}
|
||||
|
||||
if !isInstantVideo, hasReply, (replyMessage != nil || replyForward != nil || replyStory != nil) {
|
||||
if isSummarized {
|
||||
hasReply = true
|
||||
}
|
||||
|
||||
if !isInstantVideo, hasReply, (replyMessage != nil || replyForward != nil || replyStory != nil || isSummarized) {
|
||||
if headerSize.height.isZero {
|
||||
headerSize.height += 11.0
|
||||
} else {
|
||||
@@ -2733,6 +2766,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
quote: replyQuote,
|
||||
todoItemId: replyTodoItemId,
|
||||
story: replyStory,
|
||||
isSummarized: isSummarized,
|
||||
parentMessage: item.message,
|
||||
constrainedSize: CGSize(width: maximumNodeWidth - layoutConstants.text.bubbleInsets.left - layoutConstants.text.bubbleInsets.right - 6.0, height: CGFloat.greatestFiniteMagnitude),
|
||||
animationCache: item.controllerInteraction.presentationContext.animationCache,
|
||||
@@ -3491,6 +3525,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
unlockButtonSizeAndApply: unlockButtonSizeApply,
|
||||
mediaInfoOrigin: mediaInfoOrigin?.offsetBy(dx: 0.0, dy: layoutInsets.top),
|
||||
mediaInfoSizeAndApply: mediaInfoSizeApply,
|
||||
needsSummarizeButton: needsSummarizeButton,
|
||||
needsShareButton: needsShareButton,
|
||||
shareButtonOffset: shareButtonOffset,
|
||||
avatarOffset: avatarOffset,
|
||||
@@ -3556,6 +3591,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
unlockButtonSizeAndApply: (CGSize, (Bool) -> ChatMessageUnlockMediaNode?),
|
||||
mediaInfoOrigin: CGPoint?,
|
||||
mediaInfoSizeAndApply: (CGSize, (Bool) -> ChatMessageStarsMediaInfoNode?),
|
||||
needsSummarizeButton: Bool,
|
||||
needsShareButton: Bool,
|
||||
shareButtonOffset: CGPoint?,
|
||||
avatarOffset: CGFloat?,
|
||||
@@ -4787,6 +4823,20 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
})
|
||||
}
|
||||
|
||||
if needsSummarizeButton {
|
||||
if strongSelf.summarizeButtonNode == nil {
|
||||
let summarizeButtonNode = ChatMessageShareButton()
|
||||
strongSelf.summarizeButtonNode = summarizeButtonNode
|
||||
strongSelf.insertSubnode(summarizeButtonNode, belowSubnode: strongSelf.messageAccessibilityArea)
|
||||
summarizeButtonNode.pressed = { [weak strongSelf] in
|
||||
strongSelf?.toggleSummarization()
|
||||
}
|
||||
}
|
||||
} else if let summarizeButtonNode = strongSelf.summarizeButtonNode {
|
||||
strongSelf.summarizeButtonNode = nil
|
||||
summarizeButtonNode.removeFromSupernode()
|
||||
}
|
||||
|
||||
if needsShareButton {
|
||||
if strongSelf.shareButtonNode == nil {
|
||||
let shareButtonNode = ChatMessageShareButton()
|
||||
@@ -4960,6 +5010,30 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
}
|
||||
strongSelf.messageAccessibilityArea.frame = backgroundFrame
|
||||
}
|
||||
if let summarizeButtonNode = strongSelf.summarizeButtonNode {
|
||||
let buttonSize = summarizeButtonNode.update(presentationData: item.presentationData, controllerInteraction: item.controllerInteraction, chatLocation: item.chatLocation, subject: item.associatedData.subject, message: item.message, account: item.context.account, disableComments: disablesComments, isSummarize: true)
|
||||
|
||||
var buttonFrame = CGRect(origin: CGPoint(x: !incoming ? backgroundFrame.minX - buttonSize.width - 8.0 : backgroundFrame.maxX + 8.0, y: backgroundFrame.minY + 1.0), size: buttonSize)
|
||||
|
||||
if let shareButtonOffset = shareButtonOffset {
|
||||
if incoming {
|
||||
buttonFrame.origin.x = shareButtonOffset.x
|
||||
}
|
||||
buttonFrame.origin.y = buttonFrame.origin.y + shareButtonOffset.y - (buttonSize.height - 30.0)
|
||||
} else if !disablesComments {
|
||||
buttonFrame.origin.y = buttonFrame.origin.y - (buttonSize.height - 30.0)
|
||||
}
|
||||
|
||||
if isSidePanelOpen {
|
||||
buttonFrame.origin.x -= buttonFrame.width * 0.5
|
||||
buttonFrame.origin.y += buttonFrame.height * 0.5
|
||||
}
|
||||
|
||||
animation.animator.updatePosition(layer: summarizeButtonNode.layer, position: buttonFrame.center, completion: nil)
|
||||
animation.animator.updateBounds(layer: summarizeButtonNode.layer, bounds: CGRect(origin: CGPoint(), size: buttonFrame.size), completion: nil)
|
||||
animation.animator.updateAlpha(layer: summarizeButtonNode.layer, alpha: (isCurrentlyPlayingMedia || isSidePanelOpen) ? 0.0 : 1.0, completion: nil)
|
||||
animation.animator.updateScale(layer: summarizeButtonNode.layer, scale: (isCurrentlyPlayingMedia || isSidePanelOpen) ? 0.001 : 1.0, completion: nil)
|
||||
}
|
||||
if let shareButtonNode = strongSelf.shareButtonNode {
|
||||
let buttonSize = shareButtonNode.update(presentationData: item.presentationData, controllerInteraction: item.controllerInteraction, chatLocation: item.chatLocation, subject: item.associatedData.subject, message: item.message, account: item.context.account, disableComments: disablesComments)
|
||||
|
||||
@@ -4994,6 +5068,30 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
strongSelf.backgroundFrameTransition = nil
|
||||
}*/
|
||||
strongSelf.messageAccessibilityArea.frame = backgroundFrame
|
||||
if let summarizeButtonNode = strongSelf.summarizeButtonNode {
|
||||
let buttonSize = summarizeButtonNode.update(presentationData: item.presentationData, controllerInteraction: item.controllerInteraction, chatLocation: item.chatLocation, subject: item.associatedData.subject, message: item.message, account: item.context.account, disableComments: disablesComments, isSummarize: true)
|
||||
|
||||
var buttonFrame = CGRect(origin: CGPoint(x: !incoming ? backgroundFrame.minX - buttonSize.width - 8.0 : backgroundFrame.maxX + 8.0, y: backgroundFrame.minY + 1.0), size: buttonSize)
|
||||
|
||||
if let shareButtonOffset = shareButtonOffset {
|
||||
if incoming {
|
||||
buttonFrame.origin.x = shareButtonOffset.x
|
||||
}
|
||||
buttonFrame.origin.y = buttonFrame.origin.y + shareButtonOffset.y - (buttonSize.height - 30.0)
|
||||
} else if !disablesComments {
|
||||
buttonFrame.origin.y = buttonFrame.origin.y - (buttonSize.height - 30.0)
|
||||
}
|
||||
|
||||
if isSidePanelOpen {
|
||||
buttonFrame.origin.x -= buttonFrame.width * 0.5
|
||||
buttonFrame.origin.y += buttonFrame.height * 0.5
|
||||
}
|
||||
|
||||
animation.animator.updatePosition(layer: summarizeButtonNode.layer, position: buttonFrame.center, completion: nil)
|
||||
animation.animator.updateBounds(layer: summarizeButtonNode.layer, bounds: CGRect(origin: CGPoint(), size: buttonFrame.size), completion: nil)
|
||||
animation.animator.updateAlpha(layer: summarizeButtonNode.layer, alpha: (isCurrentlyPlayingMedia || isSidePanelOpen) ? 0.0 : 1.0, completion: nil)
|
||||
animation.animator.updateScale(layer: summarizeButtonNode.layer, scale: (isCurrentlyPlayingMedia || isSidePanelOpen) ? 0.001 : 1.0, completion: nil)
|
||||
}
|
||||
if let shareButtonNode = strongSelf.shareButtonNode {
|
||||
let buttonSize = shareButtonNode.update(presentationData: item.presentationData, controllerInteraction: item.controllerInteraction, chatLocation: item.chatLocation, subject: item.associatedData.subject, message: item.message, account: item.context.account, disableComments: disablesComments)
|
||||
|
||||
@@ -5275,6 +5373,15 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
}
|
||||
} else if let replyInfoNode = self.replyInfoNode, self.item?.controllerInteraction.tapMessage == nil, replyInfoNode.frame.contains(location) {
|
||||
if let item = self.item {
|
||||
if item.controllerInteraction.summarizedMessageIds.contains(item.message.id) {
|
||||
return .action(InternalBubbleTapAction.Action({ [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.toggleSummarization()
|
||||
}))
|
||||
}
|
||||
|
||||
for attribute in item.message.attributes {
|
||||
if let attribute = attribute as? ReplyMessageAttribute {
|
||||
if let threadId = item.message.threadId, Int32(clamping: threadId) == attribute.messageId.id, let quotedReply = item.message.attributes.first(where: { $0 is QuotedReplyMessageAttribute }) as? QuotedReplyMessageAttribute {
|
||||
@@ -5824,6 +5931,10 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
return boostButtonNode.view
|
||||
}
|
||||
|
||||
if let summarizeButtonNode = self.summarizeButtonNode, summarizeButtonNode.frame.contains(point) {
|
||||
return summarizeButtonNode.view.hitTest(self.view.convert(point, to: summarizeButtonNode.view), with: event)
|
||||
}
|
||||
|
||||
if let shareButtonNode = self.shareButtonNode, shareButtonNode.frame.contains(point) {
|
||||
return shareButtonNode.view.hitTest(self.view.convert(point, to: shareButtonNode.view), with: event)
|
||||
}
|
||||
@@ -6516,6 +6627,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
container.updateAbsoluteRect(containerFrame, within: containerSize)
|
||||
}
|
||||
|
||||
if let summarizeButtonNode = self.summarizeButtonNode {
|
||||
var summarizeButtonNodeFrame = summarizeButtonNode.frame
|
||||
summarizeButtonNodeFrame.origin.x += rect.minX
|
||||
summarizeButtonNodeFrame.origin.y += rect.minY
|
||||
|
||||
summarizeButtonNode.updateAbsoluteRect(summarizeButtonNodeFrame, within: containerSize)
|
||||
}
|
||||
|
||||
if let shareButtonNode = self.shareButtonNode {
|
||||
var shareButtonNodeFrame = shareButtonNode.frame
|
||||
shareButtonNodeFrame.origin.x += rect.minX
|
||||
@@ -6854,6 +6973,45 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
||||
self.updateVisibility(isScroll: false)
|
||||
}
|
||||
|
||||
private func toggleSummarization() {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
|
||||
if item.controllerInteraction.summarizedMessageIds.contains(item.message.id) {
|
||||
item.controllerInteraction.summarizedMessageIds.remove(item.message.id)
|
||||
let _ = item.controllerInteraction.requestMessageUpdate(item.message.id, false)
|
||||
} else {
|
||||
item.controllerInteraction.summarizedMessageIds.insert(item.message.id)
|
||||
let _ = item.controllerInteraction.requestMessageUpdate(item.message.id, false)
|
||||
|
||||
let translateToLanguage = item.associatedData.translateToLanguage
|
||||
var requestSummary = true
|
||||
for attribute in item.message.attributes {
|
||||
if let attribute = attribute as? SummarizationMessageAttribute, attribute.summaryForLang(translateToLanguage) != nil {
|
||||
requestSummary = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if requestSummary {
|
||||
let _ = (item.context.engine.messages.summarizeMessage(messageId: item.message.id, translateToLang: translateToLanguage)
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
if case .limitExceededPremium = error, let parentController = item.controllerInteraction.navigationController()?.topViewController as? ViewController {
|
||||
item.controllerInteraction.summarizedMessageIds.remove(item.message.id)
|
||||
let _ = item.controllerInteraction.requestMessageUpdate(item.message.id, false)
|
||||
let controller = premiumAlertController(
|
||||
context: item.context,
|
||||
parentController: parentController,
|
||||
title: item.presentationData.strings.Conversation_Summary_Limit_Title,
|
||||
text: item.presentationData.strings.Conversation_Summary_Limit_Text
|
||||
)
|
||||
parentController.present(controller, in: .window(.root))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateVisibility(isScroll: Bool) {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user