Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2025-05-22 06:12:10 +02:00
commit 880fd391c4
40 changed files with 3072 additions and 2757 deletions

View File

@ -6,26 +6,11 @@ build --apple_crosstool_top=@local_config_apple_cc//:toolchain
build --crosstool_top=@local_config_apple_cc//:toolchain
build --host_crosstool_top=@local_config_apple_cc//:toolchain
build --cxxopt='-std=c++17'
build --per_file_copt="third-party/webrtc/.*\.cpp$","@-std=c++17"
build --per_file_copt="third-party/webrtc/.*\.cc$","@-std=c++17"
build --per_file_copt="third-party/webrtc/.*\.mm$","@-std=c++17"
build --per_file_copt="submodules/LottieMeshSwift/LottieMeshBinding/Sources/.*\.mm$","@-std=c++17"
build --per_file_copt="submodules/LottieCpp/lottiecpp/Sources/.*\.mm$","@-std=c++17"
build --per_file_copt="submodules/LottieCpp/lottiecpp/Sources/.*\.cpp$","@-std=c++17"
build --per_file_copt="submodules/LottieCpp/lottiecpp/PlatformSpecific/Darwin/Sources/.*\.mm$","@-std=c++17"
build --per_file_copt="submodules/LottieCpp/lottiecpp/PlatformSpecific/Darwin/Sources/.*\.cpp$","@-std=c++17"
build --per_file_copt="Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/.*\.cpp$","@-std=c++17"
build --per_file_copt="Tests/LottieMetalTest/SoftwareLottieRenderer/Sources/.*\.mm$","@-std=c++17"
build --per_file_copt="third-party/td/TdBinding/Sources/.*\.mm$","@-std=c++17"
#build --swiftcopt=-whole-module-optimization
build --per_file_copt=".*\.m$","@-fno-objc-msgsend-selector-stubs"
build --per_file_copt=".*\.mm$","@-fno-objc-msgsend-selector-stubs"
#build --linkopt="-ld_classic"
build --features=debug_prefix_map_pwd_is_dot
build --features=swift.cacheable_swiftmodules
build --features=swift.debug_prefix_map

View File

@ -13,6 +13,5 @@
".git/**": true
},
"files.associations": {
"memory": "cpp"
}
}

View File

@ -1779,16 +1779,13 @@ ios_application(
":UrlTypesInfoPlist",
],
deps = [
#"//submodules/MtProtoKit",
#"//submodules/SSignalKit/SwiftSignalKit",
#"//submodules/Postbox",
#"//submodules/TelegramApi",
#"//submodules/TelegramCore",
#"//submodules/FFMpegBinding",
#"//submodules/Display",
#"//third-party/webrtc",
"//submodules/Display",
"//submodules/TelegramCore",
"//submodules/FFMpegBinding",
"//third-party/webrtc",
"//submodules/AsyncDisplayKit",
"//submodules/ObjCRuntimeUtils",
],
)

View File

@ -16,6 +16,11 @@ objc_library(
"-Werror",
"-I{}/Sources".format(package_name()),
],
cxxopts = [
"-Werror",
"-std=c++17",
"-I{}/Sources".format(package_name()),
],
hdrs = glob([
"PublicHeaders/**/*.h",
]),

View File

