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:
ichmagmaus 812
2026-02-23 23:04:32 +01:00
parent 703e291bcb
commit db53826061
1017 changed files with 62337 additions and 40559 deletions
@@ -349,7 +349,7 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
}
private func transcribe() {
guard let arguments = self.arguments, let context = self.context, let message = self.message else {
guard let _ = self.arguments, let context = self.context, let message = self.message else {
return
}
@@ -358,43 +358,7 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: arguments.context.currentAppConfiguration.with { $0 })
let transcriptionText = self.forcedAudioTranscriptionText ?? transcribedText(message: message)
if transcriptionText == nil && !arguments.associatedData.alwaysDisplayTranscribeButton.providedByGroupBoost {
if premiumConfiguration.audioTransciptionTrialCount > 0 {
if !arguments.associatedData.isPremium {
if self.presentAudioTranscriptionTooltip(finished: false) {
return
}
}
} else {
guard arguments.associatedData.isPremium else {
if self.hapticFeedback == nil {
self.hapticFeedback = HapticFeedback()
}
self.hapticFeedback?.impact(.medium)
let tipController = UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_voiceToText", scale: 0.065, colors: [:], title: nil, text: presentationData.strings.Message_AudioTranscription_SubscribeToPremium, customUndoText: presentationData.strings.Message_AudioTranscription_SubscribeToPremiumAction, timeout: nil), elevatedLayout: false, position: .top, animateInAsReplacement: false, action: { action in
if case .undo = action {
var replaceImpl: ((ViewController) -> Void)?
let controller = context.sharedContext.makePremiumDemoController(context: context, subject: .voiceToText, forceDark: false, action: {
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .settings, forceDark: false, dismissed: nil)
replaceImpl?(controller)
}, dismissed: nil)
replaceImpl = { [weak controller] c in
controller?.replace(with: c)
}
arguments.controllerInteraction.navigationController()?.pushViewController(controller, animated: true)
let _ = ApplicationSpecificNotice.incrementAudioTranscriptionSuggestion(accountManager: context.sharedContext.accountManager).startStandalone()
}
return false })
arguments.controllerInteraction.presentControllerInCurrent(tipController, nil)
return
}
}
}
// GHOSTGRAM: Premium check removed - local transcription is free!
var shouldBeginTranscription = false
var shouldExpandNow = false
@@ -420,7 +384,8 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
self.audioTranscriptionState = .inProgress
self.requestUpdateLayout(true)
if context.sharedContext.immediateExperimentalUISettings.localTranscription {
// GHOSTGRAM: Always use local transcription (free, private, on-device!)
if true {
let appLocale = presentationData.strings.baseLanguageCode
let signal: Signal<LocallyTranscribedAudio?, NoError> = context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: message.id))
@@ -640,8 +605,6 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
var audioWaveform: AudioWaveform?
var isVoice = false
var audioDuration: Int32 = 0
var isConsumed: Bool?
var consumableContentIcon: UIImage?
for attribute in arguments.message.attributes {
if let attribute = attribute as? ConsumableContentMessageAttribute {
@@ -652,7 +615,6 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
consumableContentIcon = PresentationResourcesChat.chatBubbleConsumableContentOutgoingIcon(arguments.presentationData.theme.theme)
}
}
isConsumed = attribute.consumed
break
}
}
@@ -771,24 +733,8 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
if Namespaces.Message.allNonRegular.contains(arguments.message.id.namespace) {
displayTranscribe = false
} else if arguments.message.id.peerId.namespace != Namespaces.Peer.SecretChat && !isViewOnceMessage && !arguments.presentationData.isPreview {
let premiumConfiguration = PremiumConfiguration.with(appConfiguration: arguments.context.currentAppConfiguration.with { $0 })
if arguments.associatedData.isPremium {
displayTranscribe = true
} else if premiumConfiguration.audioTransciptionTrialCount > 0 {
if arguments.incoming {
if audioDuration < premiumConfiguration.audioTransciptionTrialMaxDuration {
displayTranscribe = true
}
}
} else if arguments.associatedData.alwaysDisplayTranscribeButton.canBeDisplayed {
if audioDuration >= 60 {
displayTranscribe = true
} else if arguments.incoming && isConsumed == false && arguments.associatedData.alwaysDisplayTranscribeButton.displayForNotConsumed {
displayTranscribe = true
}
} else if arguments.associatedData.alwaysDisplayTranscribeButton.providedByGroupBoost {
displayTranscribe = true
}
// GHOSTGRAM: Always show transcribe button for voice messages
displayTranscribe = true
}
let transcribedText = forcedAudioTranscriptionText ?? transcribedText(message: arguments.message)
@@ -1564,8 +1510,15 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
if isTranslating, !rects.isEmpty {
if self.shimmeringNodes.isEmpty {
let color: UIColor
let isIncoming = arguments.message.effectivelyIncoming(arguments.context.account.peerId)
if arguments.presentationData.theme.theme.overallDarkAppearance {
color = isIncoming ? arguments.presentationData.theme.theme.chat.message.incoming.primaryTextColor.withAlphaComponent(0.1) : arguments.presentationData.theme.theme.chat.message.outgoing.primaryTextColor.withAlphaComponent(0.1)
} else {
color = isIncoming ? arguments.presentationData.theme.theme.chat.message.incoming.accentTextColor.withAlphaComponent(0.1) : arguments.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1)
}
for rects in rects {
let shimmeringNode = ShimmeringLinkNode(color: arguments.message.effectivelyIncoming(arguments.context.account.peerId) ? arguments.presentationData.theme.theme.chat.message.incoming.secondaryTextColor.withAlphaComponent(0.1) : arguments.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1))
let shimmeringNode = ShimmeringLinkNode(color: color)
shimmeringNode.updateRects(rects)
shimmeringNode.frame = self.bounds
shimmeringNode.updateLayout(self.bounds.size)