@ -54,10 +54,14 @@ _IGNORE_CC_LIBRARY_EMPTY_ATTRS = [
"include_prefix",
"strip_include_prefix",
"local_defines",
"conlyopts",
"module_interfaces",
"package_metadata",
]
_CC_LIBRARY_ATTRS = {
"copts": [],
"cxxopts": [],
"defines": [],
"deps": [],
"hdrs": [],
@ -108,11 +112,11 @@ _IGNORE_OBJC_LIBRARY_EMPTY_ATTRS = [
"textual_hdrs",
"sdk_includes",
"conlyopts",
"cxxopts",
]
_OBJC_LIBRARY_ATTRS = {
"copts": [],
"cxxopts": [],
"defines": [],
"deps": [],
"hdrs": [],
@ -351,6 +355,7 @@ def _collect_spm_modules_impl(target, ctx):
"sources": sorted(sources + headers),
"module_name": module_name,
"copts": result_attrs["copts"],
"cxxopts": result_attrs["cxxopts"],
"sdk_frameworks": result_attrs["sdk_frameworks"],
"sdk_dylibs": result_attrs["sdk_dylibs"],
"weak_sdk_frameworks": result_attrs["weak_sdk_frameworks"],
@ -366,6 +371,7 @@ def _collect_spm_modules_impl(target, ctx):
"sources": sorted(sources + headers),
"module_name": module_name,
"copts": result_attrs["copts"],
"cxxopts": result_attrs["cxxopts"],
"includes": result_attrs["includes"],
}
elif module_type == "swift_library":
@ -373,6 +379,7 @@ def _collect_spm_modules_impl(target, ctx):
"name": result_attrs["name"],
"type": module_type,
"path": module_path,
"defines": result_attrs["defines"],
"deps": dep_names,
"sources": sorted(sources),
"module_name": module_name,

View File

@ -19,6 +19,24 @@ if os.path.exists(spm_files_dir):
if not os.path.exists(spm_files_dir):
os.makedirs(spm_files_dir)
def escape_swift_string_literal_component(text: str) -> str:
return text.replace('\\', '\\\\').replace('"', '\\"')
parsed_modules = {}
for name, module in sorted(modules.items()):
is_empty = False
all_source_files = []
for source in module.get("hdrs", []) + module["sources"]:
if source.endswith(('.a')):
continue
all_source_files.append(source)
if module["type"] == "objc_library" or module["type"] == "swift_library" or module["type"] == "cc_library":
if all_source_files == []:
is_empty = True
parsed_modules[name] = {
"is_empty": is_empty,
}
combined_lines = []
combined_lines.append("// swift-tools-version: 6.0")
combined_lines.append("// The swift-tools-version declares the minimum version of Swift required to build this package.")
@ -28,11 +46,14 @@ combined_lines.append("")
combined_lines.append("let package = Package(")
combined_lines.append(" name: \"Telegram\",")
combined_lines.append(" platforms: [")
combined_lines.append(" .iOS(.v13)")
combined_lines.append(" .iOS(.v12)")
combined_lines.append(" ],")
combined_lines.append(" products: [")
for name, module in sorted(modules.items()):
if parsed_modules[name]["is_empty"]:
continue
if module["type"] == "objc_library" or module["type"] == "swift_library" or module["type"] == "cc_library":
combined_lines.append(" .library(name: \"%s\", targets: [\"%s\"])," % (module["name"], module["name"]))
@ -40,6 +61,9 @@ combined_lines.append(" ],")
combined_lines.append(" targets: [")
for name, module in sorted(modules.items()):
if parsed_modules[name]["is_empty"]:
continue
module_type = module["type"]
if module_type == "objc_library" or module_type == "cc_library" or module_type == "swift_library":
combined_lines.append(" .target(")
@ -47,7 +71,7 @@ for name, module in sorted(modules.items()):
linked_directory = None
has_non_linked_sources = False
for source in module["sources"]:
for source in module["sources"] + module.get("hdrs", []):
if source.startswith("bazel-out/"):
linked_directory = "spm-files/" + name
else:
@ -60,7 +84,8 @@ for name, module in sorted(modules.items()):
combined_lines.append(" dependencies: [")
for dep in module["deps"]:
combined_lines.append(" .target(name: \"%s\")," % dep)
if not parsed_modules[dep]["is_empty"]:
combined_lines.append(" .target(name: \"%s\")," % dep)
combined_lines.append(" ],")
if linked_directory:
@ -85,7 +110,7 @@ for name, module in sorted(modules.items()):
continue
# Check if any source file is under this directory
has_source = False
for source in module["sources"]:
for source in module["sources"] + module.get("hdrs", []):
rel_source = source[len(module["path"]) + 1:]
if rel_source.startswith(dir_path + "/"):
has_source = True
@ -98,16 +123,14 @@ for name, module in sorted(modules.items()):
file_path = os.path.join(rel_path, f)
if any(component.startswith('.') for component in file_path.split('/')):
continue
if file_path not in [source[len(module["path"]) + 1:] for source in module["sources"]]:
if file_path not in [source[len(module["path"]) + 1:] for source in module["sources"] + module.get("hdrs", [])]:
exclude_files_and_dirs.append(file_path)
for item in exclude_files_and_dirs:
combined_lines.append(" \"%s\"," % item)
combined_lines.append(" ],")
combined_lines.append(" sources: [")
for source in module["sources"]:
if source.endswith(('.h', '.hpp')):
continue
for source in module["sources"] + module.get("hdrs", []):
linked_source_file_names = []
if not source.startswith(module["path"]):
if source.startswith("bazel-out/"):
@ -138,7 +161,8 @@ for name, module in sorted(modules.items()):
os.symlink(symlink_target, symlink_location)
relative_source = source_file_name
combined_lines.append(" \"%s\"," % relative_source)
if not source.endswith(('.h', '.hpp', '.a')):
combined_lines.append(" \"%s\"," % relative_source)
else:
print("Source {} is not inside module path {}".format(source, module["path"]))
sys.exit(1)
@ -152,16 +176,53 @@ for name, module in sorted(modules.items()):
elif len(module["includes"]) == 1:
combined_lines.append(" publicHeadersPath: \"%s\"," % module["includes"][0])
else:
print("Multiple includes are not supported yet: {}".format(module["includes"]))
print("{}: Multiple includes are not yet supported: {}".format(name, module["includes"]))
sys.exit(1)
combined_lines.append(" cSettings: [")
combined_lines.append(" .unsafeFlags([")
for flag in module["copts"]:
# Escape C-string entities in flag
escaped_flag = flag.replace('\\', '\\\\').replace('"', '\\"')
combined_lines.append(" \"%s\"," % escaped_flag)
combined_lines.append(" ])")
combined_lines.append(" ],")
defines = module.get("defines", [])
copts = module.get("copts", [])
cxxopts = module.get("cxxopts", [])
if defines or copts:
combined_lines.append(" cSettings: [")
if defines:
for define in defines:
if "=" in define:
print("{}: Defines with = are not yet supported: {}".format(name, define))
sys.exit(1)
else:
combined_lines.append(f' .define("{define}"),')
if copts:
combined_lines.append(" .unsafeFlags([")
for flag in copts:
escaped_flag = escape_swift_string_literal_component(flag)
combined_lines.append(f' "{escaped_flag}",')
combined_lines.append(" ])")
combined_lines.append(" ],")
if defines or cxxopts: # Check for defines OR cxxopts
combined_lines.append(" cxxSettings: [")
if defines: # Add defines again if present, for C++ context
for define in defines:
if "=" in define:
print("{}: Defines with = are not yet supported: {}".format(name, define))
sys.exit(1)
else:
combined_lines.append(f' .define("{define}"),')
if cxxopts:
combined_lines.append(" .unsafeFlags([")
for flag in cxxopts:
if flag.startswith("-std="):
if flag != "-std=c++17":
print("{}: Unsupported C++ standard: {}".format(name, flag))
sys.exit(1)
else:
continue
escaped_flag = escape_swift_string_literal_component(flag)
combined_lines.append(f' "{escaped_flag}",')
combined_lines.append(" ])")
combined_lines.append(" ],")
combined_lines.append(" linkerSettings: [")
if module_type == "objc_library":
for framework in module["sdk_frameworks"]:
@ -171,12 +232,33 @@ for name, module in sorted(modules.items()):
combined_lines.append(" ]")
elif module_type == "swift_library":
defines = module.get("defines", [])
swift_copts = module.get("copts", []) # These are actual swiftc flags
# Handle cSettings for defines if they exist
if defines:
combined_lines.append(" cSettings: [")
for define in defines:
combined_lines.append(f' .define("{define}"),')
combined_lines.append(" ],")
# Handle swiftSettings
combined_lines.append(" swiftSettings: [")
combined_lines.append(" .swiftLanguageMode(.v5),")
combined_lines.append(" .unsafeFlags([")
for flag in module["copts"]:
combined_lines.append(" \"%s\"," % flag)
combined_lines.append(" ])")
# Add defines to swiftSettings as simple .define("STRING") flags
if defines:
for define in defines:
# For Swift settings, the define is passed as a single string, e.g., "KEY=VALUE" or "FLAG"
escaped_define = escape_swift_string_literal_component(define) # Escape the whole define string
combined_lines.append(f' .define("{escaped_define}"),')
# Add copts (swiftc flags) to unsafeFlags in swiftSettings
if swift_copts:
combined_lines.append(" .unsafeFlags([")
for flag in swift_copts:
escaped_flag = escape_swift_string_literal_component(flag)
combined_lines.append(f' "{escaped_flag}",')
combined_lines.append(" ])")
combined_lines.append(" ]")
combined_lines.append(" ),")
elif module["type"] == "root":
@ -185,7 +267,8 @@ for name, module in sorted(modules.items()):
print("Unknown module type: {}".format(module["type"]))
sys.exit(1)
combined_lines.append(" ]")
combined_lines.append(" ],")
combined_lines.append(" cxxLanguageStandard: .cxx17")
combined_lines.append(")")
combined_lines.append("")

View File

@ -17,6 +17,10 @@ objc_library(
copts = [
"-Werror",
],
cxxopts = [
"-Werror",
"-std=c++17",
],
hdrs = public_headers,
defines = [
"MINIMAL_ASDK",

View File

@ -63,3 +63,9 @@
#import <AsyncDisplayKit/UIResponder+AsyncDisplayKit.h>
#import <AsyncDisplayKit/_ASCoreAnimationExtras.h>
#import <AsyncDisplayKit/_ASTransitionContext.h>
#import <AsyncDisplayKit/ASInternalHelpers.h>
#import <AsyncDisplayKit/ASCGImageBuffer.h>
#import <AsyncDisplayKit/ASControlTargetAction.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>

View File

@ -1085,7 +1085,6 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate {
})
strongSelf.present(controller)
}
}, reportPeerIrrelevantGeoLocation: {
}, displaySlowmodeTooltip: { _, _ in
}, displaySendMessageOptions: { [weak self] node, gesture in
guard let strongSelf = self, let textInputPanelNode = strongSelf.textInputPanelNode else {

View File

@ -137,7 +137,6 @@ public final class ChatPanelInterfaceInteraction {
public let updateInputLanguage: (@escaping (String?) -> String?) -> Void
public let unarchiveChat: () -> Void
public let openLinkEditing: () -> Void
public let reportPeerIrrelevantGeoLocation: () -> Void
public let displaySlowmodeTooltip: (UIView, CGRect) -> Void
public let displaySendMessageOptions: (ASDisplayNode, ContextGesture) -> Void
public let openScheduledMessages: () -> Void
@ -257,7 +256,6 @@ public final class ChatPanelInterfaceInteraction {
updateInputLanguage: @escaping ((String?) -> String?) -> Void,
unarchiveChat: @escaping () -> Void,
openLinkEditing: @escaping () -> Void,
reportPeerIrrelevantGeoLocation: @escaping () -> Void,
displaySlowmodeTooltip: @escaping (UIView, CGRect) -> Void,
displaySendMessageOptions: @escaping (ASDisplayNode, ContextGesture) -> Void,
openScheduledMessages: @escaping () -> Void,
@ -376,7 +374,6 @@ public final class ChatPanelInterfaceInteraction {
self.updateInputLanguage = updateInputLanguage
self.unarchiveChat = unarchiveChat
self.openLinkEditing = openLinkEditing
self.reportPeerIrrelevantGeoLocation = reportPeerIrrelevantGeoLocation
self.displaySlowmodeTooltip = displaySlowmodeTooltip
self.displaySendMessageOptions = displaySendMessageOptions
self.openScheduledMessages = openScheduledMessages
@ -503,8 +500,8 @@ public final class ChatPanelInterfaceInteraction {
}, requestStopPollInMessage: { _ in
}, updateInputLanguage: { _ in
}, unarchiveChat: {
}, openLinkEditing: openLinkEditing, reportPeerIrrelevantGeoLocation: {
}, displaySlowmodeTooltip: { _, _ in
}, openLinkEditing: openLinkEditing,
displaySlowmodeTooltip: { _, _ in
}, displaySendMessageOptions: { _, _ in
}, openScheduledMessages: {
}, openPeersNearby: {

View File

@ -266,14 +266,12 @@ public final class ChatManagingBot: Equatable {
public struct ChatContactStatus: Equatable {
public var canAddContact: Bool
public var canReportIrrelevantLocation: Bool
public var peerStatusSettings: PeerStatusSettings?
public var invitedBy: Peer?
public var managingBot: ChatManagingBot?
public init(canAddContact: Bool, canReportIrrelevantLocation: Bool, peerStatusSettings: PeerStatusSettings?, invitedBy: Peer?, managingBot: ChatManagingBot?) {
public init(canAddContact: Bool, peerStatusSettings: PeerStatusSettings?, invitedBy: Peer?, managingBot: ChatManagingBot?) {
self.canAddContact = canAddContact
self.canReportIrrelevantLocation = canReportIrrelevantLocation
self.peerStatusSettings = peerStatusSettings
self.invitedBy = invitedBy
self.managingBot = managingBot
@ -286,9 +284,6 @@ public struct ChatContactStatus: Equatable {
if !self.canAddContact {
peerStatusSettings.flags.remove(.canAddContact)
}
if !self.canReportIrrelevantLocation {
peerStatusSettings.flags.remove(.canReportIrrelevantGeoLocation)
}
return peerStatusSettings.flags.isEmpty
}
@ -296,9 +291,6 @@ public struct ChatContactStatus: Equatable {
if lhs.canAddContact != rhs.canAddContact {
return false
}
if lhs.canReportIrrelevantLocation != rhs.canReportIrrelevantLocation {
return false
}
if lhs.peerStatusSettings != rhs.peerStatusSettings {
return false
}
@ -454,6 +446,34 @@ public final class ChatPresentationInterfaceState: Equatable {
case side
}
public final class ReportReasonData: Equatable {
public let title: String
public let option: Data
public let message: String?
public init(title: String, option: Data, message: String?) {
self.title = title
self.option = option
self.message = message
}
public static func ==(lhs: ReportReasonData, rhs: ReportReasonData) -> Bool {
if lhs === rhs {
return true
}
if lhs.title != rhs.title {
return false
}
if lhs.option != rhs.option {
return false
}
if lhs.message != rhs.message {
return false
}
return true
}
}
public let interfaceState: ChatInterfaceState
public let chatLocation: ChatLocation
public let renderedPeer: RenderedPeer?
@ -505,7 +525,7 @@ public final class ChatPresentationInterfaceState: Equatable {
public let activeGroupCallInfo: ChatActiveGroupCallInfo?
public let hasActiveGroupCall: Bool
public let importState: ChatPresentationImportState?
public let reportReason: (String, Data, String?)?
public let reportReason: ReportReasonData?
public let showCommands: Bool
public let hasBotCommands: Bool
public let showSendAsPeers: Bool
@ -638,7 +658,7 @@ public final class ChatPresentationInterfaceState: Equatable {
self.topicListDisplayMode = nil
}
public init(interfaceState: ChatInterfaceState, chatLocation: ChatLocation, renderedPeer: RenderedPeer?, isNotAccessible: Bool, explicitelyCanPinMessages: Bool, contactStatus: ChatContactStatus?, hasBots: Bool, isArchived: Bool, inputTextPanelState: ChatTextInputPanelState, editMessageState: ChatEditInterfaceMessageState?, inputQueryResults: [ChatPresentationInputQueryKind: ChatPresentationInputQueryResult], inputMode: ChatInputMode, titlePanelContexts: [ChatTitlePanelContext], keyboardButtonsMessage: Message?, pinnedMessageId: MessageId?, pinnedMessage: ChatPinnedMessage?, peerIsBlocked: Bool, peerIsMuted: Bool, peerDiscussionId: PeerId?, peerGeoLocation: PeerGeoLocation?, callsAvailable: Bool, callsPrivate: Bool, slowmodeState: ChatSlowmodeState?, chatHistoryState: ChatHistoryNodeHistoryState?, botStartPayload: String?, urlPreview: UrlPreview?, editingUrlPreview: UrlPreview?, search: ChatSearchData?, searchQuerySuggestionResult: ChatPresentationInputQueryResult?, historyFilter: HistoryFilter?, displayHistoryFilterAsList: Bool, presentationReady: Bool, chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, accountPeerId: PeerId, mode: ChatControllerPresentationMode, hasScheduledMessages: Bool, autoremoveTimeout: Int32?, subject: ChatControllerSubject?, peerNearbyData: ChatPeerNearbyData?, greetingData: ChatGreetingData?, pendingUnpinnedAllMessages: Bool, activeGroupCallInfo: ChatActiveGroupCallInfo?, hasActiveGroupCall: Bool, importState: ChatPresentationImportState?, reportReason: (String, Data, String?)?, showCommands: Bool, hasBotCommands: Bool, showSendAsPeers: Bool, sendAsPeers: [SendAsPeer]?, botMenuButton: BotMenuButton, showWebView: Bool, currentSendAsPeerId: PeerId?, copyProtectionEnabled: Bool, hasAtLeast3Messages: Bool, hasPlentyOfMessages: Bool, isPremium: Bool, premiumGiftOptions: [CachedPremiumGiftOption], suggestPremiumGift: Bool, forceInputCommandsHidden: Bool, voiceMessagesAvailable: Bool, customEmojiAvailable: Bool, threadData: ThreadData?, forumTopicData: ThreadData?, isGeneralThreadClosed: Bool?, translationState: ChatPresentationTranslationState?, replyMessage: Message?, accountPeerColor: AccountPeerColor?, savedMessagesTopicPeer: EnginePeer?, hasSearchTags: Bool, isPremiumRequiredForMessaging: Bool, sendPaidMessageStars: StarsAmount?, acknowledgedPaidMessage: Bool, hasSavedChats: Bool, appliedBoosts: Int32?, boostsToUnrestrict: Int32?, businessIntro: TelegramBusinessIntro?, hasBirthdayToday: Bool, adMessage: Message?, peerVerification: PeerVerification?, starGiftsAvailable: Bool, alwaysShowGiftButton: Bool, disallowedGifts: TelegramDisallowedGifts?, topicListDisplayMode: TopicListDisplayMode?) {
public init(interfaceState: ChatInterfaceState, chatLocation: ChatLocation, renderedPeer: RenderedPeer?, isNotAccessible: Bool, explicitelyCanPinMessages: Bool, contactStatus: ChatContactStatus?, hasBots: Bool, isArchived: Bool, inputTextPanelState: ChatTextInputPanelState, editMessageState: ChatEditInterfaceMessageState?, inputQueryResults: [ChatPresentationInputQueryKind: ChatPresentationInputQueryResult], inputMode: ChatInputMode, titlePanelContexts: [ChatTitlePanelContext], keyboardButtonsMessage: Message?, pinnedMessageId: MessageId?, pinnedMessage: ChatPinnedMessage?, peerIsBlocked: Bool, peerIsMuted: Bool, peerDiscussionId: PeerId?, peerGeoLocation: PeerGeoLocation?, callsAvailable: Bool, callsPrivate: Bool, slowmodeState: ChatSlowmodeState?, chatHistoryState: ChatHistoryNodeHistoryState?, botStartPayload: String?, urlPreview: UrlPreview?, editingUrlPreview: UrlPreview?, search: ChatSearchData?, searchQuerySuggestionResult: ChatPresentationInputQueryResult?, historyFilter: HistoryFilter?, displayHistoryFilterAsList: Bool, presentationReady: Bool, chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, bubbleCorners: PresentationChatBubbleCorners, accountPeerId: PeerId, mode: ChatControllerPresentationMode, hasScheduledMessages: Bool, autoremoveTimeout: Int32?, subject: ChatControllerSubject?, peerNearbyData: ChatPeerNearbyData?, greetingData: ChatGreetingData?, pendingUnpinnedAllMessages: Bool, activeGroupCallInfo: ChatActiveGroupCallInfo?, hasActiveGroupCall: Bool, importState: ChatPresentationImportState?, reportReason: ReportReasonData?, showCommands: Bool, hasBotCommands: Bool, showSendAsPeers: Bool, sendAsPeers: [SendAsPeer]?, botMenuButton: BotMenuButton, showWebView: Bool, currentSendAsPeerId: PeerId?, copyProtectionEnabled: Bool, hasAtLeast3Messages: Bool, hasPlentyOfMessages: Bool, isPremium: Bool, premiumGiftOptions: [CachedPremiumGiftOption], suggestPremiumGift: Bool, forceInputCommandsHidden: Bool, voiceMessagesAvailable: Bool, customEmojiAvailable: Bool, threadData: ThreadData?, forumTopicData: ThreadData?, isGeneralThreadClosed: Bool?, translationState: ChatPresentationTranslationState?, replyMessage: Message?, accountPeerColor: AccountPeerColor?, savedMessagesTopicPeer: EnginePeer?, hasSearchTags: Bool, isPremiumRequiredForMessaging: Bool, sendPaidMessageStars: StarsAmount?, acknowledgedPaidMessage: Bool, hasSavedChats: Bool, appliedBoosts: Int32?, boostsToUnrestrict: Int32?, businessIntro: TelegramBusinessIntro?, hasBirthdayToday: Bool, adMessage: Message?, peerVerification: PeerVerification?, starGiftsAvailable: Bool, alwaysShowGiftButton: Bool, disallowedGifts: TelegramDisallowedGifts?, topicListDisplayMode: TopicListDisplayMode?) {
self.interfaceState = interfaceState
self.chatLocation = chatLocation
self.renderedPeer = renderedPeer
@ -894,7 +914,7 @@ public final class ChatPresentationInterfaceState: Equatable {
if lhs.importState != rhs.importState {
return false
}
if lhs.reportReason?.0 != rhs.reportReason?.0 || lhs.reportReason?.1 != rhs.reportReason?.1 || lhs.reportReason?.2 != rhs.reportReason?.2 {
if lhs.reportReason != rhs.reportReason {
return false
}
if lhs.showCommands != rhs.showCommands {
@ -1207,7 +1227,7 @@ public final class ChatPresentationInterfaceState: Equatable {
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: importState, reportReason: self.reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode)
}
public func updatedReportReason(_ reportReason: (String, Data, String?)?) -> ChatPresentationInterfaceState {
public func updatedReportReason(_ reportReason: ReportReasonData?) -> ChatPresentationInterfaceState {
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, contactStatus: self.contactStatus, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, peerGeoLocation: self.peerGeoLocation, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, slowmodeState: self.slowmodeState, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, historyFilter: self.historyFilter, displayHistoryFilterAsList: self.displayHistoryFilterAsList, presentationReady: self.presentationReady, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, bubbleCorners: self.bubbleCorners, accountPeerId: self.accountPeerId, mode: self.mode, hasScheduledMessages: self.hasScheduledMessages, autoremoveTimeout: self.autoremoveTimeout, subject: self.subject, peerNearbyData: self.peerNearbyData, greetingData: self.greetingData, pendingUnpinnedAllMessages: self.pendingUnpinnedAllMessages, activeGroupCallInfo: self.activeGroupCallInfo, hasActiveGroupCall: self.hasActiveGroupCall, importState: self.importState, reportReason: reportReason, showCommands: self.showCommands, hasBotCommands: self.hasBotCommands, showSendAsPeers: self.showSendAsPeers, sendAsPeers: self.sendAsPeers, botMenuButton: self.botMenuButton, showWebView: self.showWebView, currentSendAsPeerId: self.currentSendAsPeerId, copyProtectionEnabled: self.copyProtectionEnabled, hasAtLeast3Messages: self.hasAtLeast3Messages, hasPlentyOfMessages: self.hasPlentyOfMessages, isPremium: self.isPremium, premiumGiftOptions: self.premiumGiftOptions, suggestPremiumGift: self.suggestPremiumGift, forceInputCommandsHidden: self.forceInputCommandsHidden, voiceMessagesAvailable: self.voiceMessagesAvailable, customEmojiAvailable: self.customEmojiAvailable, threadData: self.threadData, forumTopicData: self.forumTopicData, isGeneralThreadClosed: self.isGeneralThreadClosed, translationState: self.translationState, replyMessage: self.replyMessage, accountPeerColor: self.accountPeerColor, savedMessagesTopicPeer: self.savedMessagesTopicPeer, hasSearchTags: self.hasSearchTags, isPremiumRequiredForMessaging: self.isPremiumRequiredForMessaging, sendPaidMessageStars: self.sendPaidMessageStars, acknowledgedPaidMessage: self.acknowledgedPaidMessage, hasSavedChats: self.hasSavedChats, appliedBoosts: self.appliedBoosts, boostsToUnrestrict: self.boostsToUnrestrict, businessIntro: self.businessIntro, hasBirthdayToday: self.hasBirthdayToday, adMessage: self.adMessage, peerVerification: self.peerVerification, starGiftsAvailable: self.starGiftsAvailable, alwaysShowGiftButton: self.alwaysShowGiftButton, disallowedGifts: self.disallowedGifts, topicListDisplayMode: self.topicListDisplayMode)
}
@ -1364,16 +1384,20 @@ public final class ChatPresentationInterfaceState: Equatable {
}
}
public func canBypassRestrictions(chatPresentationInterfaceState: ChatPresentationInterfaceState) -> Bool {
guard let boostsToUnrestrict = chatPresentationInterfaceState.boostsToUnrestrict, boostsToUnrestrict > 0 else {
public func canBypassRestrictions(boostsToUnrestrict: Int32?, appliedBoosts: Int32?) -> Bool {
guard let boostsToUnrestrict, boostsToUnrestrict > 0 else {
return false
}
if let appliedBoosts = chatPresentationInterfaceState.appliedBoosts, appliedBoosts >= boostsToUnrestrict {
if let appliedBoosts, appliedBoosts >= boostsToUnrestrict {
return true
}
return false
}
public func canBypassRestrictions(chatPresentationInterfaceState: ChatPresentationInterfaceState) -> Bool {
return canBypassRestrictions(boostsToUnrestrict: chatPresentationInterfaceState.boostsToUnrestrict, appliedBoosts: chatPresentationInterfaceState.appliedBoosts)
}
public func canSendMessagesToChat(_ state: ChatPresentationInterfaceState) -> Bool {
if let peer = state.renderedPeer?.peer {
let canBypassRestrictions = canBypassRestrictions(chatPresentationInterfaceState: state)

View File

@ -22,6 +22,11 @@ objc_library(
"-Werror",
"-I{}/lottiecpp/Sources".format(package_name()),
],
cxxopts = [
"-Werror",
"-std=c++17",
"-I{}/lottiecpp/Sources".format(package_name()),
],
hdrs = glob([
"lottiecpp/PublicHeaders/**/*.h",
]),
@ -49,6 +54,9 @@ cc_library(
"PublicHeaders",
],
copts = [],
cxxopts = [
"-std=c++17",
],
visibility = ["//visibility:public"],
linkstatic = 1,
)

View File

@ -46,7 +46,7 @@
}
}
NSInteger providerIndex = -1;
__unused NSInteger providerIndex = -1;
for (NSItemProvider *provider in providers)
{
providerIndex++;
@ -140,7 +140,7 @@
}];
}
static UIImage *TGScaleImageToPixelSize(UIImage *image, CGSize size) {
__unused static UIImage *TGScaleImageToPixelSize(UIImage *image, CGSize size) {
UIGraphicsBeginImageContextWithOptions(size, true, 1.0f);
[image drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModeCopy alpha:1.0f];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
@ -149,7 +149,7 @@ static UIImage *TGScaleImageToPixelSize(UIImage *image, CGSize size) {
return result;
}
static CGSize TGFitSize(CGSize size, CGSize maxSize) {
__unused static CGSize TGFitSize(CGSize size, CGSize maxSize) {
if (size.width < 1)
size.width = 1;
if (size.height < 1)

View File

@ -64,12 +64,15 @@ NSString *const TGShareGoogleProvider = @"google";
NSString * TGURLEncodedStringFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
static NSString * const kAFLegalCharactersToBeEscaped = @"?!@#$^&%*+=,:;'\"`<>()[]{}/\\|~ ";
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
NSString *unescapedString = [string stringByReplacingPercentEscapesUsingEncoding:encoding];
if (unescapedString) {
string = unescapedString;
}
return (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kAFLegalCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding));
#pragma clang diagnostic pop
}
@implementation TGQueryStringComponent

View File

@ -23,9 +23,6 @@ extension PeerStatusSettings {
if (flags & (1 << 4)) != 0 {
result.insert(.addExceptionWhenAddingContact)
}
if (flags & (1 << 5)) != 0 {
result.insert(.canReportIrrelevantGeoLocation)
}
if (flags & (1 << 7)) != 0 {
result.insert(.autoArchived)
}

View File

@ -13,7 +13,6 @@ public struct PeerStatusSettings: PostboxCoding, Equatable {
public static let canBlock = Flags(rawValue: 1 << 3)
public static let canAddContact = Flags(rawValue: 1 << 4)
public static let addExceptionWhenAddingContact = Flags(rawValue: 1 << 5)
public static let canReportIrrelevantGeoLocation = Flags(rawValue: 1 << 6)
public static let autoArchived = Flags(rawValue: 1 << 7)
public static let suggestAddMembers = Flags(rawValue: 1 << 8)

View File

@ -559,6 +559,7 @@ private class AdMessagesHistoryContextImpl {
public class AdMessagesHistoryContext {
private let queue = Queue()
private let impl: QueueLocalObject<AdMessagesHistoryContextImpl>
public let peerId: EnginePeer.Id
public var state: Signal<(interPostInterval: Int32?, messages: [Message]), NoError> {
return Signal { subscriber in
@ -576,6 +577,7 @@ public class AdMessagesHistoryContext {
}
public init(account: Account, peerId: PeerId) {
self.peerId = peerId
let queue = self.queue
self.impl = QueueLocalObject(queue: queue, generate: {
return AdMessagesHistoryContextImpl(queue: queue, account: account, peerId: peerId)

View File

@ -112,7 +112,6 @@ public enum EnginePeer: Equatable {
public static let canBlock = Flags(rawValue: 1 << 3)
public static let canAddContact = Flags(rawValue: 1 << 4)
public static let addExceptionWhenAddingContact = Flags(rawValue: 1 << 5)
public static let canReportIrrelevantGeoLocation = Flags(rawValue: 1 << 6)
public static let autoArchived = Flags(rawValue: 1 << 7)
public static let suggestAddMembers = Flags(rawValue: 1 << 8)

View File

@ -134,7 +134,6 @@ public final class ChatRecentActionsController: TelegramBaseController {
}, updateInputLanguage: { _ in
}, unarchiveChat: {
}, openLinkEditing: {
}, reportPeerIrrelevantGeoLocation: {
}, displaySlowmodeTooltip: { _, _ in
}, displaySendMessageOptions: { _, _ in
}, openScheduledMessages: {

View File

@ -398,7 +398,6 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
}, updateInputLanguage: { _ in
}, unarchiveChat: {
}, openLinkEditing: {
}, reportPeerIrrelevantGeoLocation: {
}, displaySlowmodeTooltip: { _, _ in
}, displaySendMessageOptions: { _, _ in
}, openScheduledMessages: {

View File

@ -682,7 +682,6 @@ final class PeerSelectionControllerNode: ASDisplayNode {
})
strongSelf.present(controller, nil)
}
}, reportPeerIrrelevantGeoLocation: {
}, displaySlowmodeTooltip: { _, _ in
}, displaySendMessageOptions: { [weak self] node, gesture in
guard let strongSelf = self else {

View File

@ -384,8 +384,15 @@ extension ChatControllerImpl {
})
}
case let .openChatInfo(expandAvatar, section):
let _ = self.presentVoiceMessageDiscardAlert(action: {
switch self.chatLocationInfoData {
let _ = self.presentVoiceMessageDiscardAlert(action: { [weak self] in
guard let self else {
return
}
guard let contentData = self.contentData else {
return
}
switch contentData.chatLocationInfoData {
case let .peer(peerView):
self.navigationActionDisposable.set((peerView.get()
|> take(1)
@ -413,7 +420,7 @@ extension ChatControllerImpl {
default:
mode = .generic
}
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: mode, avatarInitiallyExpanded: expandAvatar, fromChat: true, requestsContext: strongSelf.inviteRequestsContext) {
if let infoController = strongSelf.context.sharedContext.makePeerInfoController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, mode: mode, avatarInitiallyExpanded: expandAvatar, fromChat: true, requestsContext: strongSelf.contentData?.inviteRequestsContext) {
strongSelf.effectiveNavigationController?.pushViewController(infoController)
}
}
@ -444,7 +451,7 @@ extension ChatControllerImpl {
}
}
} else if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForumOrMonoForum, case let .replyThread(message) = self.chatLocation {
if let infoController = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: self.updatedPresentationData, peer: channel, mode: .forumTopic(thread: message), avatarInitiallyExpanded: false, fromChat: true, requestsContext: self.inviteRequestsContext) {
if let infoController = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: self.updatedPresentationData, peer: channel, mode: .forumTopic(thread: message), avatarInitiallyExpanded: false, fromChat: true, requestsContext: self.contentData?.inviteRequestsContext) {
self.effectiveNavigationController?.pushViewController(infoController)
}
}
@ -459,6 +466,10 @@ extension ChatControllerImpl {
self.dismiss()
}
case .clearCache:
guard let contentData = self.contentData else {
return
}
let controller = OverlayStatusController(theme: self.presentationData.theme, type: .loading(cancelled: nil))
self.present(controller, in: .window(.root))
@ -470,7 +481,7 @@ extension ChatControllerImpl {
self.clearCacheDisposable = disposable
}
switch self.chatLocationInfoData {
switch contentData.chatLocationInfoData {
case let .peer(peerView):
self.navigationActionDisposable.set((peerView.get()
|> take(1)

View File

@ -42,7 +42,7 @@ extension ChatControllerImpl {
presentationData = presentationData.withUpdated(theme: defaultDarkColorPresentationTheme)
}
var peer = peer
if let peerDiscussionId = self.presentationInterfaceState.peerDiscussionId, let channel = self.peerView?.peers[peerDiscussionId] {
if let peerDiscussionId = self.presentationInterfaceState.peerDiscussionId, let channel = self.contentData?.state.peerView?.peers[peerDiscussionId] {
peer = EnginePeer(channel)
}
let controller = chatMessagePaymentAlertController(

View File

@ -168,7 +168,7 @@ extension ChatControllerImpl {
}
var canResetWallpaper = false
if let cachedUserData = strongSelf.peerView?.cachedData as? CachedUserData {
if let cachedUserData = strongSelf.contentData?.state.peerView?.cachedData as? CachedUserData {
canResetWallpaper = cachedUserData.wallpaper != nil
}

View File

@ -137,11 +137,6 @@ import TelegramCallsUI
import QuickShareScreen
import PostSuggestionsSettingsScreen
public enum ChatControllerPeekActions {
case standard
case remove(() -> Void)
}
public final class ChatControllerOverlayPresentationData {
public let expandData: (ASDisplayNode?, () -> Void)
public init(expandData: (ASDisplayNode?, () -> Void)) {
@ -243,31 +238,31 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let chatNavigationStack: [ChatNavigationStackItem]
let customChatNavigationStack: [EnginePeer.Id]?
public var peekActions: ChatControllerPeekActions = .standard
var didSetup3dTouch: Bool = false
var didSetupDropToPaste: Bool = false
let context: AccountContext
public internal(set) var chatLocation: ChatLocation
public let subject: ChatControllerSubject?
var botStart: ChatControllerInitialBotStart?
var attachBotStart: ChatControllerInitialAttachBotStart?
var botAppStart: ChatControllerInitialBotAppStart?
var mode: ChatControllerPresentationMode
let peerDisposable = MetaDisposable()
let titleDisposable = MetaDisposable()
var pendingContentData: (contentData: ChatControllerImpl.ContentData, historyNode: ChatHistoryListNodeImpl)?
var contentData: ChatControllerImpl.ContentData?
let contentDataReady = ValuePromise<Bool>(false, ignoreRepeated: true)
var contentDataDisposable: Disposable?
var didHandlePerformDismissAction: Bool = false
var accountPeerDisposable: Disposable?
let navigationActionDisposable = MetaDisposable()
var networkStateDisposable: Disposable?
let messageIndexDisposable = MetaDisposable()
let _chatLocationInfoReady = Promise<Bool>()
var didSetChatLocationInfoReady = false
var chatLocationInfoData: ChatLocationInfoData
let cachedDataReady = Promise<Bool>()
var didSetCachedDataReady = false
let navigationActionDisposable = MetaDisposable()
let messageIndexDisposable = MetaDisposable()
var networkStateDisposable: Disposable?
let wallpaperReady = Promise<Bool>()
let presentationReady = Promise<Bool>()
@ -294,9 +289,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var moreBarButton: MoreHeaderButton
var moreInfoNavigationButton: ChatNavigationButton?
var peerView: PeerView?
var threadInfo: EngineMessageHistoryThread.Info?
var historyStateDisposable: Disposable?
let galleryHiddenMesageAndMediaDisposable = MetaDisposable()
@ -343,14 +335,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var stateServiceTasks: [AnyHashable: Disposable] = [:]
var preloadHistoryPeerId: PeerId?
let preloadHistoryPeerIdDisposable = MetaDisposable()
var preloadNextChatPeerId: PeerId?
let preloadNextChatPeerIdDisposable = MetaDisposable()
var preloadSavedMessagesChatsDisposable: Disposable?
let botCallbackAlertMessage = Promise<String?>(nil)
var botCallbackAlertMessageDisposable: Disposable?
@ -381,8 +365,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var recorderDataDisposable = MetaDisposable()
var buttonKeyboardMessageDisposable: Disposable?
var cachedDataDisposable: Disposable?
var chatUnreadCountDisposable: Disposable?
var buttonUnreadCountDisposable: Disposable?
var chatUnreadMentionCountDisposable: Disposable?
@ -411,8 +393,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
public let canReadHistory = ValuePromise<Bool>(true, ignoreRepeated: true)
public let hasBrowserOrAppInFront = Promise<Bool>(false)
var reminderActivity: NSUserActivity?
var isReminderActivityEnabled: Bool = false
var canReadHistoryValue = false {
didSet {
@ -505,13 +485,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
weak var currentPinchSourceItemNode: ListViewItemNode?
var screenCaptureManager: ScreenCaptureDetectionManager?
let chatAdditionalDataDisposable = MetaDisposable()
var reportIrrelvantGeoNoticePromise = Promise<Bool?>()
var reportIrrelvantGeoNotice: Bool?
var reportIrrelvantGeoDisposable: Disposable?
var hasScheduledMessages: Bool = false
var volumeButtonsListener: VolumeButtonsListener?
@ -536,7 +509,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let selectAddMemberDisposable = MetaDisposable()
let addMemberDisposable = MetaDisposable()
let joinChannelDisposable = MetaDisposable()
var premiumOrStarsRequiredDisposable: Disposable?
var shouldDisplayDownButton = false
@ -583,40 +555,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
public var isSelectingMessagesUpdated: ((Bool) -> Void)?
let scrolledToMessageId = ValuePromise<ScrolledToMessageId?>(nil, ignoreRepeated: true)
var scrolledToMessageIdValue: ScrolledToMessageId? = nil {
didSet {
self.scrolledToMessageId.set(self.scrolledToMessageIdValue)
}
}
var translationStateDisposable: Disposable?
var premiumGiftSuggestionDisposable: Disposable?
var nextChannelToReadDisposable: Disposable?
var offerNextChannelToRead = false
var inviteRequestsContext: PeerInvitationImportersContext?
var inviteRequestsDisposable = MetaDisposable()
var overlayTitle: String? {
var title: String?
if let threadInfo = self.threadInfo {
title = threadInfo.title
} else if let peerView = self.peerView {
if let peer = peerViewMainPeer(peerView) {
title = EnginePeer(peer).displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder)
}
}
return title
}
var currentSpeechHolder: SpeechSynthesizerHolder?
var powerSavingMonitoringDisposable: Disposable?
var avatarNode: ChatAvatarNavigationNode?
var storyStats: PeerStoryStats?
var performTextSelectionAction: ((Message?, Bool, NSAttributedString, TextSelectionAction) -> Void)?
var performOpenURL: ((Message?, String, Promise<Bool>?) -> Void)?
@ -728,27 +674,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
default:
groupCallPanelSource = .none
}
self.chatLocationInfoData = .peer(Promise())
case let .replyThread(replyThreadMessage):
case .replyThread:
locationBroadcastPanelSource = .none
groupCallPanelSource = .none
let promise = Promise<Message?>()
if let effectiveMessageId = replyThreadMessage.effectiveMessageId {
promise.set(context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.Message(id: effectiveMessageId))
|> map { message -> Message? in
guard let message = message else {
return nil
}
return message._asMessage()
})
} else {
promise.set(.single(nil))
}
self.chatLocationInfoData = .replyThread(promise)
case .customChatContents:
locationBroadcastPanelSource = .none
groupCallPanelSource = .none
self.chatLocationInfoData = .customChatContents
}
var presentationData = context.sharedContext.currentPresentationData.with { $0 }
@ -1325,7 +1256,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let adAttribute = message.attributes.first(where: { $0 is AdMessageAttribute }) as? AdMessageAttribute {
if let file = message.media.first(where: { $0 is TelegramMediaFile}) as? TelegramMediaFile, file.isVideo && !file.isAnimated {
self.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId, media: true, fullscreen: false)
self.chatDisplayNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId, media: true, fullscreen: false)
} else {
self.controllerInteraction?.activateAdAction(message.id, nil, true, false)
return true
@ -1495,7 +1426,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
legacyMediaEditor(context: self.context, peer: peer, threadTitle: self.threadInfo?.title, media: mediaReference, mode: .draw, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
legacyMediaEditor(context: self.context, peer: peer, threadTitle: self.contentData?.state.threadInfo?.title, media: mediaReference, mode: .draw, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
transitionCompletion()
}, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView(isFile: false)
@ -2682,7 +2613,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if let message, let adAttribute = message.attributes.first(where: { $0 is AdMessageAttribute }) as? AdMessageAttribute {
strongSelf.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId, media: false, fullscreen: false)
strongSelf.chatDisplayNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId, media: false, fullscreen: false)
}
if let performOpenURL = strongSelf.performOpenURL {
@ -2867,7 +2798,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return
}
if let cachedUserData = strongSelf.peerView?.cachedData as? CachedUserData, cachedUserData.callsPrivate {
if let cachedUserData = strongSelf.contentData?.state.peerView?.cachedData as? CachedUserData, cachedUserData.callsPrivate {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: presentationData.strings.Call_ConnectionErrorTitle, text: presentationData.strings.Call_PrivacyErrorMessage(EnginePeer(peer).compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
@ -3887,7 +3818,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
let inputText = strongSelf.presentationInterfaceState.interfaceState.effectiveInputState.inputText
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, mode: .draw, initialCaption: inputText, snapshots: [], transitionCompletion: nil, getCaptionPanelView: { [weak self] in
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.contentData?.state.threadInfo?.title, media: mediaReference, mode: .draw, initialCaption: inputText, snapshots: [], transitionCompletion: nil, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView(isFile: true)
}, sendMessagesWithSignals: { [weak self] signals, _, _, _ in
if let strongSelf = self {
@ -4051,7 +3982,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
}
self.chatDisplayNode.historyNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId, media: media, fullscreen: fullscreen)
self.chatDisplayNode.adMessagesContext?.markAction(opaqueId: adAttribute.opaqueId, media: media, fullscreen: fullscreen)
self.controllerInteraction?.openUrl(ChatControllerInteraction.OpenUrl(url: adAttribute.url, concealed: false, external: true, progress: progress))
}, adContextAction: { [weak self] message, sourceNode, gesture in
guard let self else {
@ -4642,7 +4573,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let premiumOptions = giftOptions.filter { $0.users == 1 }.map { CachedPremiumGiftOption(months: $0.months, currency: $0.currency, amount: $0.amount, botUrl: "", storeProductId: $0.storeProductId) }
var hasBirthday = false
if let cachedUserData = self.peerView?.cachedData as? CachedUserData {
if let cachedUserData = self.contentData?.state.peerView?.cachedData as? CachedUserData {
hasBirthday = hasBirthdayToday(cachedData: cachedUserData)
}
let controller = self.context.sharedContext.makeGiftOptionsController(context: context, peerId: peerId, premiumOptions: premiumOptions, hasBirthday: hasBirthday, completion: nil)
@ -4862,7 +4793,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.navigationItem.titleView = self.chatTitleView
self.chatTitleView?.longPressed = { [weak self] in
if let strongSelf = self, let peerView = strongSelf.peerView, let peer = peerView.peers[peerView.peerId], peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil && !strongSelf.presentationInterfaceState.isNotAccessible {
if let strongSelf = self, let peerView = strongSelf.contentData?.state.peerView, let peer = peerView.peers[peerView.peerId], peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil && !strongSelf.presentationInterfaceState.isNotAccessible {
if case .standard(.previewing) = strongSelf.mode {
} else {
strongSelf.interfaceInteraction?.beginMessageSearch(.everything, "")
@ -5299,7 +5230,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}
self.reloadChatLocation(chatLocation: self.chatLocation, isReady: nil)
self.reloadChatLocation(chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, historyNode: self.chatDisplayNode.historyNode, isReady: nil)
self.botCallbackAlertMessageDisposable = (self.botCallbackAlertMessage.get()
|> deliverOnMainQueue).startStrict(next: { [weak self] message in
@ -5782,8 +5713,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let strongSelf = self, strongSelf.canReadHistoryValue != value {
strongSelf.canReadHistoryValue = value
strongSelf.raiseToListen?.enabled = value
strongSelf.isReminderActivityEnabled = value
strongSelf.updateReminderActivity()
}
})
@ -5808,104 +5737,89 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let _ = ChatControllerCount.modify { value in
return value - 1
}
let deallocate: () -> Void = {
self.historyStateDisposable?.dispose()
self.messageIndexDisposable.dispose()
self.navigationActionDisposable.dispose()
self.galleryHiddenMesageAndMediaDisposable.dispose()
self.temporaryHiddenGalleryMediaDisposable.dispose()
self.peerDisposable.dispose()
self.accountPeerDisposable?.dispose()
self.titleDisposable.dispose()
self.messageContextDisposable.dispose()
self.controllerNavigationDisposable.dispose()
self.sentMessageEventsDisposable.dispose()
self.failedMessageEventsDisposable.dispose()
self.sentPeerMediaMessageEventsDisposable.dispose()
self.messageActionCallbackDisposable.dispose()
self.messageActionUrlAuthDisposable.dispose()
self.editMessageDisposable.dispose()
self.editMessageErrorsDisposable.dispose()
self.enqueueMediaMessageDisposable.dispose()
self.resolvePeerByNameDisposable?.dispose()
self.shareStatusDisposable?.dispose()
self.clearCacheDisposable?.dispose()
self.bankCardDisposable?.dispose()
self.botCallbackAlertMessageDisposable?.dispose()
self.selectMessagePollOptionDisposables?.dispose()
for (_, info) in self.contextQueryStates {
info.1.dispose()
}
self.urlPreviewQueryState?.1.dispose()
self.editingUrlPreviewQueryState?.1.dispose()
self.replyMessageState?.1.dispose()
self.audioRecorderDisposable?.dispose()
self.audioRecorderStatusDisposable?.dispose()
self.videoRecorderDisposable?.dispose()
self.buttonKeyboardMessageDisposable?.dispose()
self.cachedDataDisposable?.dispose()
self.resolveUrlDisposable?.dispose()
self.chatUnreadCountDisposable?.dispose()
self.buttonUnreadCountDisposable?.dispose()
self.chatUnreadMentionCountDisposable?.dispose()
self.peerInputActivitiesDisposable?.dispose()
self.interactiveEmojiSyncDisposable.dispose()
self.recentlyUsedInlineBotsDisposable?.dispose()
self.unpinMessageDisposable?.dispose()
self.inputActivityDisposable?.dispose()
self.recordingActivityDisposable?.dispose()
self.acquiredRecordingActivityDisposable?.dispose()
self.presentationDataDisposable?.dispose()
self.searchDisposable?.dispose()
self.applicationInForegroundDisposable?.dispose()
self.applicationInFocusDisposable?.dispose()
self.canReadHistoryDisposable?.dispose()
self.networkStateDisposable?.dispose()
self.chatAdditionalDataDisposable.dispose()
self.shareStatusDisposable?.dispose()
self.context.sharedContext.mediaManager.galleryHiddenMediaManager.removeTarget(self)
self.preloadHistoryPeerIdDisposable.dispose()
self.preloadNextChatPeerIdDisposable.dispose()
self.reportIrrelvantGeoDisposable?.dispose()
self.reminderActivity?.invalidate()
self.updateSlowmodeStatusDisposable.dispose()
self.keepPeerInfoScreenDataHotDisposable.dispose()
self.preloadAvatarDisposable.dispose()
self.peekTimerDisposable.dispose()
self.hasActiveGroupCallDisposable?.dispose()
self.createVoiceChatDisposable.dispose()
self.checksTooltipDisposable.dispose()
self.peerSuggestionsDisposable.dispose()
self.peerSuggestionsDismissDisposable.dispose()
self.selectAddMemberDisposable.dispose()
self.addMemberDisposable.dispose()
self.joinChannelDisposable.dispose()
self.nextChannelToReadDisposable?.dispose()
self.inviteRequestsDisposable.dispose()
self.sendAsPeersDisposable?.dispose()
self.preloadAttachBotIconsDisposables?.dispose()
self.keepMessageCountersSyncrhonizedDisposable?.dispose()
self.keepSavedMessagesSyncrhonizedDisposable?.dispose()
self.translationStateDisposable?.dispose()
self.premiumGiftSuggestionDisposable?.dispose()
self.powerSavingMonitoringDisposable?.dispose()
self.saveMediaDisposable?.dispose()
self.giveawayStatusDisposable?.dispose()
self.nameColorDisposable?.dispose()
self.choosingStickerActivityDisposable?.dispose()
self.automaticMediaDownloadSettingsDisposable?.dispose()
self.stickerSettingsDisposable?.dispose()
self.searchQuerySuggestionState?.1.dispose()
self.preloadSavedMessagesChatsDisposable?.dispose()
self.recorderDataDisposable.dispose()
self.displaySendWhenOnlineTipDisposable.dispose()
self.networkSpeedEventsDisposable?.dispose()
self.postedScheduledMessagesEventsDisposable?.dispose()
self.premiumOrStarsRequiredDisposable?.dispose()
self.updateChatLocationThreadDisposable?.dispose()
self.historyStateDisposable?.dispose()
self.messageIndexDisposable.dispose()
self.navigationActionDisposable.dispose()
self.galleryHiddenMesageAndMediaDisposable.dispose()
self.temporaryHiddenGalleryMediaDisposable.dispose()
self.messageContextDisposable.dispose()
self.controllerNavigationDisposable.dispose()
self.sentMessageEventsDisposable.dispose()
self.failedMessageEventsDisposable.dispose()
self.sentPeerMediaMessageEventsDisposable.dispose()
self.messageActionCallbackDisposable.dispose()
self.messageActionUrlAuthDisposable.dispose()
self.editMessageDisposable.dispose()
self.editMessageErrorsDisposable.dispose()
self.enqueueMediaMessageDisposable.dispose()
self.resolvePeerByNameDisposable?.dispose()
self.shareStatusDisposable?.dispose()
self.clearCacheDisposable?.dispose()
self.bankCardDisposable?.dispose()
self.botCallbackAlertMessageDisposable?.dispose()
self.selectMessagePollOptionDisposables?.dispose()
for (_, info) in self.contextQueryStates {
info.1.dispose()
}
deallocate()
self.urlPreviewQueryState?.1.dispose()
self.editingUrlPreviewQueryState?.1.dispose()
self.replyMessageState?.1.dispose()
self.audioRecorderDisposable?.dispose()
self.audioRecorderStatusDisposable?.dispose()
self.videoRecorderDisposable?.dispose()
self.resolveUrlDisposable?.dispose()
self.chatUnreadCountDisposable?.dispose()
self.buttonUnreadCountDisposable?.dispose()
self.chatUnreadMentionCountDisposable?.dispose()
self.peerInputActivitiesDisposable?.dispose()
self.interactiveEmojiSyncDisposable.dispose()
self.recentlyUsedInlineBotsDisposable?.dispose()
self.unpinMessageDisposable?.dispose()
self.inputActivityDisposable?.dispose()
self.recordingActivityDisposable?.dispose()
self.acquiredRecordingActivityDisposable?.dispose()
self.presentationDataDisposable?.dispose()
self.searchDisposable?.dispose()
self.applicationInForegroundDisposable?.dispose()
self.applicationInFocusDisposable?.dispose()
self.canReadHistoryDisposable?.dispose()
self.networkStateDisposable?.dispose()
self.shareStatusDisposable?.dispose()
self.context.sharedContext.mediaManager.galleryHiddenMediaManager.removeTarget(self)
self.updateSlowmodeStatusDisposable.dispose()
self.keepPeerInfoScreenDataHotDisposable.dispose()
self.preloadAvatarDisposable.dispose()
self.peekTimerDisposable.dispose()
self.hasActiveGroupCallDisposable?.dispose()
self.createVoiceChatDisposable.dispose()
self.checksTooltipDisposable.dispose()
self.peerSuggestionsDisposable.dispose()
self.peerSuggestionsDismissDisposable.dispose()
self.selectAddMemberDisposable.dispose()
self.addMemberDisposable.dispose()
self.joinChannelDisposable.dispose()
self.sendAsPeersDisposable?.dispose()
self.preloadAttachBotIconsDisposables?.dispose()
self.keepMessageCountersSyncrhonizedDisposable?.dispose()
self.keepSavedMessagesSyncrhonizedDisposable?.dispose()
self.translationStateDisposable?.dispose()
self.premiumGiftSuggestionDisposable?.dispose()
self.powerSavingMonitoringDisposable?.dispose()
self.saveMediaDisposable?.dispose()
self.giveawayStatusDisposable?.dispose()
self.nameColorDisposable?.dispose()
self.choosingStickerActivityDisposable?.dispose()
self.automaticMediaDownloadSettingsDisposable?.dispose()
self.stickerSettingsDisposable?.dispose()
self.searchQuerySuggestionState?.1.dispose()
self.recorderDataDisposable.dispose()
self.displaySendWhenOnlineTipDisposable.dispose()
self.networkSpeedEventsDisposable?.dispose()
self.postedScheduledMessagesEventsDisposable?.dispose()
self.updateChatLocationThreadDisposable?.dispose()
self.accountPeerDisposable?.dispose()
self.contentDataDisposable?.dispose()
}
public func updatePresentationMode(_ mode: ChatControllerPresentationMode) {
@ -6039,10 +5953,48 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
self.chatTitleView?.updateThemeAndStrings(theme: presentationTheme, strings: self.presentationData.strings, hasEmbeddedTitleContent: self.hasEmbeddedTitleContent)
}
func topPinnedMessageSignal(latest: Bool) -> Signal<ChatPinnedMessage?, NoError> {
var pinnedPeerId: EnginePeer.Id?
let threadId = self.chatLocation.threadId
let loadState: Signal<Bool, NoError> = self.chatDisplayNode.historyNode.historyState.get()
enum PinnedReferenceMessage {
struct Loaded {
var id: MessageId
var minId: MessageId
var isScrolled: Bool
}
case ready(Loaded)
case loading
}
static func topPinnedScrollReferenceMessage(historyNode: ChatHistoryListNodeImpl, scrolledToMessageId: Signal<ScrolledToMessageId?, NoError>) -> Signal<PinnedReferenceMessage?, NoError> {
return combineLatest(queue: Queue.mainQueue(),
scrolledToMessageId,
historyNode.topVisibleMessageRange.get()
)
|> map { scrolledToMessageId, topVisibleMessageRange -> PinnedReferenceMessage? in
if let topVisibleMessageRange, topVisibleMessageRange.isLoading {
return .loading
}
let bottomVisibleMessage = topVisibleMessageRange?.lowerBound.id
let topVisibleMessage = topVisibleMessageRange?.upperBound.id
if let scrolledToMessageId = scrolledToMessageId {
if let topVisibleMessage, let bottomVisibleMessage {
if scrolledToMessageId.allowedReplacementDirection.contains(.up) && topVisibleMessage < scrolledToMessageId.id {
return .ready(PinnedReferenceMessage.Loaded(id: topVisibleMessage, minId: bottomVisibleMessage, isScrolled: false))
}
}
return .ready(PinnedReferenceMessage.Loaded(id: scrolledToMessageId.id, minId: scrolledToMessageId.id, isScrolled: true))
} else if let topVisibleMessage, let bottomVisibleMessage {
return .ready(PinnedReferenceMessage.Loaded(id: topVisibleMessage, minId: bottomVisibleMessage, isScrolled: false))
} else {
return nil
}
}
}
static func topPinnedScrollMessage(context: AccountContext, chatLocation: ChatLocation, historyNode: ChatHistoryListNodeImpl, scrolledToMessageId: Signal<ScrolledToMessageId?, NoError>) -> Signal<ChatPinnedMessage?, NoError> {
//TODO:release move to ContentData
let loadState: Signal<Bool, NoError> = historyNode.historyState.get()
|> map { state -> Bool in
switch state {
case .loading:
@ -6053,12 +6005,28 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
|> distinctUntilChanged
switch self.chatLocation {
let referenceMessage = self.topPinnedScrollReferenceMessage(historyNode: historyNode, scrolledToMessageId: scrolledToMessageId)
return loadState
|> mapToSignal { loadState in
if !loadState {
return .single(nil)
} else {
return ChatControllerImpl.topPinnedMessageSignal(context: context, chatLocation: chatLocation, referenceMessage: referenceMessage)
}
}
}
static func topPinnedMessageSignal(context: AccountContext, chatLocation: ChatLocation, referenceMessage: Signal<PinnedReferenceMessage?, NoError>?) -> Signal<ChatPinnedMessage?, NoError> {
var pinnedPeerId: EnginePeer.Id?
let threadId = chatLocation.threadId
switch chatLocation {
case let .peer(id):
pinnedPeerId = id
case let .replyThread(message):
if message.isForumPost {
pinnedPeerId = self.chatLocation.peerId
pinnedPeerId = chatLocation.peerId
}
default:
break
@ -6067,51 +6035,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let peerId = pinnedPeerId {
let topPinnedMessage: Signal<ChatPinnedMessage?, NoError>
enum ReferenceMessage {
struct Loaded {
var id: MessageId
var minId: MessageId
var isScrolled: Bool
}
case ready(Loaded)
case loading
}
let referenceMessage: Signal<ReferenceMessage?, NoError>
if latest {
referenceMessage = .single(nil)
} else {
referenceMessage = combineLatest(
queue: Queue.mainQueue(),
self.scrolledToMessageId.get(),
self.chatDisplayNode.historyNode.topVisibleMessageRange.get()
)
|> map { scrolledToMessageId, topVisibleMessageRange -> ReferenceMessage? in
if let topVisibleMessageRange = topVisibleMessageRange, topVisibleMessageRange.isLoading {
return .loading
}
let bottomVisibleMessage = topVisibleMessageRange?.lowerBound.id
let topVisibleMessage = topVisibleMessageRange?.upperBound.id
if let scrolledToMessageId = scrolledToMessageId {
if let topVisibleMessage, let bottomVisibleMessage {
if scrolledToMessageId.allowedReplacementDirection.contains(.up) && topVisibleMessage < scrolledToMessageId.id {
return .ready(ReferenceMessage.Loaded(id: topVisibleMessage, minId: bottomVisibleMessage, isScrolled: false))
}
}
return .ready(ReferenceMessage.Loaded(id: scrolledToMessageId.id, minId: scrolledToMessageId.id, isScrolled: true))
} else if let topVisibleMessage, let bottomVisibleMessage {
return .ready(ReferenceMessage.Loaded(id: topVisibleMessage, minId: bottomVisibleMessage, isScrolled: false))
} else {
return nil
}
}
}
let context = self.context
func pinnedHistorySignal(anchorMessageId: MessageId?, count: Int) -> Signal<ChatHistoryViewUpdate, NoError> {
let location: ChatHistoryLocation
if let anchorMessageId = anchorMessageId {
@ -6187,36 +6110,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
let adjustedReplyHistory: Signal<PinnedHistory, NoError>
if latest {
adjustedReplyHistory = pinnedHistorySignal(anchorMessageId: nil, count: loadCount)
|> map { view -> PinnedHistory in
switch view {
case .Loading:
return PinnedHistory(messages: [], totalCount: 0)
case let .HistoryView(viewValue, _, _, _, _, _, _):
var messages: [PinnedHistory.PinnedMessage] = []
var totalCount = viewValue.entries.count
for i in 0 ..< viewValue.entries.count {
let index: Int
if !viewValue.holeEarlier && viewValue.earlierId == nil {
index = i
} else if let location = viewValue.entries[i].location {
index = location.index
totalCount = location.count
} else {
index = i
}
messages.append(PinnedHistory.PinnedMessage(
message: viewValue.entries[i].message,
index: index
))
}
return PinnedHistory(messages: messages, totalCount: totalCount)
}
}
} else {
if let referenceMessage {
adjustedReplyHistory = (Signal<PinnedHistory, NoError> { subscriber in
var referenceMessageValue: ReferenceMessage?
var referenceMessageValue: PinnedReferenceMessage?
var view: ChatHistoryViewUpdate?
let updateState: () -> Void = {
@ -6298,19 +6194,41 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
|> runOn(.mainQueue()))
|> restart
} else {
adjustedReplyHistory = pinnedHistorySignal(anchorMessageId: nil, count: loadCount)
|> map { view -> PinnedHistory in
switch view {
case .Loading:
return PinnedHistory(messages: [], totalCount: 0)
case let .HistoryView(viewValue, _, _, _, _, _, _):
var messages: [PinnedHistory.PinnedMessage] = []
var totalCount = viewValue.entries.count
for i in 0 ..< viewValue.entries.count {
let index: Int
if !viewValue.holeEarlier && viewValue.earlierId == nil {
index = i
} else if let location = viewValue.entries[i].location {
index = location.index
totalCount = location.count
} else {
index = i
}
messages.append(PinnedHistory.PinnedMessage(
message: viewValue.entries[i].message,
index: index
))
}
return PinnedHistory(messages: messages, totalCount: totalCount)
}
}
}
topPinnedMessage = combineLatest(queue: .mainQueue(),
adjustedReplyHistory,
topMessage,
referenceMessage,
loadState
referenceMessage ?? .single(nil)
)
|> map { pinnedMessages, topMessage, referenceMessage, loadState -> ChatPinnedMessage? in
if !loadState {
return nil
}
|> map { pinnedMessages, topMessage, referenceMessage -> ChatPinnedMessage? in
var message: ChatPinnedMessage?
let topMessageId: MessageId
@ -6584,12 +6502,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}
if !self.didSetup3dTouch {
self.didSetup3dTouch = true
if #available(iOSApplicationExtension 11.0, iOS 11.0, *) {
let dropInteraction = UIDropInteraction(delegate: self)
self.chatDisplayNode.view.addInteraction(dropInteraction)
}
if !self.didSetupDropToPaste {
self.didSetupDropToPaste = true
let dropInteraction = UIDropInteraction(delegate: self)
self.chatDisplayNode.view.addInteraction(dropInteraction)
}
if !self.checkedPeerChatServiceActions {
@ -7224,7 +7140,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let button = self.rightNavigationButton {
if case .standard(.previewing) = self.mode {
self.navigationButtonAction(button.action)
} else if case let .peer(peerId) = self.chatLocation, case .openChatInfo(expandAvatar: true, _) = button.action, let storyStats = self.storyStats, storyStats.unseenCount != 0, let avatarNode = self.avatarNode {
} else if case let .peer(peerId) = self.chatLocation, case .openChatInfo(expandAvatar: true, _) = button.action, let storyStats = self.contentData?.state.storyStats, storyStats.unseenCount != 0, let avatarNode = self.avatarNode {
self.openStories(peerId: peerId, avatarHeaderNode: nil, avatarNode: avatarNode.avatarNode)
} else {
self.navigationButtonAction(button.action)
@ -8729,7 +8645,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard let self else {
return
}
let disposable = openUserGeneratedUrl(context: self.context, peerId: self.peerView?.peerId, url: url, concealed: concealed, skipUrlAuth: skipUrlAuth, skipConcealedAlert: skipConcealedAlert, present: { [weak self] c in
let disposable = openUserGeneratedUrl(context: self.context, peerId: self.contentData?.state.peerView?.peerId, url: url, concealed: concealed, skipUrlAuth: skipUrlAuth, skipConcealedAlert: skipConcealedAlert, present: { [weak self] c in
self?.present(c, in: .window(.root))
}, openResolved: { [weak self] resolved in
self?.openResolved(result: resolved, sourceMessageId: message?.id, progress: progress, forceExternal: forceExternal, concealed: concealed, commit: commit)
@ -8809,7 +8725,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
public func beginReportSelection(reason: NavigateToChatControllerParams.ReportReason) {
self.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedReportReason((reason.title, reason.option, reason.message)).updatedInterfaceState { $0.withUpdatedSelectedMessages([]) } })
self.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedReportReason(ChatPresentationInterfaceState.ReportReasonData(title: reason.title, option: reason.option, message: reason.message)).updatedInterfaceState { $0.withUpdatedSelectedMessages([]) } })
}
func displayMediaRecordingTooltip() {
@ -8987,7 +8903,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard let rect = self.chatDisplayNode.frameForEmojiButton(), self.effectiveNavigationController?.topViewController === self else {
return
}
guard let peerId = self.chatLocation.peerId, let emojiPack = (self.peerView?.cachedData as? CachedChannelData)?.emojiPack, let thumbnailFileId = emojiPack.thumbnailFileId else {
guard let peerId = self.chatLocation.peerId, let emojiPack = (self.contentData?.state.peerView?.cachedData as? CachedChannelData)?.emojiPack, let thumbnailFileId = emojiPack.thumbnailFileId else {
return
}
@ -9042,7 +8958,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
guard !self.didDisplayBirthdayTooltip else {
return
}
if let birthday = (self.peerView?.cachedData as? CachedUserData)?.birthday {
if let birthday = (self.contentData?.state.peerView?.cachedData as? CachedUserData)?.birthday {
PeerInfoScreenImpl.preloadBirthdayAnimations(context: self.context, birthday: birthday)
}
guard let rect = self.chatDisplayNode.frameForGiftButton(), self.effectiveNavigationController?.topViewController === self, let peer = self.presentationInterfaceState.renderedPeer?.peer.flatMap({ EnginePeer($0) }) else {
@ -9286,34 +9202,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})
}
func updateReminderActivity() {
if self.isReminderActivityEnabled && false {
if #available(iOS 9.0, *) {
if self.reminderActivity == nil, case let .peer(peerId) = self.chatLocation, let peer = self.presentationInterfaceState.renderedPeer?.chatMainPeer {
let reminderActivity = NSUserActivity(activityType: "RemindAboutChatIntent")
self.reminderActivity = reminderActivity
if peer is TelegramGroup {
reminderActivity.title = self.presentationData.strings.Activity_RemindAboutGroup(EnginePeer(peer).displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder)).string
} else if let channel = peer as? TelegramChannel {
if case .broadcast = channel.info {
reminderActivity.title = self.presentationData.strings.Activity_RemindAboutChannel(EnginePeer(peer).displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder)).string
} else {
reminderActivity.title = self.presentationData.strings.Activity_RemindAboutGroup(EnginePeer(peer).displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder)).string
}
} else {
reminderActivity.title = self.presentationData.strings.Activity_RemindAboutUser(EnginePeer(peer).displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder)).string
}
reminderActivity.userInfo = ["peerId": peerId.toInt64(), "peerTitle": EnginePeer(peer).displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder)]
reminderActivity.isEligibleForHandoff = true
reminderActivity.becomeCurrent()
}
}
} else if let reminderActivity = self.reminderActivity {
self.reminderActivity = nil
reminderActivity.invalidate()
}
}
func updateSlowmodeStatus() {
if let slowmodeState = self.presentationInterfaceState.slowmodeState, case let .timestamp(slowmodeActiveUntilTimestamp) = slowmodeState.variant {
let timestamp = Int32(Date().timeIntervalSince1970)
@ -9783,7 +9671,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
func updateNextChannelToReadVisibility() {
self.chatDisplayNode.historyNode.offerNextChannelToRead = self.offerNextChannelToRead && self.presentationInterfaceState.interfaceState.selectionState == nil
guard let contentData = self.contentData else {
return
}
self.chatDisplayNode.historyNode.offerNextChannelToRead = contentData.state.offerNextChannelToRead && self.presentationInterfaceState.interfaceState.selectionState == nil
}
func displayGiveawayStatusInfo(messageId: EngineMessage.Id, giveawayInfo: PremiumGiveawayInfo) {
@ -9820,7 +9711,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
var currentChatSwitchDirection: ChatControllerAnimateInnerChatSwitchDirection?
public func updateChatLocationThread(threadId: Int64?, animationDirection: ChatControllerAnimateInnerChatSwitchDirection? = nil) {
if self.isUpdatingChatLocationThread {
/*if self.isUpdatingChatLocationThread {
return
}
@ -9836,6 +9727,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let navigationSnapshot = self.chatTitleView?.prepareSnapshotState()
//let historyNode = self.chatDisplayNode.createHistoryNodeForChatLocation(chatLocation: self.chatLocation, chatLocationContextHolder: )
let rightBarButtonItemSnapshots: [(UIView, CGRect)] = (self.navigationItem.rightBarButtonItems ?? []).compactMap { item -> (UIView, CGRect)? in
guard let view = item.customDisplayNode?.view, let snapshotView = view.snapshotView(afterScreenUpdates: false) else {
return nil
@ -9870,7 +9763,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
let isReady = Promise<Bool>()
self.reloadChatLocation(chatLocation: updatedChatLocation, isReady: isReady)
let chatLocationContextHolder = Atomic<ChatLocationContextHolder?>(value: nil)
self.reloadChatLocation(chatLocation: updatedChatLocation, chatLocationContextHolder: chatLocationContextHolder, historyNode: historyNode, isReady: isReady)
self.isUpdatingChatLocationThread = true
self.updateChatLocationThreadDisposable?.dispose()
@ -9928,7 +9822,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
self.currentChatSwitchDirection = nil
})
})*/
}
public var contentContainerNode: ASDisplayNode {

File diff suppressed because it is too large Load Diff

View File

@ -314,6 +314,8 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
private var loadMoreSearchResultsDisposable: Disposable?
let adMessagesContext: AdMessagesHistoryContext?
private var isLoadingValue: Bool = false
private var isLoadingEarlier: Bool = false
private func updateIsLoading(isLoading: Bool, earlier: Bool, animated: Bool) {
@ -667,9 +669,26 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
}
self.controllerInteraction.chatIsRotated = historyNodeRotated
var displayAdPeer: PeerId?
if !isChatPreview {
switch subject {
case .none, .message:
if case let .peer(peerId) = chatLocation {
displayAdPeer = peerId
}
default:
break
}
}
if let displayAdPeer {
self.adMessagesContext = context.engine.messages.adMessages(peerId: displayAdPeer)
} else {
self.adMessagesContext = nil
}
var getMessageTransitionNode: (() -> ChatMessageTransitionNodeImpl?)?
self.historyNode = ChatHistoryListNodeImpl(context: context, updatedPresentationData: controller?.updatedPresentationData ?? (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tag: nil, source: source, subject: subject, controllerInteraction: controllerInteraction, selectedMessages: self.selectedMessagesPromise.get(), rotated: historyNodeRotated, isChatPreview: isChatPreview, messageTransitionNode: {
self.historyNode = ChatHistoryListNodeImpl(context: context, updatedPresentationData: controller?.updatedPresentationData ?? (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, adMessagesContext: self.adMessagesContext, tag: nil, source: source, subject: subject, controllerInteraction: controllerInteraction, selectedMessages: self.selectedMessagesPromise.get(), rotated: historyNodeRotated, isChatPreview: isChatPreview, messageTransitionNode: {
return getMessageTransitionNode?()
})
@ -1371,11 +1390,11 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
}
}
#if DEBUG
/*#if DEBUG
if "".isEmpty {
hasTranslationPanel = true
}
#endif
#endif*/
if hasTranslationPanel {
let translationPanelNode: ChatTranslationPanelNode
@ -4330,7 +4349,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
let effectiveInputText = expandedInputStateAttributedString(effectivePresentationInterfaceState.interfaceState.composeInputState.inputText)
let peerSpecificEmojiPack = (self.controller?.peerView?.cachedData as? CachedChannelData)?.emojiPack
let peerSpecificEmojiPack = (self.controller?.contentData?.state.peerView?.cachedData as? CachedChannelData)?.emojiPack
var inlineStickers: [MediaId: Media] = [:]
var firstLockedPremiumEmoji: TelegramMediaFile?
@ -5041,6 +5060,27 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
return leftIndex < rightIndex
}
func createHistoryNodeForChatLocation(chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>) -> ChatHistoryListNodeImpl {
let historyNode = ChatHistoryListNodeImpl(
context: self.context,
updatedPresentationData: self.controller?.updatedPresentationData ?? (self.context.sharedContext.currentPresentationData.with({ $0 }), self.context.sharedContext.presentationData),
chatLocation: chatLocation,
chatLocationContextHolder: chatLocationContextHolder,
adMessagesContext: self.adMessagesContext,
tag: nil,
source: .default,
subject: nil,
controllerInteraction: self.controllerInteraction,
selectedMessages: self.selectedMessagesPromise.get(),
rotated: self.controllerInteraction.chatIsRotated,
isChatPreview: false,
messageTransitionNode: {
return nil
}
)
return historyNode
}
func updateChatLocation(chatLocation: ChatLocation, transition: ContainedViewLayoutTransition, tabSwitchDirection: ChatControllerAnimateInnerChatSwitchDirection?) {
if chatLocation == self.chatLocation {
return
@ -5053,6 +5093,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
updatedPresentationData: self.controller?.updatedPresentationData ?? (self.context.sharedContext.currentPresentationData.with({ $0 }), self.context.sharedContext.presentationData),
chatLocation: chatLocation,
chatLocationContextHolder: self.chatLocationContextHolder,
adMessagesContext: self.adMessagesContext,
tag: nil,
source: .default,
subject: nil,

View File

@ -850,7 +850,7 @@ extension ChatControllerImpl {
let controller = legacyAttachmentMenu(
context: strongSelf.context,
peer: strongSelf.presentationInterfaceState.renderedPeer?.peer,
threadTitle: strongSelf.threadInfo?.title, chatLocation: strongSelf.chatLocation,
threadTitle: strongSelf.contentData?.state.threadInfo?.title, chatLocation: strongSelf.chatLocation,
editMediaOptions: menuEditMediaOptions,
addingMedia: editMediaOptions == nil,
saveEditedPhotos: settings.storeEditedPhotos,
@ -1203,14 +1203,14 @@ extension ChatControllerImpl {
isScheduledMessages = true
}
var paidMediaAllowed = false
if let cachedData = self.peerView?.cachedData as? CachedChannelData, cachedData.flags.contains(.paidMediaAllowed) {
if let cachedData = self.contentData?.state.peerView?.cachedData as? CachedChannelData, cachedData.flags.contains(.paidMediaAllowed) {
paidMediaAllowed = true
}
let controller = MediaPickerScreenImpl(
context: self.context,
updatedPresentationData: self.updatedPresentationData,
peer: (self.presentationInterfaceState.renderedPeer?.peer).flatMap(EnginePeer.init),
threadTitle: self.threadInfo?.title,
threadTitle: self.contentData?.state.threadInfo?.title,
chatLocation: self.chatLocation,
isScheduledMessages: isScheduledMessages,
bannedSendPhotos: bannedSendPhotos,
@ -1369,7 +1369,7 @@ extension ChatControllerImpl {
slowModeEnabled = true
}
let _ = legacyAssetPicker(context: strongSelf.context, presentationData: strongSelf.presentationData, editingMedia: editingMedia, fileMode: fileMode, peer: peer, threadTitle: strongSelf.threadInfo?.title, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, selectionLimit: selectionLimit).startStandalone(next: { generator in
let _ = legacyAssetPicker(context: strongSelf.context, presentationData: strongSelf.presentationData, editingMedia: editingMedia, fileMode: fileMode, peer: peer, threadTitle: strongSelf.contentData?.state.threadInfo?.title, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, selectionLimit: selectionLimit).startStandalone(next: { generator in
if let strongSelf = self {
let legacyController = LegacyController(presentation: fileMode ? .navigation : .custom, theme: strongSelf.presentationData.theme, initialLayout: strongSelf.validLayout)
legacyController.navigationPresentation = .modal

View File

@ -20,6 +20,6 @@ public extension ChatControllerImpl {
if let foundItemNode, let message = foundItemNode.item?.message {
self.chatDisplayNode.historyNode.setCurrentDeleteAnimationCorrelationIds(Set([message.stableId]))
}
self.chatDisplayNode.historyNode.adMessagesContext?.remove(opaqueId: opaqueId)
self.chatDisplayNode.adMessagesContext?.remove(opaqueId: opaqueId)
}
}

View File

@ -475,7 +475,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
private(set) var tag: HistoryViewInputTag?
private let controllerInteraction: ChatControllerInteraction
private let selectedMessages: Signal<Set<MessageId>?, NoError>
private let messageTransitionNode: () -> ChatMessageTransitionNodeImpl?
var messageTransitionNode: () -> ChatMessageTransitionNodeImpl?
private let mode: ChatHistoryListMode
private var enableUnreadAlignment: Bool = true
@ -707,7 +707,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
var openNextChannelToRead: ((EnginePeer, (id: Int64, data: MessageHistoryThreadData)?, TelegramEngine.NextUnreadChannelLocation) -> Void)?
private var contentInsetAnimator: DisplayLinkAnimator?
let adMessagesContext: AdMessagesHistoryContext?
private let adMessagesContext: AdMessagesHistoryContext?
private var adMessagesDisposable: Disposable?
private var preloadAdPeerName: String?
private let preloadAdPeerDisposable = MetaDisposable()
@ -753,7 +753,7 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
private let initTimestamp: Double
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tag: HistoryViewInputTag?, source: ChatHistoryListSource, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, rotated: Bool = false, isChatPreview: Bool, messageTransitionNode: @escaping () -> ChatMessageTransitionNodeImpl?) {
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>), chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, adMessagesContext: AdMessagesHistoryContext?, tag: HistoryViewInputTag?, source: ChatHistoryListSource, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles, rotated: Bool = false, isChatPreview: Bool, messageTransitionNode: @escaping () -> ChatMessageTransitionNodeImpl?) {
self.initTimestamp = CFAbsoluteTimeGetCurrent()
var tag = tag
@ -788,21 +788,10 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
self.prefetchManager = InChatPrefetchManager(context: context)
var displayAdPeer: PeerId?
if !isChatPreview {
switch subject {
case .none, .message:
if case let .peer(peerId) = chatLocation {
displayAdPeer = peerId
}
default:
break
}
}
self.adMessagesContext = adMessagesContext
var adMessages: Signal<(interPostInterval: Int32?, messages: [Message]), NoError>
if case .bubbles = mode, let peerId = displayAdPeer {
let adMessagesContext = context.engine.messages.adMessages(peerId: peerId)
self.adMessagesContext = adMessagesContext
if case .bubbles = mode, let adMessagesContext {
let peerId = adMessagesContext.peerId
if peerId.namespace == Namespaces.Peer.CloudUser {
adMessages = .single((nil, []))
} else {
@ -891,7 +880,6 @@ public final class ChatHistoryListNodeImpl: ListView, ChatHistoryNode, ChatHisto
}
}
} else {
self.adMessagesContext = nil
adMessages = .single((nil, []))
}

View File

@ -153,8 +153,6 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat
displayActionsPanel = true
} else if peerStatusSettings.contains(.canShareContact) {
displayActionsPanel = true
} else if contactStatus.canReportIrrelevantLocation && peerStatusSettings.contains(.canReportIrrelevantGeoLocation) {
displayActionsPanel = true
} else if peerStatusSettings.contains(.suggestAddMembers) {
displayActionsPanel = true
}
@ -232,6 +230,10 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat
}
func titleTopicsPanelForChatPresentationInterfaceState(_ chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, currentPanel: ChatTitleAccessoryPanelNode?, controllerInteraction: ChatControllerInteraction?, interfaceInteraction: ChatPanelInterfaceInteraction?, force: Bool) -> ChatTopicListTitleAccessoryPanelNode? {
//TODO:release
if "".isEmpty {
return nil
}
if let channel = chatPresentationInterfaceState.renderedPeer?.peer as? TelegramChannel, channel.isForumOrMonoForum, let linkedMonoforumId = channel.linkedMonoforumId, let mainChannel = chatPresentationInterfaceState.renderedPeer?.peers[linkedMonoforumId] as? TelegramChannel, mainChannel.adminRights != nil, chatPresentationInterfaceState.search == nil {
let topicListDisplayMode = chatPresentationInterfaceState.topicListDisplayMode ?? .top
if case .top = topicListDisplayMode, let peerId = chatPresentationInterfaceState.chatLocation.peerId {

View File

@ -23,7 +23,6 @@ private enum ChatReportPeerTitleButton: Equatable {
case shareMyPhoneNumber
case reportSpam
case reportUserSpam
case reportIrrelevantGeoLocation
case unarchive
case addMembers
case restartTopic
@ -48,8 +47,6 @@ private enum ChatReportPeerTitleButton: Equatable {
return strings.Conversation_ReportSpamAndLeave
case .reportUserSpam:
return strings.Conversation_ReportSpam
case .reportIrrelevantGeoLocation:
return strings.Conversation_ReportGroupLocation
case .unarchive:
return strings.Conversation_Unarchive
case .addMembers:
@ -125,8 +122,6 @@ private func peerButtons(_ state: ChatPresentationInterfaceState) -> [ChatReport
if case .peer = state.chatLocation {
if let contactStatus = state.contactStatus, let peerStatusSettings = contactStatus.peerStatusSettings, peerStatusSettings.contains(.suggestAddMembers) {
buttons.append(.addMembers)
} else if let contactStatus = state.contactStatus, contactStatus.canReportIrrelevantLocation, let peerStatusSettings = contactStatus.peerStatusSettings, peerStatusSettings.contains(.canReportIrrelevantGeoLocation) {
buttons.append(.reportIrrelevantGeoLocation)
} else if let contactStatus = state.contactStatus, let peerStatusSettings = contactStatus.peerStatusSettings, peerStatusSettings.contains(.autoArchived) {
buttons.append(.reportUserSpam)
buttons.append(.unarchive)
@ -792,8 +787,6 @@ final class ChatReportPeerTitlePanelNode: ChatTitleAccessoryPanelNode {
self.interfaceInteraction?.presentInviteMembers()
case .addContact:
self.interfaceInteraction?.presentPeerContact()
case .reportIrrelevantGeoLocation:
self.interfaceInteraction?.reportPeerIrrelevantGeoLocation()
case .restartTopic:
self.interfaceInteraction?.restartTopic()
}

View File

@ -233,7 +233,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
self.isGlobalSearch = false
}
self.historyNode = ChatHistoryListNodeImpl(context: context, updatedPresentationData: (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, tag: .tag(tagMask), source: source, subject: .message(id: .id(initialMessageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: !self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch), isChatPreview: false, messageTransitionNode: { return nil })
self.historyNode = ChatHistoryListNodeImpl(context: context, updatedPresentationData: (context.sharedContext.currentPresentationData.with({ $0 }), context.sharedContext.presentationData), chatLocation: chatLocation, chatLocationContextHolder: chatLocationContextHolder, adMessagesContext: nil, tag: .tag(tagMask), source: source, subject: .message(id: .id(initialMessageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: !self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch), isChatPreview: false, messageTransitionNode: { return nil })
self.historyNode.clipsToBounds = true
super.init()
@ -576,7 +576,7 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
}
let chatLocationContextHolder = Atomic<ChatLocationContextHolder?>(value: nil)
let historyNode = ChatHistoryListNodeImpl(context: self.context, updatedPresentationData: (self.context.sharedContext.currentPresentationData.with({ $0 }), self.context.sharedContext.presentationData), chatLocation: self.chatLocation, chatLocationContextHolder: chatLocationContextHolder, tag: .tag(tagMask), source: .default, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: !self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch), isChatPreview: false, messageTransitionNode: { return nil })
let historyNode = ChatHistoryListNodeImpl(context: self.context, updatedPresentationData: (self.context.sharedContext.currentPresentationData.with({ $0 }), self.context.sharedContext.presentationData), chatLocation: self.chatLocation, chatLocationContextHolder: chatLocationContextHolder, adMessagesContext: nil, tag: .tag(tagMask), source: .default, subject: .message(id: .id(messageId), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false), controllerInteraction: self.controllerInteraction, selectedMessages: .single(nil), mode: .list(search: false, reversed: self.currentIsReversed, reverseGroups: !self.currentIsReversed, displayHeaders: .none, hintLinks: false, isGlobalSearch: self.isGlobalSearch), isChatPreview: false, messageTransitionNode: { return nil })
historyNode.clipsToBounds = true
historyNode.preloadPages = true
historyNode.stackFromBottom = true

View File

@ -2228,6 +2228,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
updatedPresentationData: updatedPresentationData,
chatLocation: chatLocation,
chatLocationContextHolder: chatLocationContextHolder,
adMessagesContext: nil,
tag: tag,
source: source,
subject: subject,

View File

@ -286,11 +286,15 @@ genrule(
PATH="$$PATH:$$YASM_DIR" "$$SOURCE_PATH/build-ffmpeg-bazel.sh" "$$VARIANT" "$$BUILD_ARCH" "$$BUILD_DIR" "$$SOURCE_PATH" "$$FFMPEG_VERSION"
""" + "\n" + "\n".join([
"cp \"$$BUILD_DIR/FFmpeg-iOS/include/{header_path}\" \"$(location Public/third_party/ffmpeg/{header_path})\"".format(header_path = header_path) for header_path in ffmpeg_header_paths
]) + "\n" + "\n".join([
"cp \"$$BUILD_DIR/FFmpeg-iOS/include/{header_path}\" \"$(location Public/{header_path})\"".format(header_path = header_path) for header_path in ffmpeg_header_paths
]) + "\n" + "\n".join([
"cp \"$$BUILD_DIR/FFmpeg-iOS/lib/{lib}\" \"$(location {lib})\"".format(lib = lib) for lib in ffmpeg_libs
]),
outs = [
"Public/third_party/ffmpeg/{}".format(header_path) for header_path in ffmpeg_header_paths
] + [
"Public/{}".format(header_path) for header_path in ffmpeg_header_paths
] + ffmpeg_libs,
tools = [
"//third-party/yasm:yasm.tar",
@ -312,10 +316,9 @@ objc_library(
name = "ffmpeg",
module_name = "ffmpeg",
enable_modules = True,
hdrs = ["Public/third_party/ffmpeg/" + x for x in ffmpeg_header_paths],
hdrs = ["Public/third_party/ffmpeg/" + x for x in ffmpeg_header_paths] + ["Public/" + x for x in ffmpeg_header_paths],
includes = [
"Public",
"Public/third_party/ffmpeg",
],
sdk_dylibs = [
"libbz2",

View File

@ -162,6 +162,9 @@ genrule(
cc_library(
name = "openssl_lib",
srcs = [":" + x for x in openssl_libs],
cxxopts = [
"-std=c++17",
],
)
objc_library(

View File

@ -29,6 +29,7 @@ objc_library(
"-DNDEBUG=1",
"-DSQLITE_MAX_MMAP_SIZE=0",
"-Wno-all",
"-Wno-#warnings",
],
sdk_frameworks = [
"Foundation",

View File

@ -135,6 +135,10 @@ objc_library(
copts = [
"-Werror",
],
cxxopts = [
"-Werror",
"-std=c++17",
],
includes = [
"TdBinding/Public",
],

View File

@ -3473,6 +3473,9 @@ cc_library(
"-DWEBRTC_HAVE_DCSCTP",
"-DWEBRTC_HAVE_SCTP",
] + arch_specific_cflags + optimization_flags,
cxxopts = [
"-std=c++17",
],
deps = [
"//third-party/boringssl:crypto",
"//third-party/boringssl:ssl",
@ -3602,6 +3605,9 @@ objc_library(
"-DRTC_DISABLE_TRACE_EVENTS",
"-DRTC_DISABLE_METRICS",
] + arch_specific_cflags + optimization_flags,
cxxopts = [
"-std=c++17",
],
deps = [
"//third-party/boringssl:crypto",
"//third-party/boringssl:ssl",