mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-16 11:20:18 +00:00
Channel discussion groups
This commit is contained in:
parent
42160412d7
commit
553156f25c
22
Images.xcassets/Chat/Info/DiscussDayIcon.imageset/Contents.json
vendored
Normal file
22
Images.xcassets/Chat/Info/DiscussDayIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "DiscussDayPreview@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "DiscussDayPreview@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Images.xcassets/Chat/Info/DiscussDayIcon.imageset/DiscussDayPreview@2x.png
vendored
Normal file
BIN
Images.xcassets/Chat/Info/DiscussDayIcon.imageset/DiscussDayPreview@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
BIN
Images.xcassets/Chat/Info/DiscussDayIcon.imageset/DiscussDayPreview@3x.png
vendored
Normal file
BIN
Images.xcassets/Chat/Info/DiscussDayIcon.imageset/DiscussDayPreview@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
22
Images.xcassets/Chat/Info/DiscussNightAccentIcon.imageset/Contents.json
vendored
Normal file
22
Images.xcassets/Chat/Info/DiscussNightAccentIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "DiscussDarkBluePreview@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "DiscussDarkBluePreview@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Images.xcassets/Chat/Info/DiscussNightAccentIcon.imageset/DiscussDarkBluePreview@2x.png
vendored
Normal file
BIN
Images.xcassets/Chat/Info/DiscussNightAccentIcon.imageset/DiscussDarkBluePreview@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.2 KiB |
BIN
Images.xcassets/Chat/Info/DiscussNightAccentIcon.imageset/DiscussDarkBluePreview@3x.png
vendored
Normal file
BIN
Images.xcassets/Chat/Info/DiscussNightAccentIcon.imageset/DiscussDarkBluePreview@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
22
Images.xcassets/Chat/Info/DiscussNightIcon.imageset/Contents.json
vendored
Normal file
22
Images.xcassets/Chat/Info/DiscussNightIcon.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "DiscussDarkPreview@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "DiscussDarkPreview@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Images.xcassets/Chat/Info/DiscussNightIcon.imageset/DiscussDarkPreview@2x.png
vendored
Normal file
BIN
Images.xcassets/Chat/Info/DiscussNightIcon.imageset/DiscussDarkPreview@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
BIN
Images.xcassets/Chat/Info/DiscussNightIcon.imageset/DiscussDarkPreview@3x.png
vendored
Normal file
BIN
Images.xcassets/Chat/Info/DiscussNightIcon.imageset/DiscussDarkPreview@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@ -561,6 +561,9 @@
|
|||||||
D0DE5805205B202500C356A8 /* ScreenCaptureDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DE5804205B202500C356A8 /* ScreenCaptureDetection.swift */; };
|
D0DE5805205B202500C356A8 /* ScreenCaptureDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DE5804205B202500C356A8 /* ScreenCaptureDetection.swift */; };
|
||||||
D0DE66061F9A51E200EF4AE9 /* GalleryHiddenMediaManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DE66051F9A51E200EF4AE9 /* GalleryHiddenMediaManager.swift */; };
|
D0DE66061F9A51E200EF4AE9 /* GalleryHiddenMediaManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DE66051F9A51E200EF4AE9 /* GalleryHiddenMediaManager.swift */; };
|
||||||
D0DFD5E21FCE2BA50039B3B1 /* CalculatingCacheSizeItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DFD5E11FCE2BA50039B3B1 /* CalculatingCacheSizeItem.swift */; };
|
D0DFD5E21FCE2BA50039B3B1 /* CalculatingCacheSizeItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DFD5E11FCE2BA50039B3B1 /* CalculatingCacheSizeItem.swift */; };
|
||||||
|
D0E1199A2297F9C6008CAE3A /* ChannelDiscussionGroupSetupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E119992297F9C6008CAE3A /* ChannelDiscussionGroupSetupController.swift */; };
|
||||||
|
D0E1199C229808B8008CAE3A /* ChannelDiscussionGroupSetupHeaderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E1199B229808B8008CAE3A /* ChannelDiscussionGroupSetupHeaderItem.swift */; };
|
||||||
|
D0E1199E229809B6008CAE3A /* ChannelDiscussionGroupActionSheetItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E1199D229809B6008CAE3A /* ChannelDiscussionGroupActionSheetItem.swift */; };
|
||||||
D0E266FD1F66706500BFC79F /* ChatBubbleVideoDecoration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E266FC1F66706500BFC79F /* ChatBubbleVideoDecoration.swift */; };
|
D0E266FD1F66706500BFC79F /* ChatBubbleVideoDecoration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E266FC1F66706500BFC79F /* ChatBubbleVideoDecoration.swift */; };
|
||||||
D0E2CE6C222930540084E3DD /* PrefetchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E2CE6B222930540084E3DD /* PrefetchManager.swift */; };
|
D0E2CE6C222930540084E3DD /* PrefetchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E2CE6B222930540084E3DD /* PrefetchManager.swift */; };
|
||||||
D0E412C62069B60600BEE4A2 /* FormControllerHeaderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E412C52069B60600BEE4A2 /* FormControllerHeaderItem.swift */; };
|
D0E412C62069B60600BEE4A2 /* FormControllerHeaderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E412C52069B60600BEE4A2 /* FormControllerHeaderItem.swift */; };
|
||||||
@ -2140,6 +2143,9 @@
|
|||||||
D0DF0CA01D821B28008AEB01 /* HashtagChatInputPanelItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashtagChatInputPanelItem.swift; sourceTree = "<group>"; };
|
D0DF0CA01D821B28008AEB01 /* HashtagChatInputPanelItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HashtagChatInputPanelItem.swift; sourceTree = "<group>"; };
|
||||||
D0DF0CA31D82BCD0008AEB01 /* MentionChatInputContextPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MentionChatInputContextPanelNode.swift; sourceTree = "<group>"; };
|
D0DF0CA31D82BCD0008AEB01 /* MentionChatInputContextPanelNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MentionChatInputContextPanelNode.swift; sourceTree = "<group>"; };
|
||||||
D0DFD5E11FCE2BA50039B3B1 /* CalculatingCacheSizeItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalculatingCacheSizeItem.swift; sourceTree = "<group>"; };
|
D0DFD5E11FCE2BA50039B3B1 /* CalculatingCacheSizeItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalculatingCacheSizeItem.swift; sourceTree = "<group>"; };
|
||||||
|
D0E119992297F9C6008CAE3A /* ChannelDiscussionGroupSetupController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelDiscussionGroupSetupController.swift; sourceTree = "<group>"; };
|
||||||
|
D0E1199B229808B8008CAE3A /* ChannelDiscussionGroupSetupHeaderItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelDiscussionGroupSetupHeaderItem.swift; sourceTree = "<group>"; };
|
||||||
|
D0E1199D229809B6008CAE3A /* ChannelDiscussionGroupActionSheetItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelDiscussionGroupActionSheetItem.swift; sourceTree = "<group>"; };
|
||||||
D0E23DD71E805E2600B9B6D2 /* FeaturedStickerPacksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeaturedStickerPacksController.swift; sourceTree = "<group>"; };
|
D0E23DD71E805E2600B9B6D2 /* FeaturedStickerPacksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeaturedStickerPacksController.swift; sourceTree = "<group>"; };
|
||||||
D0E23DDC1E8081A200B9B6D2 /* ArchivedStickerPacksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArchivedStickerPacksController.swift; sourceTree = "<group>"; };
|
D0E23DDC1E8081A200B9B6D2 /* ArchivedStickerPacksController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArchivedStickerPacksController.swift; sourceTree = "<group>"; };
|
||||||
D0E266FC1F66706500BFC79F /* ChatBubbleVideoDecoration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatBubbleVideoDecoration.swift; sourceTree = "<group>"; };
|
D0E266FC1F66706500BFC79F /* ChatBubbleVideoDecoration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatBubbleVideoDecoration.swift; sourceTree = "<group>"; };
|
||||||
@ -4443,6 +4449,9 @@
|
|||||||
09DD88E821BAF65E000766BC /* ItemListAddressItem.swift */,
|
09DD88E821BAF65E000766BC /* ItemListAddressItem.swift */,
|
||||||
D0F760DA222034910074F7E5 /* ChannelStatsController.swift */,
|
D0F760DA222034910074F7E5 /* ChannelStatsController.swift */,
|
||||||
D0F760DC222034980074F7E5 /* ChannelStatsControllerNode.swift */,
|
D0F760DC222034980074F7E5 /* ChannelStatsControllerNode.swift */,
|
||||||
|
D0E119992297F9C6008CAE3A /* ChannelDiscussionGroupSetupController.swift */,
|
||||||
|
D0E1199B229808B8008CAE3A /* ChannelDiscussionGroupSetupHeaderItem.swift */,
|
||||||
|
D0E1199D229809B6008CAE3A /* ChannelDiscussionGroupActionSheetItem.swift */,
|
||||||
);
|
);
|
||||||
name = "Peer Info";
|
name = "Peer Info";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -5338,9 +5347,11 @@
|
|||||||
D0EC6CB11EB9F58800EBF1C3 /* program.c in Sources */,
|
D0EC6CB11EB9F58800EBF1C3 /* program.c in Sources */,
|
||||||
D0E412DA206A894800BEE4A2 /* SecureIdValueFormFileItem.swift in Sources */,
|
D0E412DA206A894800BEE4A2 /* SecureIdValueFormFileItem.swift in Sources */,
|
||||||
09B4EE6221AD791600847FA6 /* InstantPageStoredState.swift in Sources */,
|
09B4EE6221AD791600847FA6 /* InstantPageStoredState.swift in Sources */,
|
||||||
|
D0E1199E229809B6008CAE3A /* ChannelDiscussionGroupActionSheetItem.swift in Sources */,
|
||||||
D0EC6CB21EB9F58800EBF1C3 /* rngs.c in Sources */,
|
D0EC6CB21EB9F58800EBF1C3 /* rngs.c in Sources */,
|
||||||
09EDAD2A220DA6A40012A50B /* VolumeButtons.swift in Sources */,
|
09EDAD2A220DA6A40012A50B /* VolumeButtons.swift in Sources */,
|
||||||
09D968A9221F804700B1458A /* ChatRecordingVideoActivityContentNode.swift in Sources */,
|
09D968A9221F804700B1458A /* ChatRecordingVideoActivityContentNode.swift in Sources */,
|
||||||
|
D0E1199A2297F9C6008CAE3A /* ChannelDiscussionGroupSetupController.swift in Sources */,
|
||||||
D083491C209361DC008CFD52 /* AvatarGalleryItemFooterContentNode.swift in Sources */,
|
D083491C209361DC008CFD52 /* AvatarGalleryItemFooterContentNode.swift in Sources */,
|
||||||
D0EC6CB31EB9F58800EBF1C3 /* shader.c in Sources */,
|
D0EC6CB31EB9F58800EBF1C3 /* shader.c in Sources */,
|
||||||
D06E4C352134AE3C00088087 /* ThemeAutoNightSettingsController.swift in Sources */,
|
D06E4C352134AE3C00088087 /* ThemeAutoNightSettingsController.swift in Sources */,
|
||||||
@ -6153,6 +6164,7 @@
|
|||||||
D093D7E22062F40100BC3599 /* SecureIdDocumentFormControllerNode.swift in Sources */,
|
D093D7E22062F40100BC3599 /* SecureIdDocumentFormControllerNode.swift in Sources */,
|
||||||
D0B2F7702052B5A800D3BFB9 /* InviteContactsControllerNode.swift in Sources */,
|
D0B2F7702052B5A800D3BFB9 /* InviteContactsControllerNode.swift in Sources */,
|
||||||
D0EC6E211EB9F58900EBF1C3 /* InstantPageController.swift in Sources */,
|
D0EC6E211EB9F58900EBF1C3 /* InstantPageController.swift in Sources */,
|
||||||
|
D0E1199C229808B8008CAE3A /* ChannelDiscussionGroupSetupHeaderItem.swift in Sources */,
|
||||||
091417F221EF4E5D00C8325A /* WallpaperGalleryController.swift in Sources */,
|
091417F221EF4E5D00C8325A /* WallpaperGalleryController.swift in Sources */,
|
||||||
D0EC6E221EB9F58900EBF1C3 /* InstantPageControllerNode.swift in Sources */,
|
D0EC6E221EB9F58900EBF1C3 /* InstantPageControllerNode.swift in Sources */,
|
||||||
D0EC6E231EB9F58900EBF1C3 /* StickerPackPreviewController.swift in Sources */,
|
D0EC6E231EB9F58900EBF1C3 /* StickerPackPreviewController.swift in Sources */,
|
||||||
|
|||||||
100
TelegramUI/ChannelDiscussionGroupActionSheetItem.swift
Normal file
100
TelegramUI/ChannelDiscussionGroupActionSheetItem.swift
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import Foundation
|
||||||
|
import Display
|
||||||
|
import Postbox
|
||||||
|
import TelegramCore
|
||||||
|
|
||||||
|
final class ChannelDiscussionGroupActionSheetItem: ActionSheetItem {
|
||||||
|
let context: AccountContext
|
||||||
|
let channelPeer: Peer
|
||||||
|
let groupPeer: Peer
|
||||||
|
let strings: PresentationStrings
|
||||||
|
|
||||||
|
init(context: AccountContext, channelPeer: Peer, groupPeer: Peer, strings: PresentationStrings) {
|
||||||
|
self.context = context
|
||||||
|
self.channelPeer = channelPeer
|
||||||
|
self.groupPeer = groupPeer
|
||||||
|
self.strings = strings
|
||||||
|
}
|
||||||
|
|
||||||
|
func node(theme: ActionSheetControllerTheme) -> ActionSheetItemNode {
|
||||||
|
return ChannelDiscussionGroupActionSheetItemNode(theme: theme, context: self.context, channelPeer: self.channelPeer, groupPeer: self.groupPeer, strings: self.strings)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateNode(_ node: ActionSheetItemNode) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 26.0)!
|
||||||
|
|
||||||
|
private final class ChannelDiscussionGroupActionSheetItemNode: ActionSheetItemNode {
|
||||||
|
private let theme: ActionSheetControllerTheme
|
||||||
|
|
||||||
|
private let channelAvatarNode: AvatarNode
|
||||||
|
private let channelAvatarOverlay: ASImageNode
|
||||||
|
private let groupAvatarNode: AvatarNode
|
||||||
|
private let textNode: ImmediateTextNode
|
||||||
|
|
||||||
|
init(theme: ActionSheetControllerTheme, context: AccountContext, channelPeer: Peer, groupPeer: Peer, strings: PresentationStrings) {
|
||||||
|
self.theme = theme
|
||||||
|
|
||||||
|
self.channelAvatarNode = AvatarNode(font: avatarFont)
|
||||||
|
self.groupAvatarNode = AvatarNode(font: avatarFont)
|
||||||
|
self.channelAvatarOverlay = ASImageNode()
|
||||||
|
self.channelAvatarOverlay.displayWithoutProcessing = true
|
||||||
|
self.channelAvatarOverlay.displaysAsynchronously = false
|
||||||
|
self.channelAvatarOverlay.image = generateFilledCircleImage(diameter: 66.0, color: theme.itemBackgroundColor.withAlphaComponent(1.0))
|
||||||
|
|
||||||
|
self.textNode = ImmediateTextNode()
|
||||||
|
self.textNode.displaysAsynchronously = false
|
||||||
|
self.textNode.maximumNumberOfLines = 0
|
||||||
|
self.textNode.textAlignment = .center
|
||||||
|
|
||||||
|
super.init(theme: theme)
|
||||||
|
|
||||||
|
self.addSubnode(self.groupAvatarNode)
|
||||||
|
self.addSubnode(self.channelAvatarOverlay)
|
||||||
|
self.addSubnode(self.channelAvatarNode)
|
||||||
|
self.addSubnode(self.textNode)
|
||||||
|
|
||||||
|
self.channelAvatarNode.setPeer(account: context.account, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: channelPeer)
|
||||||
|
self.groupAvatarNode.setPeer(account: context.account, theme: (context.sharedContext.currentPresentationData.with { $0 }).theme, peer: groupPeer)
|
||||||
|
|
||||||
|
let text: (String, [(Int, NSRange)])
|
||||||
|
if let channelPeer = channelPeer as? TelegramChannel, let addressName = channelPeer.addressName, !addressName.isEmpty {
|
||||||
|
text = strings.Channel_DiscussionGroup_PublicChannelLink(groupPeer.displayTitle, channelPeer.displayTitle)
|
||||||
|
} else {
|
||||||
|
text = strings.Channel_DiscussionGroup_PrivateChannelLink(groupPeer.displayTitle, channelPeer.displayTitle)
|
||||||
|
}
|
||||||
|
let attributedText = NSMutableAttributedString(attributedString: NSAttributedString(string: text.0, font: Font.regular(14.0), textColor: theme.primaryTextColor))
|
||||||
|
for (_, range) in text.1 {
|
||||||
|
attributedText.addAttribute(.font, value: Font.semibold(14.0), range: range)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.textNode.attributedText = attributedText
|
||||||
|
}
|
||||||
|
|
||||||
|
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||||
|
let textSize = self.textNode.updateLayout(CGSize(width: constrainedSize.width - 20.0, height: .greatestFiniteMagnitude))
|
||||||
|
|
||||||
|
let topInset: CGFloat = 16.0
|
||||||
|
let avatarSize: CGFloat = 60.0
|
||||||
|
let textSpacing: CGFloat = 12.0
|
||||||
|
let bottomInset: CGFloat = 15.0
|
||||||
|
|
||||||
|
let avatarOverlap: CGFloat = 10.0
|
||||||
|
let avatarsWidth = avatarSize * 2.0 - avatarOverlap
|
||||||
|
|
||||||
|
let channelAvatarFrame = CGRect(origin: CGPoint(x: floor((constrainedSize.width - avatarsWidth) / 2.0), y: topInset), size: CGSize(width: avatarSize, height: avatarSize))
|
||||||
|
self.channelAvatarNode.frame = channelAvatarFrame
|
||||||
|
self.groupAvatarNode.frame = channelAvatarFrame.offsetBy(dx: avatarSize - avatarOverlap, dy: 0.0)
|
||||||
|
self.channelAvatarOverlay.frame = CGRect(origin: CGPoint(x: channelAvatarFrame.minX - 3.0, y: channelAvatarFrame.minY - 3.0), size: CGSize(width: 66.0, height: 66.0))
|
||||||
|
|
||||||
|
self.textNode.frame = CGRect(origin: CGPoint(x: floor((constrainedSize.width - textSize.width) / 2.0), y: topInset + avatarSize + textSpacing), size: textSize)
|
||||||
|
|
||||||
|
return CGSize(width: constrainedSize.width, height: topInset + avatarSize + textSpacing + textSize.height + bottomInset)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layout() {
|
||||||
|
super.layout()
|
||||||
|
}
|
||||||
|
}
|
||||||
458
TelegramUI/ChannelDiscussionGroupSetupController.swift
Normal file
458
TelegramUI/ChannelDiscussionGroupSetupController.swift
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
import Foundation
|
||||||
|
import Display
|
||||||
|
import SwiftSignalKit
|
||||||
|
import Postbox
|
||||||
|
import TelegramCore
|
||||||
|
|
||||||
|
private final class ChannelDiscussionGroupSetupControllerArguments {
|
||||||
|
let account: Account
|
||||||
|
let createGroup: () -> Void
|
||||||
|
let selectGroup: (PeerId) -> Void
|
||||||
|
let unlinkGroup: () -> Void
|
||||||
|
|
||||||
|
init(account: Account, createGroup: @escaping () -> Void, selectGroup: @escaping (PeerId) -> Void, unlinkGroup: @escaping () -> Void) {
|
||||||
|
self.account = account
|
||||||
|
self.createGroup = createGroup
|
||||||
|
self.selectGroup = selectGroup
|
||||||
|
self.unlinkGroup = unlinkGroup
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum ChannelDiscussionGroupSetupControllerSection: Int32 {
|
||||||
|
case header
|
||||||
|
case groups
|
||||||
|
case unlink
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum ChannelDiscussionGroupSetupControllerEntryStableId: Hashable {
|
||||||
|
case id(Int)
|
||||||
|
case peer(PeerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum ChannelDiscussionGroupSetupControllerEntry: ItemListNodeEntry {
|
||||||
|
case header(PresentationTheme, String, String)
|
||||||
|
case create(PresentationTheme, String)
|
||||||
|
case group(Int, PresentationTheme, PresentationStrings, Peer, PresentationPersonNameOrder)
|
||||||
|
case groupsInfo(PresentationTheme, String)
|
||||||
|
case unlink(PresentationTheme, String)
|
||||||
|
|
||||||
|
var section: Int32 {
|
||||||
|
switch self {
|
||||||
|
case .header:
|
||||||
|
return ChannelDiscussionGroupSetupControllerSection.header.rawValue
|
||||||
|
case .create, .group, .groupsInfo:
|
||||||
|
return ChannelDiscussionGroupSetupControllerSection.groups.rawValue
|
||||||
|
case .unlink:
|
||||||
|
return ChannelDiscussionGroupSetupControllerSection.unlink.rawValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var stableId: ChannelDiscussionGroupSetupControllerEntryStableId {
|
||||||
|
switch self {
|
||||||
|
case .header:
|
||||||
|
return .id(0)
|
||||||
|
case .create:
|
||||||
|
return .id(1)
|
||||||
|
case let .group(_, _, _, peer, _):
|
||||||
|
return .peer(peer.id)
|
||||||
|
case .groupsInfo:
|
||||||
|
return .id(2)
|
||||||
|
case .unlink:
|
||||||
|
return .id(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func ==(lhs: ChannelDiscussionGroupSetupControllerEntry, rhs: ChannelDiscussionGroupSetupControllerEntry) -> Bool {
|
||||||
|
switch lhs {
|
||||||
|
case let .header(lhsTheme, lhsTitle, lhsLabel):
|
||||||
|
if case let .header(rhsTheme, rhsTitle, rhsLabel) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsLabel == rhsLabel {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .create(lhsTheme, lhsTitle):
|
||||||
|
if case let .create(rhsTheme, rhsTitle) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .group(lhsIndex, lhsTheme, lhsStrings, lhsPeer, lhsNameOrder):
|
||||||
|
if case let .group(rhsIndex, rhsTheme, rhsStrings, rhsPeer, rhsNameOrder) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings == rhsStrings, lhsPeer.isEqual(rhsPeer), lhsNameOrder == rhsNameOrder {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .groupsInfo(lhsTheme, lhsTitle):
|
||||||
|
if case let .groupsInfo(rhsTheme, rhsTitle) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .unlink(lhsTheme, lhsTitle):
|
||||||
|
if case let .unlink(rhsTheme, rhsTitle) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var sortIndex: Int {
|
||||||
|
switch self {
|
||||||
|
case .header:
|
||||||
|
return 0
|
||||||
|
case .create:
|
||||||
|
return 1
|
||||||
|
case let .group(index, _, _, _, _):
|
||||||
|
return 10 + index
|
||||||
|
case .groupsInfo:
|
||||||
|
return 1000
|
||||||
|
case .unlink:
|
||||||
|
return 1001
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func <(lhs: ChannelDiscussionGroupSetupControllerEntry, rhs: ChannelDiscussionGroupSetupControllerEntry) -> Bool {
|
||||||
|
return lhs.sortIndex < rhs.sortIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
func item(_ arguments: ChannelDiscussionGroupSetupControllerArguments) -> ListViewItem {
|
||||||
|
switch self {
|
||||||
|
case let .header(theme, title, label):
|
||||||
|
return ChannelDiscussionGroupSetupHeaderItem(theme: theme, text: title, label: label, sectionId: self.section)
|
||||||
|
case let .create(theme, text):
|
||||||
|
return ItemListPeerActionItem(theme: theme, icon: PresentationResourcesItemList.plusIconImage(theme), title: text, sectionId: self.section, editing: false, action: {
|
||||||
|
arguments.createGroup()
|
||||||
|
})
|
||||||
|
case let .group(_, theme, strings, peer, nameOrder):
|
||||||
|
let text: String
|
||||||
|
if let peer = peer as? TelegramChannel, let addressName = peer.addressName, !addressName.isEmpty {
|
||||||
|
text = "@\(addressName)"
|
||||||
|
} else {
|
||||||
|
text = strings.Channel_DiscussionGroup_PrivateGroup
|
||||||
|
}
|
||||||
|
return ItemListPeerItem(theme: theme, strings: strings, dateTimeFormat: PresentationDateTimeFormat(timeFormat: .regular, dateFormat: .monthFirst, dateSeparator: ".", decimalSeparator: ".", groupingSeparator: "."), nameDisplayOrder: nameOrder, account: arguments.account, peer: peer, aliasHandling: .standard, nameStyle: .plain, presence: nil, text: .text(text), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: {
|
||||||
|
arguments.selectGroup(peer.id)
|
||||||
|
}, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in })
|
||||||
|
case let .groupsInfo(theme, title):
|
||||||
|
return ItemListTextItem(theme: theme, text: .plain(title), sectionId: self.section)
|
||||||
|
case let .unlink(theme, title):
|
||||||
|
return ItemListActionItem(theme: theme, title: title, kind: .destructive, alignment: .center, sectionId: self.section, style: .blocks, action: {
|
||||||
|
arguments.unlinkGroup()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func channelDiscussionGroupSetupControllerEntries(presentationData: PresentationData, view: PeerView, groups: [Peer]?) -> [ChannelDiscussionGroupSetupControllerEntry] {
|
||||||
|
guard let groups = groups, let peer = view.peers[view.peerId] as? TelegramChannel, let cachedData = view.cachedData as? CachedChannelData else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
var entries: [ChannelDiscussionGroupSetupControllerEntry] = []
|
||||||
|
|
||||||
|
if let linkedDiscussionPeerId = cachedData.linkedDiscussionPeerId {
|
||||||
|
if let group = view.peers[linkedDiscussionPeerId] {
|
||||||
|
if case .group = peer.info {
|
||||||
|
entries.append(.header(presentationData.theme, presentationData.strings.Channel_DiscussionGroup_HeaderSet(group.displayTitle).0, presentationData.strings.Channel_DiscussionGroup_HeaderLabel))
|
||||||
|
} else {
|
||||||
|
entries.append(.header(presentationData.theme, presentationData.strings.Channel_DiscussionGroup_HeaderSet(group.displayTitle).0, presentationData.strings.Channel_DiscussionGroup_HeaderLabel))
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.append(.group(0, presentationData.theme, presentationData.strings, group, presentationData.nameDisplayOrder))
|
||||||
|
entries.append(.groupsInfo(presentationData.theme, presentationData.strings.Channel_DiscussionGroup_Info))
|
||||||
|
let unlinkText: String
|
||||||
|
if case .group = peer.info {
|
||||||
|
unlinkText = presentationData.strings.Channel_DiscussionGroup_UnlinkChannel
|
||||||
|
} else {
|
||||||
|
unlinkText = presentationData.strings.Channel_DiscussionGroup_UnlinkGroup
|
||||||
|
}
|
||||||
|
entries.append(.unlink(presentationData.theme, unlinkText))
|
||||||
|
}
|
||||||
|
} else if case .broadcast = peer.info {
|
||||||
|
entries.append(.header(presentationData.theme, presentationData.strings.Channel_DiscussionGroup_Header, presentationData.strings.Channel_DiscussionGroup_HeaderLabel))
|
||||||
|
|
||||||
|
entries.append(.create(presentationData.theme, presentationData.strings.Channel_DiscussionGroup_Create))
|
||||||
|
var index = 0
|
||||||
|
for group in groups {
|
||||||
|
entries.append(.group(index, presentationData.theme, presentationData.strings, group, presentationData.nameDisplayOrder))
|
||||||
|
index += 1
|
||||||
|
}
|
||||||
|
entries.append(.groupsInfo(presentationData.theme, presentationData.strings.Channel_DiscussionGroup_Info))
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct ChannelDiscussionGroupSetupControllerState: Equatable {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public func channelDiscussionGroupSetupController(context: AccountContext, peerId: PeerId) -> ViewController {
|
||||||
|
let statePromise = ValuePromise(ChannelDiscussionGroupSetupControllerState(), ignoreRepeated: true)
|
||||||
|
let stateValue = Atomic(value: ChannelDiscussionGroupSetupControllerState())
|
||||||
|
let updateState: ((ChannelDiscussionGroupSetupControllerState) -> ChannelDiscussionGroupSetupControllerState) -> Void = { f in
|
||||||
|
statePromise.set(stateValue.modify { f($0) })
|
||||||
|
}
|
||||||
|
|
||||||
|
let groupPeers = Promise<[Peer]?>()
|
||||||
|
groupPeers.set(.single(nil)
|
||||||
|
|> then(
|
||||||
|
availableGroupsForChannelDiscussion(network: context.account.network)
|
||||||
|
|> map(Optional.init)
|
||||||
|
|> `catch` { _ -> Signal<[Peer]?, NoError> in
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
))
|
||||||
|
|
||||||
|
let peerView = context.account.viewTracker.peerView(peerId)
|
||||||
|
|
||||||
|
var dismissImpl: (() -> Void)?
|
||||||
|
var pushControllerImpl: ((ViewController) -> Void)?
|
||||||
|
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
||||||
|
var navigateToGroupImpl: ((PeerId) -> Void)?
|
||||||
|
|
||||||
|
let actionsDisposable = DisposableSet()
|
||||||
|
|
||||||
|
let applyGroupDisposable = MetaDisposable()
|
||||||
|
actionsDisposable.add(applyGroupDisposable)
|
||||||
|
|
||||||
|
let arguments = ChannelDiscussionGroupSetupControllerArguments(account: context.account, createGroup: {
|
||||||
|
let _ = (context.account.postbox.transaction { transaction -> Peer? in
|
||||||
|
transaction.getPeer(peerId)
|
||||||
|
}
|
||||||
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
guard let peer = peer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pushControllerImpl?(createGroupController(context: context, peerIds: [], initialTitle: peer.displayTitle + " Chat", supergroup: true, completion: { groupId in
|
||||||
|
var applySignal = updateGroupDiscussionForChannel(network: context.account.network, postbox: context.account.postbox, channelId: peerId, groupId: groupId)
|
||||||
|
var cancelImpl: (() -> Void)?
|
||||||
|
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: {
|
||||||
|
cancelImpl?()
|
||||||
|
}))
|
||||||
|
presentControllerImpl?(controller, nil)
|
||||||
|
return ActionDisposable { [weak controller] in
|
||||||
|
Queue.mainQueue().async() {
|
||||||
|
controller?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> runOn(Queue.mainQueue())
|
||||||
|
|> delay(0.15, queue: Queue.mainQueue())
|
||||||
|
let progressDisposable = progressSignal.start()
|
||||||
|
|
||||||
|
applySignal = applySignal
|
||||||
|
|> afterDisposed {
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
progressDisposable.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cancelImpl = {
|
||||||
|
applyGroupDisposable.set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
applyGroupDisposable.set((applySignal
|
||||||
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
|
}, completed: {
|
||||||
|
/*let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .success)
|
||||||
|
presentControllerImpl?(controller, nil)*/
|
||||||
|
}))
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}, selectGroup: { groupId in
|
||||||
|
let _ = (context.account.postbox.transaction { transaction -> (CachedChannelData?, Peer?, Peer?) in
|
||||||
|
return (transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData, transaction.getPeer(peerId), transaction.getPeer(groupId))
|
||||||
|
}
|
||||||
|
|> deliverOnMainQueue).start(next: { cachedData, channelPeer, groupPeer in
|
||||||
|
guard let cachedData = cachedData, let channelPeer = channelPeer, let groupPeer = groupPeer else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if groupId == cachedData.linkedDiscussionPeerId {
|
||||||
|
navigateToGroupImpl?(groupId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
|
||||||
|
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
|
||||||
|
ChannelDiscussionGroupActionSheetItem(context: context, channelPeer: channelPeer, groupPeer: groupPeer, strings: presentationData.strings),
|
||||||
|
ActionSheetButtonItem(title: presentationData.strings.Channel_DiscussionGroup_LinkGroup, color: .accent, action: { [weak actionSheet] in
|
||||||
|
actionSheet?.dismissAnimated()
|
||||||
|
|
||||||
|
var applySignal = updateGroupDiscussionForChannel(network: context.account.network, postbox: context.account.postbox, channelId: peerId, groupId: groupId)
|
||||||
|
var cancelImpl: (() -> Void)?
|
||||||
|
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: {
|
||||||
|
cancelImpl?()
|
||||||
|
}))
|
||||||
|
presentControllerImpl?(controller, nil)
|
||||||
|
return ActionDisposable { [weak controller] in
|
||||||
|
Queue.mainQueue().async() {
|
||||||
|
controller?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> runOn(Queue.mainQueue())
|
||||||
|
|> delay(0.15, queue: Queue.mainQueue())
|
||||||
|
let progressDisposable = progressSignal.start()
|
||||||
|
|
||||||
|
applySignal = applySignal
|
||||||
|
|> afterDisposed {
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
progressDisposable.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cancelImpl = {
|
||||||
|
applyGroupDisposable.set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
applyGroupDisposable.set((applySignal
|
||||||
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
|
}, completed: {
|
||||||
|
/*let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .success)
|
||||||
|
presentControllerImpl?(controller, nil)*/
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
]), ActionSheetItemGroup(items: [
|
||||||
|
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
|
||||||
|
actionSheet?.dismissAnimated()
|
||||||
|
})
|
||||||
|
])])
|
||||||
|
presentControllerImpl?(actionSheet, nil)
|
||||||
|
})
|
||||||
|
}, unlinkGroup: {
|
||||||
|
let _ = (context.account.postbox.transaction { transaction -> (CachedChannelData?, Peer?) in
|
||||||
|
return (transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData, transaction.getPeer(peerId))
|
||||||
|
}
|
||||||
|
|> deliverOnMainQueue).start(next: { cachedData, peer in
|
||||||
|
guard let cachedData = cachedData, let peer = peer as? TelegramChannel else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let applyPeerId: PeerId
|
||||||
|
if case .broadcast = peer.info {
|
||||||
|
applyPeerId = peerId
|
||||||
|
} else if let linkedDiscussionPeerId = cachedData.linkedDiscussionPeerId {
|
||||||
|
applyPeerId = linkedDiscussionPeerId
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var applySignal = updateGroupDiscussionForChannel(network: context.account.network, postbox: context.account.postbox, channelId: applyPeerId, groupId: nil)
|
||||||
|
var cancelImpl: (() -> Void)?
|
||||||
|
let progressSignal = Signal<Never, NoError> { subscriber in
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: {
|
||||||
|
cancelImpl?()
|
||||||
|
}))
|
||||||
|
presentControllerImpl?(controller, nil)
|
||||||
|
return ActionDisposable { [weak controller] in
|
||||||
|
Queue.mainQueue().async() {
|
||||||
|
controller?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> runOn(Queue.mainQueue())
|
||||||
|
|> delay(0.15, queue: Queue.mainQueue())
|
||||||
|
let progressDisposable = progressSignal.start()
|
||||||
|
|
||||||
|
applySignal = applySignal
|
||||||
|
|> afterDisposed {
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
progressDisposable.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cancelImpl = {
|
||||||
|
applyGroupDisposable.set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
applyGroupDisposable.set((applySignal
|
||||||
|
|> deliverOnMainQueue).start(error: { _ in
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
|
}, completed: {
|
||||||
|
if let channel = peer as? TelegramChannel, case .group = channel.info {
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .success)
|
||||||
|
presentControllerImpl?(controller, nil)
|
||||||
|
|
||||||
|
dismissImpl?()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
var wasEmpty: Bool?
|
||||||
|
|
||||||
|
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), peerView, groupPeers.get())
|
||||||
|
|> deliverOnMainQueue
|
||||||
|
|> map { presentationData, state, view, groups -> (ItemListControllerState, (ItemListNodeState<ChannelDiscussionGroupSetupControllerEntry>, ChannelDiscussionGroupSetupControllerEntry.ItemGenerationArguments)) in
|
||||||
|
let title: String
|
||||||
|
if let peer = view.peers[view.peerId] as? TelegramChannel, case .broadcast = peer.info {
|
||||||
|
title = presentationData.strings.Channel_DiscussionGroup
|
||||||
|
} else {
|
||||||
|
title = presentationData.strings.Group_LinkedChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
var crossfade = false
|
||||||
|
var isEmptyState = false
|
||||||
|
if let cachedData = view.cachedData as? CachedChannelData {
|
||||||
|
let isEmpty = cachedData.linkedDiscussionPeerId == nil
|
||||||
|
if cachedData.linkedDiscussionPeerId == nil, let peer = view.peers[view.peerId] as? TelegramChannel, case .broadcast = peer.info {
|
||||||
|
if groups == nil {
|
||||||
|
isEmptyState = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let wasEmpty = wasEmpty, wasEmpty != isEmpty {
|
||||||
|
crossfade = true
|
||||||
|
}
|
||||||
|
wasEmpty = isEmpty
|
||||||
|
} else {
|
||||||
|
isEmptyState = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var emptyStateItem: ItemListControllerEmptyStateItem?
|
||||||
|
if isEmptyState {
|
||||||
|
emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
||||||
|
let listState = ItemListNodeState(entries: channelDiscussionGroupSetupControllerEntries(presentationData: presentationData, view: view, groups: groups), style: .blocks, emptyStateItem: emptyStateItem, crossfadeState: crossfade, animateChanges: false)
|
||||||
|
|
||||||
|
return (controllerState, (listState, arguments))
|
||||||
|
}
|
||||||
|
|> afterDisposed {
|
||||||
|
actionsDisposable.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
let controller = ItemListController(context: context, state: signal)
|
||||||
|
dismissImpl = { [weak controller] in
|
||||||
|
if let controller = controller {
|
||||||
|
(controller.navigationController as? NavigationController)?.filterController(controller, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pushControllerImpl = { [weak controller] c in
|
||||||
|
(controller?.navigationController as? NavigationController)?.pushViewController(c)
|
||||||
|
}
|
||||||
|
presentControllerImpl = { [weak controller] c, a in
|
||||||
|
controller?.present(c, in: .window(.root), with: a)
|
||||||
|
}
|
||||||
|
navigateToGroupImpl = { [weak controller] groupId in
|
||||||
|
guard let navigationController = controller?.navigationController as? NavigationController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navigateToChatController(navigationController: navigationController, context: context, chatLocation: .peer(groupId), keepStack: .always)
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
160
TelegramUI/ChannelDiscussionGroupSetupHeaderItem.swift
Normal file
160
TelegramUI/ChannelDiscussionGroupSetupHeaderItem.swift
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import Foundation
|
||||||
|
import Display
|
||||||
|
import AsyncDisplayKit
|
||||||
|
import SwiftSignalKit
|
||||||
|
|
||||||
|
class ChannelDiscussionGroupSetupHeaderItem: ListViewItem, ItemListItem {
|
||||||
|
let theme: PresentationTheme
|
||||||
|
let text: String
|
||||||
|
let label: String
|
||||||
|
let sectionId: ItemListSectionId
|
||||||
|
|
||||||
|
let isAlwaysPlain: Bool = true
|
||||||
|
|
||||||
|
init(theme: PresentationTheme, text: String, label: String, sectionId: ItemListSectionId) {
|
||||||
|
self.theme = theme
|
||||||
|
self.text = text
|
||||||
|
self.label = label
|
||||||
|
self.sectionId = sectionId
|
||||||
|
}
|
||||||
|
|
||||||
|
func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal<Void, NoError>?, (ListViewItemApply) -> Void)) -> Void) {
|
||||||
|
async {
|
||||||
|
let node = ChannelDiscussionGroupSetupHeaderItemNode()
|
||||||
|
let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||||
|
|
||||||
|
node.contentSize = layout.contentSize
|
||||||
|
node.insets = layout.insets
|
||||||
|
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
completion(node, {
|
||||||
|
return (nil, { _ in apply() })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) {
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
guard let nodeValue = node() as? ChannelDiscussionGroupSetupHeaderItemNode else {
|
||||||
|
assertionFailure()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let makeLayout = nodeValue.asyncLayout()
|
||||||
|
|
||||||
|
async {
|
||||||
|
let (layout, apply) = makeLayout(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem))
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
completion(layout, { _ in
|
||||||
|
apply()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let iconFont = Font.medium(12.0)
|
||||||
|
private let titleFont = Font.regular(14.0)
|
||||||
|
|
||||||
|
class ChannelDiscussionGroupSetupHeaderItemNode: ListViewItemNode {
|
||||||
|
private let imageNode: ASImageNode
|
||||||
|
private let titleNode: TextNode
|
||||||
|
private let labelNode: TextNode
|
||||||
|
|
||||||
|
private var item: ChannelDiscussionGroupSetupHeaderItem?
|
||||||
|
|
||||||
|
init() {
|
||||||
|
self.imageNode = ASImageNode()
|
||||||
|
|
||||||
|
self.titleNode = TextNode()
|
||||||
|
self.titleNode.isUserInteractionEnabled = false
|
||||||
|
self.titleNode.contentMode = .left
|
||||||
|
self.titleNode.contentsScale = UIScreen.main.scale
|
||||||
|
|
||||||
|
self.labelNode = TextNode()
|
||||||
|
self.labelNode.isUserInteractionEnabled = false
|
||||||
|
self.labelNode.contentMode = .left
|
||||||
|
self.labelNode.contentsScale = UIScreen.main.scale
|
||||||
|
|
||||||
|
super.init(layerBacked: false, dynamicBounce: false)
|
||||||
|
|
||||||
|
self.addSubnode(self.imageNode)
|
||||||
|
self.addSubnode(self.titleNode)
|
||||||
|
self.addSubnode(self.labelNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func asyncLayout() -> (_ item: ChannelDiscussionGroupSetupHeaderItem, _ params: ListViewItemLayoutParams, _ neighbors: ItemListNeighbors) -> (ListViewItemNodeLayout, () -> Void) {
|
||||||
|
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
|
||||||
|
let makeLabelLayout = TextNode.asyncLayout(self.labelNode)
|
||||||
|
|
||||||
|
let currentItem = self.item
|
||||||
|
let currentIconImage = self.imageNode.image
|
||||||
|
|
||||||
|
return { item, params, neighbors in
|
||||||
|
let topInset: CGFloat = 30.0
|
||||||
|
let bottomInset: CGFloat = 0.0
|
||||||
|
let iconSpacing: CGFloat = 21.0
|
||||||
|
|
||||||
|
let iconImage: UIImage?
|
||||||
|
if item.theme !== currentItem?.theme {
|
||||||
|
switch item.theme.name {
|
||||||
|
case let .builtin(name):
|
||||||
|
switch name {
|
||||||
|
case .day, .dayClassic:
|
||||||
|
iconImage = UIImage(bundleImageName: "Chat/Info/DiscussDayIcon")?.precomposed()
|
||||||
|
case .nightAccent:
|
||||||
|
iconImage = UIImage(bundleImageName: "Chat/Info/DiscussNightAccentIcon")?.precomposed()
|
||||||
|
case .nightGrayscale:
|
||||||
|
iconImage = UIImage(bundleImageName: "Chat/Info/DiscussNightIcon")?.precomposed()
|
||||||
|
}
|
||||||
|
case .custom:
|
||||||
|
iconImage = UIImage(bundleImageName: "Chat/Info/DiscussDayIcon")?.precomposed()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iconImage = currentIconImage
|
||||||
|
}
|
||||||
|
|
||||||
|
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.text, font: titleFont, textColor: item.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: params.width - params.leftInset - params.rightInset - 20.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
|
let (labelLayout, labelApply) = makeLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.label, font: iconFont, textColor: item.theme.list.itemAccentColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.leftInset - params.rightInset - 20.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
|
let contentSize: CGSize
|
||||||
|
var insets = UIEdgeInsets()
|
||||||
|
insets.top = topInset
|
||||||
|
insets.bottom = bottomInset
|
||||||
|
|
||||||
|
contentSize = CGSize(width: params.width, height: (iconImage?.size.height ?? 0.0) + iconSpacing + titleLayout.size.height)
|
||||||
|
|
||||||
|
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||||
|
|
||||||
|
return (layout, { [weak self] in
|
||||||
|
if let strongSelf = self {
|
||||||
|
strongSelf.item = item
|
||||||
|
|
||||||
|
let _ = titleApply()
|
||||||
|
let _ = labelApply()
|
||||||
|
|
||||||
|
strongSelf.imageNode.image = iconImage
|
||||||
|
|
||||||
|
let iconSize = iconImage?.size ?? CGSize()
|
||||||
|
let iconFrame = CGRect(origin: CGPoint(x: floor((params.width - iconSize.width) / 2.0), y: 0.0), size: iconSize)
|
||||||
|
strongSelf.imageNode.frame = iconFrame
|
||||||
|
|
||||||
|
strongSelf.labelNode.frame = CGRect(origin: CGPoint(x: floor((params.width - labelLayout.size.width) / 2.0), y: iconFrame.minY + 63.0), size: labelLayout.size)
|
||||||
|
|
||||||
|
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: floor((params.width - titleLayout.size.width) / 2.0), y: iconFrame.maxY + iconSpacing), size: titleLayout.size)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func animateInsertion(_ currentTimestamp: Double, duration: Double, short: Bool) {
|
||||||
|
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.4)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func animateRemoved(_ currentTimestamp: Double, duration: Double) {
|
||||||
|
self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,6 +13,7 @@ private final class ChannelInfoControllerArguments {
|
|||||||
let updateEditingName: (ItemListAvatarAndNameInfoItemName) -> Void
|
let updateEditingName: (ItemListAvatarAndNameInfoItemName) -> Void
|
||||||
let updateEditingDescriptionText: (String) -> Void
|
let updateEditingDescriptionText: (String) -> Void
|
||||||
let openChannelTypeSetup: () -> Void
|
let openChannelTypeSetup: () -> Void
|
||||||
|
let openDiscussionGroupSetup: () -> Void
|
||||||
let changeNotificationMuteSettings: () -> Void
|
let changeNotificationMuteSettings: () -> Void
|
||||||
let openSharedMedia: () -> Void
|
let openSharedMedia: () -> Void
|
||||||
let openStats: () -> Void
|
let openStats: () -> Void
|
||||||
@ -26,7 +27,7 @@ private final class ChannelInfoControllerArguments {
|
|||||||
let displayContextMenu: (ChannelInfoEntryTag, String) -> Void
|
let displayContextMenu: (ChannelInfoEntryTag, String) -> Void
|
||||||
let aboutLinkAction: (TextLinkItemActionType, TextLinkItem) -> Void
|
let aboutLinkAction: (TextLinkItemActionType, TextLinkItem) -> Void
|
||||||
let toggleSignatures:(Bool) -> Void
|
let toggleSignatures:(Bool) -> Void
|
||||||
init(account: Account, avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext, tapAvatarAction: @escaping () -> Void, changeProfilePhoto: @escaping () -> Void, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updateEditingDescriptionText: @escaping (String) -> Void, openChannelTypeSetup: @escaping () -> Void, changeNotificationMuteSettings: @escaping () -> Void, openSharedMedia: @escaping () -> Void, openStats: @escaping () -> Void, openAdmins: @escaping () -> Void, openMembers: @escaping () -> Void, openBanned: @escaping () -> Void, reportChannel: @escaping () -> Void, leaveChannel: @escaping () -> Void, deleteChannel: @escaping () -> Void, displayAddressNameContextMenu: @escaping (String) -> Void, displayContextMenu: @escaping (ChannelInfoEntryTag, String) -> Void, aboutLinkAction: @escaping (TextLinkItemActionType, TextLinkItem) -> Void, toggleSignatures: @escaping(Bool)->Void) {
|
init(account: Account, avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext, tapAvatarAction: @escaping () -> Void, changeProfilePhoto: @escaping () -> Void, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updateEditingDescriptionText: @escaping (String) -> Void, openChannelTypeSetup: @escaping () -> Void, openDiscussionGroupSetup: @escaping () -> Void, changeNotificationMuteSettings: @escaping () -> Void, openSharedMedia: @escaping () -> Void, openStats: @escaping () -> Void, openAdmins: @escaping () -> Void, openMembers: @escaping () -> Void, openBanned: @escaping () -> Void, reportChannel: @escaping () -> Void, leaveChannel: @escaping () -> Void, deleteChannel: @escaping () -> Void, displayAddressNameContextMenu: @escaping (String) -> Void, displayContextMenu: @escaping (ChannelInfoEntryTag, String) -> Void, aboutLinkAction: @escaping (TextLinkItemActionType, TextLinkItem) -> Void, toggleSignatures: @escaping(Bool)->Void) {
|
||||||
self.account = account
|
self.account = account
|
||||||
self.avatarAndNameInfoContext = avatarAndNameInfoContext
|
self.avatarAndNameInfoContext = avatarAndNameInfoContext
|
||||||
self.tapAvatarAction = tapAvatarAction
|
self.tapAvatarAction = tapAvatarAction
|
||||||
@ -34,6 +35,7 @@ private final class ChannelInfoControllerArguments {
|
|||||||
self.updateEditingName = updateEditingName
|
self.updateEditingName = updateEditingName
|
||||||
self.updateEditingDescriptionText = updateEditingDescriptionText
|
self.updateEditingDescriptionText = updateEditingDescriptionText
|
||||||
self.openChannelTypeSetup = openChannelTypeSetup
|
self.openChannelTypeSetup = openChannelTypeSetup
|
||||||
|
self.openDiscussionGroupSetup = openDiscussionGroupSetup
|
||||||
self.changeNotificationMuteSettings = changeNotificationMuteSettings
|
self.changeNotificationMuteSettings = changeNotificationMuteSettings
|
||||||
self.openSharedMedia = openSharedMedia
|
self.openSharedMedia = openSharedMedia
|
||||||
self.openStats = openStats
|
self.openStats = openStats
|
||||||
@ -54,6 +56,7 @@ private enum ChannelInfoSection: ItemListSectionId {
|
|||||||
case info
|
case info
|
||||||
case discriptionAndType
|
case discriptionAndType
|
||||||
case sharedMediaAndNotifications
|
case sharedMediaAndNotifications
|
||||||
|
case sign
|
||||||
case members
|
case members
|
||||||
case reportOrLeave
|
case reportOrLeave
|
||||||
}
|
}
|
||||||
@ -69,6 +72,8 @@ private enum ChannelInfoEntry: ItemListNodeEntry {
|
|||||||
case addressName(theme: PresentationTheme, text: String, value: String)
|
case addressName(theme: PresentationTheme, text: String, value: String)
|
||||||
case channelPhotoSetup(theme: PresentationTheme, text: String)
|
case channelPhotoSetup(theme: PresentationTheme, text: String)
|
||||||
case channelTypeSetup(theme: PresentationTheme, text: String, value: String)
|
case channelTypeSetup(theme: PresentationTheme, text: String, value: String)
|
||||||
|
case discussionGroupSetup(theme: PresentationTheme, text: String, value: String)
|
||||||
|
case discussionGroupSetupInfo(theme: PresentationTheme, text: String)
|
||||||
case channelDescriptionSetup(theme: PresentationTheme, placeholder: String, value: String)
|
case channelDescriptionSetup(theme: PresentationTheme, placeholder: String, value: String)
|
||||||
case admins(theme: PresentationTheme, text: String, value: String)
|
case admins(theme: PresentationTheme, text: String, value: String)
|
||||||
case members(theme: PresentationTheme, text: String, value: String)
|
case members(theme: PresentationTheme, text: String, value: String)
|
||||||
@ -86,8 +91,10 @@ private enum ChannelInfoEntry: ItemListNodeEntry {
|
|||||||
switch self {
|
switch self {
|
||||||
case .info, .about, .addressName, .channelPhotoSetup, .channelDescriptionSetup:
|
case .info, .about, .addressName, .channelPhotoSetup, .channelDescriptionSetup:
|
||||||
return ChannelInfoSection.info.rawValue
|
return ChannelInfoSection.info.rawValue
|
||||||
case .channelTypeSetup, .signMessages, .signInfo:
|
case .channelTypeSetup, .discussionGroupSetup, .discussionGroupSetupInfo:
|
||||||
return ChannelInfoSection.discriptionAndType.rawValue
|
return ChannelInfoSection.discriptionAndType.rawValue
|
||||||
|
case .signMessages, .signInfo:
|
||||||
|
return ChannelInfoSection.sign.rawValue
|
||||||
case .admins, .members, .banned:
|
case .admins, .members, .banned:
|
||||||
return ChannelInfoSection.members.rawValue
|
return ChannelInfoSection.members.rawValue
|
||||||
case .sharedMedia, .notifications, .stats:
|
case .sharedMedia, .notifications, .stats:
|
||||||
@ -111,18 +118,22 @@ private enum ChannelInfoEntry: ItemListNodeEntry {
|
|||||||
return 4
|
return 4
|
||||||
case .channelTypeSetup:
|
case .channelTypeSetup:
|
||||||
return 5
|
return 5
|
||||||
case .signMessages:
|
case .discussionGroupSetup:
|
||||||
return 6
|
return 6
|
||||||
case .signInfo:
|
case .discussionGroupSetupInfo:
|
||||||
return 7
|
return 7
|
||||||
case .admins:
|
case .signMessages:
|
||||||
return 8
|
return 8
|
||||||
case .members:
|
case .signInfo:
|
||||||
return 9
|
return 9
|
||||||
case .banned:
|
case .admins:
|
||||||
return 10
|
return 10
|
||||||
case .notifications:
|
case .members:
|
||||||
|
return 11
|
||||||
|
case .banned:
|
||||||
return 12
|
return 12
|
||||||
|
case .notifications:
|
||||||
|
return 13
|
||||||
case .sharedMedia:
|
case .sharedMedia:
|
||||||
return 14
|
return 14
|
||||||
case .stats:
|
case .stats:
|
||||||
@ -198,6 +209,18 @@ private enum ChannelInfoEntry: ItemListNodeEntry {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
case let .discussionGroupSetup(lhsTheme, lhsText, lhsValue):
|
||||||
|
if case let .discussionGroupSetup(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
case let .discussionGroupSetupInfo(lhsTheme, lhsText):
|
||||||
|
if case let .discussionGroupSetupInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
case let .channelDescriptionSetup(lhsTheme, lhsPlaceholder, lhsValue):
|
case let .channelDescriptionSetup(lhsTheme, lhsPlaceholder, lhsValue):
|
||||||
if case let .channelDescriptionSetup(rhsTheme, rhsPlaceholder, rhsValue) = rhs, lhsTheme === rhsTheme, lhsPlaceholder == rhsPlaceholder, lhsValue == rhsValue {
|
if case let .channelDescriptionSetup(rhsTheme, rhsPlaceholder, rhsValue) = rhs, lhsTheme === rhsTheme, lhsPlaceholder == rhsPlaceholder, lhsValue == rhsValue {
|
||||||
return true
|
return true
|
||||||
@ -305,6 +328,12 @@ private enum ChannelInfoEntry: ItemListNodeEntry {
|
|||||||
return ItemListDisclosureItem(theme: theme, title: text, label: value, sectionId: self.section, style: .plain, action: {
|
return ItemListDisclosureItem(theme: theme, title: text, label: value, sectionId: self.section, style: .plain, action: {
|
||||||
arguments.openChannelTypeSetup()
|
arguments.openChannelTypeSetup()
|
||||||
})
|
})
|
||||||
|
case let .discussionGroupSetup(theme, text, value):
|
||||||
|
return ItemListDisclosureItem(theme: theme, title: text, label: value, sectionId: self.section, style: .plain, action: {
|
||||||
|
arguments.openDiscussionGroupSetup()
|
||||||
|
})
|
||||||
|
case let .discussionGroupSetupInfo(theme, text):
|
||||||
|
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
|
||||||
case let .channelDescriptionSetup(theme, placeholder, value):
|
case let .channelDescriptionSetup(theme, placeholder, value):
|
||||||
return ItemListMultilineInputItem(theme: theme, text: value, placeholder: placeholder, maxLength: ItemListMultilineInputItemTextLimit(value: 255, display: true), sectionId: self.section, style: .plain, textUpdated: { updatedText in
|
return ItemListMultilineInputItem(theme: theme, text: value, placeholder: placeholder, maxLength: ItemListMultilineInputItemTextLimit(value: 255, display: true), sectionId: self.section, style: .plain, textUpdated: { updatedText in
|
||||||
arguments.updateEditingDescriptionText(updatedText)
|
arguments.updateEditingDescriptionText(updatedText)
|
||||||
@ -442,6 +471,23 @@ private func channelInfoEntries(account: Account, presentationData: Presentation
|
|||||||
linkText = presentationData.strings.Channel_Setup_TypePrivate
|
linkText = presentationData.strings.Channel_Setup_TypePrivate
|
||||||
}
|
}
|
||||||
entries.append(.channelTypeSetup(theme: presentationData.theme, text: presentationData.strings.Channel_TypeSetup_Title, value: linkText))
|
entries.append(.channelTypeSetup(theme: presentationData.theme, text: presentationData.strings.Channel_TypeSetup_Title, value: linkText))
|
||||||
|
let discussionGroupTitle: String
|
||||||
|
if let cachedData = view.cachedData as? CachedChannelData {
|
||||||
|
if let linkedDiscussionPeerId = cachedData.linkedDiscussionPeerId, let peer = view.peers[linkedDiscussionPeerId] {
|
||||||
|
if let addressName = peer.addressName, !addressName.isEmpty {
|
||||||
|
discussionGroupTitle = "@\(addressName)"
|
||||||
|
} else {
|
||||||
|
discussionGroupTitle = peer.displayTitle
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
discussionGroupTitle = presentationData.strings.Channel_DiscussionGroupAdd
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
discussionGroupTitle = "..."
|
||||||
|
}
|
||||||
|
entries.append(.discussionGroupSetup(theme: presentationData.theme, text: presentationData.strings.Channel_DiscussionGroup, value: discussionGroupTitle))
|
||||||
|
entries.append(.discussionGroupSetupInfo(theme: presentationData.theme, text: presentationData.strings.Channel_DiscussionGroupInfo))
|
||||||
|
|
||||||
let messagesShouldHaveSignatures:Bool
|
let messagesShouldHaveSignatures:Bool
|
||||||
switch peer.info {
|
switch peer.info {
|
||||||
case let .broadcast(info):
|
case let .broadcast(info):
|
||||||
@ -715,6 +761,8 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi
|
|||||||
}
|
}
|
||||||
}, openChannelTypeSetup: {
|
}, openChannelTypeSetup: {
|
||||||
presentControllerImpl?(channelVisibilityController(context: context, peerId: peerId, mode: .generic, upgradedToSupergroup: { _, f in f() }), ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet))
|
presentControllerImpl?(channelVisibilityController(context: context, peerId: peerId, mode: .generic, upgradedToSupergroup: { _, f in f() }), ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet))
|
||||||
|
}, openDiscussionGroupSetup: {
|
||||||
|
pushControllerImpl?(channelDiscussionGroupSetupController(context: context, peerId: peerId))
|
||||||
}, changeNotificationMuteSettings: {
|
}, changeNotificationMuteSettings: {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let _ = (context.account.postbox.transaction { transaction -> (TelegramPeerNotificationSettings, GlobalNotificationSettings) in
|
let _ = (context.account.postbox.transaction { transaction -> (TelegramPeerNotificationSettings, GlobalNotificationSettings) in
|
||||||
@ -854,7 +902,7 @@ public func channelInfoController(context: AccountContext, peerId: PeerId) -> Vi
|
|||||||
let hapticFeedback = HapticFeedback()
|
let hapticFeedback = HapticFeedback()
|
||||||
|
|
||||||
let globalNotificationsKey: PostboxViewKey = .preferences(keys: Set<ValueBoxKey>([PreferencesKeys.globalNotifications]))
|
let globalNotificationsKey: PostboxViewKey = .preferences(keys: Set<ValueBoxKey>([PreferencesKeys.globalNotifications]))
|
||||||
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), context.account.viewTracker.peerView(peerId), context.account.postbox.combinedView(keys: [globalNotificationsKey]))
|
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), context.account.viewTracker.peerView(peerId, updateData: true), context.account.postbox.combinedView(keys: [globalNotificationsKey]))
|
||||||
|> map { presentationData, state, view, combinedView -> (ItemListControllerState, (ItemListNodeState<ChannelInfoEntry>, ChannelInfoEntry.ItemGenerationArguments)) in
|
|> map { presentationData, state, view, combinedView -> (ItemListControllerState, (ItemListNodeState<ChannelInfoEntry>, ChannelInfoEntry.ItemGenerationArguments)) in
|
||||||
let peer = peerViewMainPeer(view)
|
let peer = peerViewMainPeer(view)
|
||||||
|
|
||||||
|
|||||||
@ -44,13 +44,19 @@ private func actionForPeer(peer: Peer, isMuted: Bool) -> SubscriberAction? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private let badgeFont = Font.regular(14.0)
|
||||||
|
|
||||||
final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
||||||
private let button: UIButton
|
private let button: UIButton
|
||||||
|
private let discussButton: UIButton
|
||||||
|
private let badgeBackground: ASImageNode
|
||||||
|
private let badgeText: ImmediateTextNode
|
||||||
private let activityIndicator: UIActivityIndicatorView
|
private let activityIndicator: UIActivityIndicatorView
|
||||||
|
|
||||||
private var action: SubscriberAction?
|
private var action: SubscriberAction?
|
||||||
|
|
||||||
private let actionDisposable = MetaDisposable()
|
private let actionDisposable = MetaDisposable()
|
||||||
|
private let badgeDisposable = MetaDisposable()
|
||||||
|
|
||||||
private var presentationInterfaceState: ChatPresentationInterfaceState?
|
private var presentationInterfaceState: ChatPresentationInterfaceState?
|
||||||
|
|
||||||
@ -58,22 +64,40 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
|||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
self.button = UIButton()
|
self.button = UIButton()
|
||||||
|
self.discussButton = UIButton()
|
||||||
self.activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
|
self.activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: .gray)
|
||||||
self.activityIndicator.isHidden = true
|
self.activityIndicator.isHidden = true
|
||||||
|
|
||||||
|
self.badgeBackground = ASImageNode()
|
||||||
|
self.badgeBackground.displaysAsynchronously = false
|
||||||
|
self.badgeBackground.displayWithoutProcessing = true
|
||||||
|
self.badgeBackground.isHidden = true
|
||||||
|
|
||||||
|
self.badgeText = ImmediateTextNode()
|
||||||
|
self.badgeText.displaysAsynchronously = false
|
||||||
|
self.badgeText.isHidden = true
|
||||||
|
|
||||||
|
self.discussButton.addSubnode(self.badgeBackground)
|
||||||
|
self.discussButton.addSubnode(self.badgeText)
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.view.addSubview(self.button)
|
self.view.addSubview(self.button)
|
||||||
|
self.view.addSubview(self.discussButton)
|
||||||
self.view.addSubview(self.activityIndicator)
|
self.view.addSubview(self.activityIndicator)
|
||||||
|
|
||||||
button.addTarget(self, action: #selector(self.buttonPressed), for: [.touchUpInside])
|
self.button.addTarget(self, action: #selector(self.buttonPressed), for: [.touchUpInside])
|
||||||
|
self.discussButton.addTarget(self, action: #selector(self.discussPressed), for: [.touchUpInside])
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
self.actionDisposable.dispose()
|
self.actionDisposable.dispose()
|
||||||
|
self.badgeDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
return super.hitTest(point, with: event)
|
||||||
|
|
||||||
if self.bounds.contains(point) {
|
if self.bounds.contains(point) {
|
||||||
return self.button
|
return self.button
|
||||||
} else {
|
} else {
|
||||||
@ -108,6 +132,12 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func discussPressed() {
|
||||||
|
if let presentationInterfaceState = self.presentationInterfaceState, let peerDiscussionId = presentationInterfaceState.peerDiscussionId {
|
||||||
|
self.interfaceInteraction?.navigateToChat(peerDiscussionId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat {
|
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, maxHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics) -> CGFloat {
|
||||||
self.layoutData = (width, leftInset, rightInset)
|
self.layoutData = (width, leftInset, rightInset)
|
||||||
|
|
||||||
@ -115,7 +145,57 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
|||||||
let previousState = self.presentationInterfaceState
|
let previousState = self.presentationInterfaceState
|
||||||
self.presentationInterfaceState = interfaceState
|
self.presentationInterfaceState = interfaceState
|
||||||
|
|
||||||
if let peer = interfaceState.renderedPeer?.peer, previousState?.renderedPeer?.peer == nil || !peer.isEqual(previousState!.renderedPeer!.peer!) || previousState?.theme !== interfaceState.theme || previousState?.strings !== interfaceState.strings || previousState?.peerIsMuted != interfaceState.peerIsMuted {
|
if previousState?.theme !== interfaceState.theme {
|
||||||
|
self.badgeBackground.image = PresentationResourcesChatList.badgeBackgroundActive(interfaceState.theme)
|
||||||
|
}
|
||||||
|
|
||||||
|
if previousState?.peerDiscussionId != interfaceState.peerDiscussionId {
|
||||||
|
let signal: Signal<Int?, NoError>
|
||||||
|
if let peerDiscussionId = interfaceState.peerDiscussionId, let context = self.context {
|
||||||
|
let key = PostboxViewKey.unreadCounts(items: [.peer(peerDiscussionId)])
|
||||||
|
let inclusionKey = PostboxViewKey.peerChatInclusion(peerDiscussionId)
|
||||||
|
signal = context.account.postbox.combinedView(keys: [key, inclusionKey])
|
||||||
|
|> map { view -> Int? in
|
||||||
|
guard let inclusionView = view.views[inclusionKey] as? PeerChatInclusionView, let countsView = view.views[key] as? UnreadMessageCountsView else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !inclusionView.inclusion {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if let count = countsView.count(for: .peer(peerDiscussionId)), count != 0 {
|
||||||
|
return Int(count)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
} else {
|
||||||
|
signal = .single(nil)
|
||||||
|
}
|
||||||
|
self.badgeDisposable.set((signal
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] value in
|
||||||
|
guard let strongSelf = self, let interfaceState = strongSelf.presentationInterfaceState, let image = strongSelf.badgeBackground.image else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let text = "\(value ?? 0)"
|
||||||
|
|
||||||
|
strongSelf.badgeText.attributedText = NSAttributedString(string: text, font: badgeFont, textColor: interfaceState.theme.chatList.unreadBadgeActiveTextColor)
|
||||||
|
let textSize = strongSelf.badgeText.updateLayout(CGSize(width: 100.0, height: 100.0))
|
||||||
|
let badgeSize = CGSize(width: max(image.size.width, textSize.width + 4.0), height: image.size.height)
|
||||||
|
let badgeFrame = CGRect(origin: CGPoint(x: strongSelf.discussButton.bounds.width + 5.0, y: floor((strongSelf.discussButton.bounds.height - badgeSize.height) / 2.0)), size: badgeSize)
|
||||||
|
strongSelf.badgeBackground.frame = badgeFrame
|
||||||
|
strongSelf.badgeText.frame = CGRect(origin: CGPoint(x: badgeFrame.minX + floor((badgeSize.width - textSize.width) / 2.0), y: badgeFrame.minY + floor((badgeSize.height - textSize.height) / 2.0)), size: textSize)
|
||||||
|
if value == nil || value == 0 {
|
||||||
|
strongSelf.badgeBackground.isHidden = true
|
||||||
|
strongSelf.badgeText.isHidden = true
|
||||||
|
} else {
|
||||||
|
strongSelf.badgeBackground.isHidden = false
|
||||||
|
strongSelf.badgeText.isHidden = false
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
if let peer = interfaceState.renderedPeer?.peer, previousState?.renderedPeer?.peer == nil || !peer.isEqual(previousState!.renderedPeer!.peer!) || previousState?.theme !== interfaceState.theme || previousState?.strings !== interfaceState.strings || previousState?.peerIsMuted != interfaceState.peerIsMuted || previousState?.peerDiscussionId != interfaceState.peerDiscussionId {
|
||||||
if let action = actionForPeer(peer: peer, isMuted: interfaceState.peerIsMuted) {
|
if let action = actionForPeer(peer: peer, isMuted: interfaceState.peerIsMuted) {
|
||||||
self.action = action
|
self.action = action
|
||||||
let (title, color) = titleAndColorForAction(action, theme: interfaceState.theme, strings: interfaceState.strings)
|
let (title, color) = titleAndColorForAction(action, theme: interfaceState.theme, strings: interfaceState.strings)
|
||||||
@ -126,13 +206,33 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
|||||||
} else {
|
} else {
|
||||||
self.action = nil
|
self.action = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if interfaceState.peerDiscussionId != nil {
|
||||||
|
self.discussButton.setTitle(interfaceState.strings.Channel_DiscussionGroup_HeaderLabel, for: [])
|
||||||
|
self.discussButton.setTitleColor(interfaceState.theme.chat.inputPanel.panelControlAccentColor, for: [.normal])
|
||||||
|
self.discussButton.setTitleColor(interfaceState.theme.chat.inputPanel.panelControlAccentColor.withAlphaComponent(0.5), for: [.highlighted])
|
||||||
|
self.discussButton.sizeToFit()
|
||||||
|
self.discussButton.isHidden = false
|
||||||
|
} else {
|
||||||
|
self.discussButton.isHidden = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let panelHeight = defaultHeight(metrics: metrics)
|
let panelHeight = defaultHeight(metrics: metrics)
|
||||||
|
|
||||||
let buttonSize = self.button.bounds.size
|
let buttonSize = self.button.bounds.size
|
||||||
self.button.frame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - rightInset - buttonSize.width) / 2.0), y: floor((panelHeight - buttonSize.height) / 2.0)), size: buttonSize)
|
let discussSize = self.discussButton.bounds.size
|
||||||
|
if self.discussButton.isHidden {
|
||||||
|
self.button.frame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - rightInset - buttonSize.width) / 2.0), y: floor((panelHeight - buttonSize.height) / 2.0)), size: buttonSize)
|
||||||
|
} else {
|
||||||
|
let availableWidth = floor((width - leftInset - rightInset) / 2.0)
|
||||||
|
self.button.frame = CGRect(origin: CGPoint(x: leftInset + floor((availableWidth - buttonSize.width) / 2.0), y: floor((panelHeight - buttonSize.height) / 2.0)), size: buttonSize)
|
||||||
|
self.discussButton.frame = CGRect(origin: CGPoint(x: leftInset + availableWidth + floor((availableWidth - discussSize.width) / 2.0), y: floor((panelHeight - discussSize.height) / 2.0)), size: discussSize)
|
||||||
|
let badgeOffset = self.discussButton.bounds.width + 5.0 - self.badgeBackground.frame.minX
|
||||||
|
self.badgeBackground.frame = self.badgeBackground.frame.offsetBy(dx: badgeOffset, dy: 0.0)
|
||||||
|
self.badgeText.frame = self.badgeText.frame.offsetBy(dx: badgeOffset, dy: 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
let indicatorSize = self.activityIndicator.bounds.size
|
let indicatorSize = self.activityIndicator.bounds.size
|
||||||
self.activityIndicator.frame = CGRect(origin: CGPoint(x: width - rightInset - indicatorSize.width - 12.0, y: floor((panelHeight - indicatorSize.height) / 2.0)), size: indicatorSize)
|
self.activityIndicator.frame = CGRect(origin: CGPoint(x: width - rightInset - indicatorSize.width - 12.0, y: floor((panelHeight - indicatorSize.height) / 2.0)), size: indicatorSize)
|
||||||
|
|||||||
@ -1377,6 +1377,10 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
peerIsMuted = true
|
peerIsMuted = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var peerDiscussionId: PeerId?
|
||||||
|
if let peer = peerView.peers[peerView.peerId] as? TelegramChannel, case .broadcast = peer.info, let cachedData = peerView.cachedData as? CachedChannelData {
|
||||||
|
peerDiscussionId = cachedData.linkedDiscussionPeerId
|
||||||
|
}
|
||||||
var renderedPeer: RenderedPeer?
|
var renderedPeer: RenderedPeer?
|
||||||
var isContact: Bool = false
|
var isContact: Bool = false
|
||||||
if let peer = peerView.peers[peerView.peerId] {
|
if let peer = peerView.peers[peerView.peerId] {
|
||||||
@ -1422,7 +1426,7 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
}
|
}
|
||||||
strongSelf.updateChatPresentationInterfaceState(animated: animated, interactive: false, {
|
strongSelf.updateChatPresentationInterfaceState(animated: animated, interactive: false, {
|
||||||
return $0.updatedPeer { _ in return renderedPeer
|
return $0.updatedPeer { _ in return renderedPeer
|
||||||
}.updatedIsNotAccessible(isNotAccessible).updatedIsContact(isContact).updatedHasBots(hasBots).updatedIsArchived(isArchived).updatedPeerIsMuted(peerIsMuted).updatedExplicitelyCanPinMessages(explicitelyCanPinMessages)
|
}.updatedIsNotAccessible(isNotAccessible).updatedIsContact(isContact).updatedHasBots(hasBots).updatedIsArchived(isArchived).updatedPeerIsMuted(peerIsMuted).updatedPeerDiscussionId(peerDiscussionId).updatedExplicitelyCanPinMessages(explicitelyCanPinMessages)
|
||||||
})
|
})
|
||||||
if !strongSelf.didSetChatLocationInfoReady {
|
if !strongSelf.didSetChatLocationInfoReady {
|
||||||
strongSelf.didSetChatLocationInfoReady = true
|
strongSelf.didSetChatLocationInfoReady = true
|
||||||
@ -2591,6 +2595,13 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
}
|
}
|
||||||
}, navigateToMessage: { [weak self] messageId in
|
}, navigateToMessage: { [weak self] messageId in
|
||||||
self?.navigateToMessage(from: nil, to: .id(messageId))
|
self?.navigateToMessage(from: nil, to: .id(messageId))
|
||||||
|
}, navigateToChat: { [weak self] peerId in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let navigationController = strongSelf.navigationController as? NavigationController {
|
||||||
|
navigateToChatController(navigationController: navigationController, context: strongSelf.context, chatLocation: .peer(peerId), messageId: nil, keepStack: .always)
|
||||||
|
}
|
||||||
}, openPeerInfo: { [weak self] in
|
}, openPeerInfo: { [weak self] in
|
||||||
self?.navigationButtonAction(.openChatInfo)
|
self?.navigationButtonAction(.openChatInfo)
|
||||||
}, togglePeerNotifications: { [weak self] in
|
}, togglePeerNotifications: { [weak self] in
|
||||||
@ -5446,11 +5457,11 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
})
|
})
|
||||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
(strongSelf.navigationController as? NavigationController)?.pushViewController(ChatController(context: strongSelf.context, chatLocation: .peer(peerId), messageId: nil))
|
(strongSelf.navigationController as? NavigationController)?.pushViewController(ChatController(context: strongSelf.context, chatLocation: .peer(peerId), messageId: messageId))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
(self.navigationController as? NavigationController)?.pushViewController(ChatController(context: self.context, chatLocation: .peer(peerId), messageId: nil))
|
(self.navigationController as? NavigationController)?.pushViewController(ChatController(context: self.context, chatLocation: .peer(peerId), messageId: messageId))
|
||||||
}
|
}
|
||||||
case let .withBotStartPayload(botStart):
|
case let .withBotStartPayload(botStart):
|
||||||
(self.navigationController as? NavigationController)?.pushViewController(ChatController(context: self.context, chatLocation: .peer(peerId), messageId: nil, botStart: botStart))
|
(self.navigationController as? NavigationController)?.pushViewController(ChatController(context: self.context, chatLocation: .peer(peerId), messageId: nil, botStart: botStart))
|
||||||
|
|||||||
@ -631,7 +631,6 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return preparedChatHistoryViewTransition(from: previous, to: processedView, reason: reason, reverse: reverse, chatLocation: chatLocation, controllerInteraction: controllerInteraction, scrollPosition: updatedScrollPosition, initialData: initialData?.initialData, keyboardButtonsMessage: view.topTaggedMessages.first, cachedData: initialData?.cachedData, cachedDataMessages: initialData?.cachedDataMessages, readStateData: initialData?.readStateData, flashIndicators: flashIndicators)
|
return preparedChatHistoryViewTransition(from: previous, to: processedView, reason: reason, reverse: reverse, chatLocation: chatLocation, controllerInteraction: controllerInteraction, scrollPosition: updatedScrollPosition, initialData: initialData?.initialData, keyboardButtonsMessage: view.topTaggedMessages.first, cachedData: initialData?.cachedData, cachedDataMessages: initialData?.cachedDataMessages, readStateData: initialData?.readStateData, flashIndicators: flashIndicators)
|
||||||
|> map({
|
|> map({
|
||||||
mappedChatHistoryViewListTransition(context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, mode: mode, transition: $0)
|
mappedChatHistoryViewListTransition(context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, mode: mode, transition: $0)
|
||||||
@ -724,204 +723,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.displayedItemRangeChanged = { [weak self] displayedRange, opaqueTransactionState in
|
self.displayedItemRangeChanged = { [weak self] displayedRange, opaqueTransactionState in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self, let transactionState = opaqueTransactionState as? ChatHistoryTransactionOpaqueState {
|
||||||
if let historyView = (opaqueTransactionState as? ChatHistoryTransactionOpaqueState)?.historyView {
|
self?.processDisplayedItemRangeChanged(displayedRange: displayedRange, transactionState: transactionState)
|
||||||
if let visible = displayedRange.visibleRange {
|
|
||||||
let indexRange = (historyView.filteredEntries.count - 1 - visible.lastIndex, historyView.filteredEntries.count - 1 - visible.firstIndex)
|
|
||||||
|
|
||||||
let readIndexRange = (0, historyView.filteredEntries.count - 1 - visible.firstIndex)
|
|
||||||
|
|
||||||
let toEarlierRange = (0, historyView.filteredEntries.count - 1 - visible.lastIndex - 1)
|
|
||||||
let toLaterRange = (historyView.filteredEntries.count - 1 - (visible.firstIndex - 1), historyView.filteredEntries.count - 1)
|
|
||||||
|
|
||||||
var messageIdsWithViewCount: [MessageId] = []
|
|
||||||
var messageIdsWithUnsupportedMedia: [MessageId] = []
|
|
||||||
var messageIdsWithUnseenPersonalMention: [MessageId] = []
|
|
||||||
var messagesWithPreloadableMediaToEarlier: [(Message, Media)] = []
|
|
||||||
var messagesWithPreloadableMediaToLater: [(Message, Media)] = []
|
|
||||||
|
|
||||||
for i in (indexRange.0 ... indexRange.1) {
|
|
||||||
switch historyView.filteredEntries[i] {
|
|
||||||
case let .MessageEntry(message, _, _, _, _, _):
|
|
||||||
var hasUnconsumedMention = false
|
|
||||||
var hasUnconsumedContent = false
|
|
||||||
if message.tags.contains(.unseenPersonalMessage) {
|
|
||||||
for attribute in message.attributes {
|
|
||||||
if let attribute = attribute as? ConsumablePersonalMentionMessageAttribute, !attribute.pending {
|
|
||||||
hasUnconsumedMention = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var contentRequiredValidation = false
|
|
||||||
for attribute in message.attributes {
|
|
||||||
if attribute is ViewCountMessageAttribute {
|
|
||||||
if message.id.namespace == Namespaces.Message.Cloud {
|
|
||||||
messageIdsWithViewCount.append(message.id)
|
|
||||||
}
|
|
||||||
} else if let attribute = attribute as? ConsumableContentMessageAttribute, !attribute.consumed {
|
|
||||||
hasUnconsumedContent = true
|
|
||||||
} else if let _ = attribute as? ContentRequiresValidationMessageAttribute {
|
|
||||||
contentRequiredValidation = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for media in message.media {
|
|
||||||
if let _ = media as? TelegramMediaUnsupported {
|
|
||||||
contentRequiredValidation = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if contentRequiredValidation {
|
|
||||||
messageIdsWithUnsupportedMedia.append(message.id)
|
|
||||||
}
|
|
||||||
if hasUnconsumedMention && !hasUnconsumedContent {
|
|
||||||
messageIdsWithUnseenPersonalMention.append(message.id)
|
|
||||||
}
|
|
||||||
case let .MessageGroupEntry(_, messages, _):
|
|
||||||
for (message, _, _, _) in messages {
|
|
||||||
var hasUnconsumedMention = false
|
|
||||||
var hasUnconsumedContent = false
|
|
||||||
if message.tags.contains(.unseenPersonalMessage) {
|
|
||||||
for attribute in message.attributes {
|
|
||||||
if let attribute = attribute as? ConsumablePersonalMentionMessageAttribute, !attribute.pending {
|
|
||||||
hasUnconsumedMention = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for attribute in message.attributes {
|
|
||||||
if attribute is ViewCountMessageAttribute {
|
|
||||||
if message.id.namespace == Namespaces.Message.Cloud {
|
|
||||||
messageIdsWithViewCount.append(message.id)
|
|
||||||
}
|
|
||||||
} else if let attribute = attribute as? ConsumableContentMessageAttribute, !attribute.consumed {
|
|
||||||
hasUnconsumedContent = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if hasUnconsumedMention && !hasUnconsumedContent {
|
|
||||||
messageIdsWithUnseenPersonalMention.append(message.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func addMediaToPrefetch(_ message: Message, _ media: Media, _ messages: inout [(Message, Media)]) -> Bool {
|
|
||||||
if media is TelegramMediaImage || media is TelegramMediaFile {
|
|
||||||
messages.append((message, media))
|
|
||||||
}
|
|
||||||
if messages.count >= 3 {
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var toEarlierMediaMessages: [(Message, Media)] = []
|
|
||||||
if toEarlierRange.0 <= toEarlierRange.1 {
|
|
||||||
outer: for i in (toEarlierRange.0 ... toEarlierRange.1).reversed() {
|
|
||||||
switch historyView.filteredEntries[i] {
|
|
||||||
case let .MessageEntry(message, _, _, _, _, _):
|
|
||||||
for media in message.media {
|
|
||||||
if !addMediaToPrefetch(message, media, &toEarlierMediaMessages) {
|
|
||||||
break outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case let .MessageGroupEntry(_, messages, _):
|
|
||||||
for (message, _, _, _) in messages {
|
|
||||||
var stop = false
|
|
||||||
for media in message.media {
|
|
||||||
if !addMediaToPrefetch(message, media, &toEarlierMediaMessages) {
|
|
||||||
stop = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if stop {
|
|
||||||
break outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var toLaterMediaMessages: [(Message, Media)] = []
|
|
||||||
if toLaterRange.0 <= toLaterRange.1 {
|
|
||||||
outer: for i in (toLaterRange.0 ... toLaterRange.1) {
|
|
||||||
switch historyView.filteredEntries[i] {
|
|
||||||
case let .MessageEntry(message, _, _, _, _, _):
|
|
||||||
for media in message.media {
|
|
||||||
if !addMediaToPrefetch(message, media, &toLaterMediaMessages) {
|
|
||||||
break outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case let .MessageGroupEntry(_, messages, _):
|
|
||||||
for (message, _, _, _) in messages {
|
|
||||||
for media in message.media {
|
|
||||||
if !addMediaToPrefetch(message, media, &toLaterMediaMessages) {
|
|
||||||
break outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !messageIdsWithViewCount.isEmpty {
|
|
||||||
strongSelf.messageProcessingManager.add(messageIdsWithViewCount)
|
|
||||||
}
|
|
||||||
if !messageIdsWithUnsupportedMedia.isEmpty {
|
|
||||||
strongSelf.unsupportedMessageProcessingManager.add(messageIdsWithUnsupportedMedia)
|
|
||||||
}
|
|
||||||
if !messageIdsWithUnseenPersonalMention.isEmpty {
|
|
||||||
strongSelf.messageMentionProcessingManager.add(messageIdsWithUnseenPersonalMention)
|
|
||||||
}
|
|
||||||
|
|
||||||
strongSelf.currentEarlierPrefetchMessages = toEarlierMediaMessages
|
|
||||||
strongSelf.currentLaterPrefetchMessages = toLaterMediaMessages
|
|
||||||
if strongSelf.currentPrefetchDirectionIsToLater {
|
|
||||||
strongSelf.prefetchManager.updateMessages(toLaterMediaMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
|
|
||||||
} else {
|
|
||||||
strongSelf.prefetchManager.updateMessages(toEarlierMediaMessages, directionIsToLater: strongSelf.currentPrefetchDirectionIsToLater)
|
|
||||||
}
|
|
||||||
|
|
||||||
if readIndexRange.0 <= readIndexRange.1 {
|
|
||||||
let (maxIncomingIndex, maxOverallIndex) = maxMessageIndexForEntries(historyView, indexRange: readIndexRange)
|
|
||||||
|
|
||||||
if let maxIncomingIndex = maxIncomingIndex {
|
|
||||||
strongSelf.updateMaxVisibleReadIncomingMessageIndex(maxIncomingIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let maxOverallIndex = maxOverallIndex, maxOverallIndex != strongSelf.maxVisibleMessageIndexReported {
|
|
||||||
strongSelf.maxVisibleMessageIndexReported = maxOverallIndex
|
|
||||||
strongSelf.maxVisibleMessageIndexUpdated?(maxOverallIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let loaded = displayedRange.loadedRange, let firstEntry = historyView.filteredEntries.first, let lastEntry = historyView.filteredEntries.last {
|
|
||||||
if loaded.firstIndex < 5 && historyView.originalView.laterId != nil {
|
|
||||||
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount), id: 0)
|
|
||||||
} else if loaded.firstIndex < 5, historyView.originalView.laterId == nil, !historyView.originalView.holeLater, let chatHistoryLocationValue = strongSelf.chatHistoryLocationValue, !chatHistoryLocationValue.isAtUpperBound, historyView.originalView.anchorIndex != .upperBound {
|
|
||||||
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .upperBound, anchorIndex: .upperBound, count: historyMessageCount), id: 0)
|
|
||||||
} else if loaded.lastIndex >= historyView.filteredEntries.count - 5 && historyView.originalView.earlierId != nil {
|
|
||||||
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(firstEntry.index), anchorIndex: .message(firstEntry.index), count: historyMessageCount), id: 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var containsPlayableWithSoundItemNode = false
|
|
||||||
strongSelf.forEachVisibleItemNode { itemNode in
|
|
||||||
if let chatItemView = itemNode as? ChatMessageItemView, chatItemView.playMediaWithSound() != nil {
|
|
||||||
containsPlayableWithSoundItemNode = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
strongSelf.hasVisiblePlayableItemNodesPromise.set(containsPlayableWithSoundItemNode)
|
|
||||||
|
|
||||||
if containsPlayableWithSoundItemNode && !strongSelf.isInteractivelyScrollingValue {
|
|
||||||
strongSelf.isInteractivelyScrollingPromise.set(true)
|
|
||||||
strongSelf.isInteractivelyScrollingPromise.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1012,6 +815,205 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
self.loadStateUpdated = f
|
self.loadStateUpdated = f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func processDisplayedItemRangeChanged(displayedRange: ListViewDisplayedItemRange, transactionState: ChatHistoryTransactionOpaqueState) {
|
||||||
|
let historyView = transactionState.historyView
|
||||||
|
if let visible = displayedRange.visibleRange {
|
||||||
|
let indexRange = (historyView.filteredEntries.count - 1 - visible.lastIndex, historyView.filteredEntries.count - 1 - visible.firstIndex)
|
||||||
|
|
||||||
|
let readIndexRange = (0, historyView.filteredEntries.count - 1 - visible.firstIndex)
|
||||||
|
|
||||||
|
let toEarlierRange = (0, historyView.filteredEntries.count - 1 - visible.lastIndex - 1)
|
||||||
|
let toLaterRange = (historyView.filteredEntries.count - 1 - (visible.firstIndex - 1), historyView.filteredEntries.count - 1)
|
||||||
|
|
||||||
|
var messageIdsWithViewCount: [MessageId] = []
|
||||||
|
var messageIdsWithUnsupportedMedia: [MessageId] = []
|
||||||
|
var messageIdsWithUnseenPersonalMention: [MessageId] = []
|
||||||
|
var messagesWithPreloadableMediaToEarlier: [(Message, Media)] = []
|
||||||
|
var messagesWithPreloadableMediaToLater: [(Message, Media)] = []
|
||||||
|
|
||||||
|
for i in (indexRange.0 ... indexRange.1) {
|
||||||
|
switch historyView.filteredEntries[i] {
|
||||||
|
case let .MessageEntry(message, _, _, _, _, _):
|
||||||
|
var hasUnconsumedMention = false
|
||||||
|
var hasUnconsumedContent = false
|
||||||
|
if message.tags.contains(.unseenPersonalMessage) {
|
||||||
|
for attribute in message.attributes {
|
||||||
|
if let attribute = attribute as? ConsumablePersonalMentionMessageAttribute, !attribute.pending {
|
||||||
|
hasUnconsumedMention = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var contentRequiredValidation = false
|
||||||
|
for attribute in message.attributes {
|
||||||
|
if attribute is ViewCountMessageAttribute {
|
||||||
|
if message.id.namespace == Namespaces.Message.Cloud {
|
||||||
|
messageIdsWithViewCount.append(message.id)
|
||||||
|
}
|
||||||
|
} else if let attribute = attribute as? ConsumableContentMessageAttribute, !attribute.consumed {
|
||||||
|
hasUnconsumedContent = true
|
||||||
|
} else if let _ = attribute as? ContentRequiresValidationMessageAttribute {
|
||||||
|
contentRequiredValidation = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for media in message.media {
|
||||||
|
if let _ = media as? TelegramMediaUnsupported {
|
||||||
|
contentRequiredValidation = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if contentRequiredValidation {
|
||||||
|
messageIdsWithUnsupportedMedia.append(message.id)
|
||||||
|
}
|
||||||
|
if hasUnconsumedMention && !hasUnconsumedContent {
|
||||||
|
messageIdsWithUnseenPersonalMention.append(message.id)
|
||||||
|
}
|
||||||
|
case let .MessageGroupEntry(_, messages, _):
|
||||||
|
for (message, _, _, _) in messages {
|
||||||
|
var hasUnconsumedMention = false
|
||||||
|
var hasUnconsumedContent = false
|
||||||
|
if message.tags.contains(.unseenPersonalMessage) {
|
||||||
|
for attribute in message.attributes {
|
||||||
|
if let attribute = attribute as? ConsumablePersonalMentionMessageAttribute, !attribute.pending {
|
||||||
|
hasUnconsumedMention = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for attribute in message.attributes {
|
||||||
|
if attribute is ViewCountMessageAttribute {
|
||||||
|
if message.id.namespace == Namespaces.Message.Cloud {
|
||||||
|
messageIdsWithViewCount.append(message.id)
|
||||||
|
}
|
||||||
|
} else if let attribute = attribute as? ConsumableContentMessageAttribute, !attribute.consumed {
|
||||||
|
hasUnconsumedContent = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if hasUnconsumedMention && !hasUnconsumedContent {
|
||||||
|
messageIdsWithUnseenPersonalMention.append(message.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addMediaToPrefetch(_ message: Message, _ media: Media, _ messages: inout [(Message, Media)]) -> Bool {
|
||||||
|
if media is TelegramMediaImage || media is TelegramMediaFile {
|
||||||
|
messages.append((message, media))
|
||||||
|
}
|
||||||
|
if messages.count >= 3 {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var toEarlierMediaMessages: [(Message, Media)] = []
|
||||||
|
if toEarlierRange.0 <= toEarlierRange.1 {
|
||||||
|
outer: for i in (toEarlierRange.0 ... toEarlierRange.1).reversed() {
|
||||||
|
switch historyView.filteredEntries[i] {
|
||||||
|
case let .MessageEntry(message, _, _, _, _, _):
|
||||||
|
for media in message.media {
|
||||||
|
if !addMediaToPrefetch(message, media, &toEarlierMediaMessages) {
|
||||||
|
break outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case let .MessageGroupEntry(_, messages, _):
|
||||||
|
for (message, _, _, _) in messages {
|
||||||
|
var stop = false
|
||||||
|
for media in message.media {
|
||||||
|
if !addMediaToPrefetch(message, media, &toEarlierMediaMessages) {
|
||||||
|
stop = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if stop {
|
||||||
|
break outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var toLaterMediaMessages: [(Message, Media)] = []
|
||||||
|
if toLaterRange.0 <= toLaterRange.1 {
|
||||||
|
outer: for i in (toLaterRange.0 ... toLaterRange.1) {
|
||||||
|
switch historyView.filteredEntries[i] {
|
||||||
|
case let .MessageEntry(message, _, _, _, _, _):
|
||||||
|
for media in message.media {
|
||||||
|
if !addMediaToPrefetch(message, media, &toLaterMediaMessages) {
|
||||||
|
break outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case let .MessageGroupEntry(_, messages, _):
|
||||||
|
for (message, _, _, _) in messages {
|
||||||
|
for media in message.media {
|
||||||
|
if !addMediaToPrefetch(message, media, &toLaterMediaMessages) {
|
||||||
|
break outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !messageIdsWithViewCount.isEmpty {
|
||||||
|
self.messageProcessingManager.add(messageIdsWithViewCount)
|
||||||
|
}
|
||||||
|
if !messageIdsWithUnsupportedMedia.isEmpty {
|
||||||
|
self.unsupportedMessageProcessingManager.add(messageIdsWithUnsupportedMedia)
|
||||||
|
}
|
||||||
|
if !messageIdsWithUnseenPersonalMention.isEmpty {
|
||||||
|
self.messageMentionProcessingManager.add(messageIdsWithUnseenPersonalMention)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.currentEarlierPrefetchMessages = toEarlierMediaMessages
|
||||||
|
self.currentLaterPrefetchMessages = toLaterMediaMessages
|
||||||
|
if self.currentPrefetchDirectionIsToLater {
|
||||||
|
self.prefetchManager.updateMessages(toLaterMediaMessages, directionIsToLater: self.currentPrefetchDirectionIsToLater)
|
||||||
|
} else {
|
||||||
|
self.prefetchManager.updateMessages(toEarlierMediaMessages, directionIsToLater: self.currentPrefetchDirectionIsToLater)
|
||||||
|
}
|
||||||
|
|
||||||
|
if readIndexRange.0 <= readIndexRange.1 {
|
||||||
|
let (maxIncomingIndex, maxOverallIndex) = maxMessageIndexForEntries(historyView, indexRange: readIndexRange)
|
||||||
|
|
||||||
|
if let maxIncomingIndex = maxIncomingIndex {
|
||||||
|
self.updateMaxVisibleReadIncomingMessageIndex(maxIncomingIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let maxOverallIndex = maxOverallIndex, maxOverallIndex != self.maxVisibleMessageIndexReported {
|
||||||
|
self.maxVisibleMessageIndexReported = maxOverallIndex
|
||||||
|
self.maxVisibleMessageIndexUpdated?(maxOverallIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let loaded = displayedRange.loadedRange, let firstEntry = historyView.filteredEntries.first, let lastEntry = historyView.filteredEntries.last {
|
||||||
|
if loaded.firstIndex < 5 && historyView.originalView.laterId != nil {
|
||||||
|
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(lastEntry.index), anchorIndex: .message(lastEntry.index), count: historyMessageCount), id: 0)
|
||||||
|
} else if loaded.firstIndex < 5, historyView.originalView.laterId == nil, !historyView.originalView.holeLater, let chatHistoryLocationValue = self.chatHistoryLocationValue, !chatHistoryLocationValue.isAtUpperBound, historyView.originalView.anchorIndex != .upperBound {
|
||||||
|
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .upperBound, anchorIndex: .upperBound, count: historyMessageCount), id: 0)
|
||||||
|
} else if loaded.lastIndex >= historyView.filteredEntries.count - 5 && historyView.originalView.earlierId != nil {
|
||||||
|
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .message(firstEntry.index), anchorIndex: .message(firstEntry.index), count: historyMessageCount), id: 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var containsPlayableWithSoundItemNode = false
|
||||||
|
self.forEachVisibleItemNode { itemNode in
|
||||||
|
if let chatItemView = itemNode as? ChatMessageItemView, chatItemView.playMediaWithSound() != nil {
|
||||||
|
containsPlayableWithSoundItemNode = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.hasVisiblePlayableItemNodesPromise.set(containsPlayableWithSoundItemNode)
|
||||||
|
|
||||||
|
if containsPlayableWithSoundItemNode && !self.isInteractivelyScrollingValue {
|
||||||
|
self.isInteractivelyScrollingPromise.set(true)
|
||||||
|
self.isInteractivelyScrollingPromise.set(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func scrollScreenToTop() {
|
public func scrollScreenToTop() {
|
||||||
var currentMessage: Message?
|
var currentMessage: Message?
|
||||||
if let historyView = self.historyView {
|
if let historyView = self.historyView {
|
||||||
|
|||||||
@ -695,7 +695,7 @@ func chatAvailableMessageActions(postbox: Postbox, accountPeerId: PeerId, messag
|
|||||||
if message.flags.contains(.Incoming) {
|
if message.flags.contains(.Incoming) {
|
||||||
optionsMap[id]!.insert(.report)
|
optionsMap[id]!.insert(.report)
|
||||||
}
|
}
|
||||||
if channel.hasPermission(.banMembers), case .group = channel.info {
|
if channel.hasPermission(.banMembers), case .group = channel.info, message.author is TelegramUser {
|
||||||
if message.flags.contains(.Incoming) {
|
if message.flags.contains(.Incoming) {
|
||||||
if !hadBanPeerId {
|
if !hadBanPeerId {
|
||||||
hadBanPeerId = true
|
hadBanPeerId = true
|
||||||
|
|||||||
@ -132,6 +132,7 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
|
|||||||
return currentPanel
|
return currentPanel
|
||||||
} else {
|
} else {
|
||||||
let panel = ChatChannelSubscriberInputPanelNode()
|
let panel = ChatChannelSubscriberInputPanelNode()
|
||||||
|
panel.interfaceInteraction = interfaceInteraction
|
||||||
panel.context = context
|
panel.context = context
|
||||||
return panel
|
return panel
|
||||||
}
|
}
|
||||||
@ -143,6 +144,7 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
|
|||||||
return currentPanel
|
return currentPanel
|
||||||
} else {
|
} else {
|
||||||
let panel = ChatChannelSubscriberInputPanelNode()
|
let panel = ChatChannelSubscriberInputPanelNode()
|
||||||
|
panel.interfaceInteraction = interfaceInteraction
|
||||||
panel.context = context
|
panel.context = context
|
||||||
return panel
|
return panel
|
||||||
}
|
}
|
||||||
|
|||||||
@ -379,6 +379,21 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
|||||||
let firstMessage = content.firstMessage
|
let firstMessage = content.firstMessage
|
||||||
let incoming = item.content.effectivelyIncoming(item.context.account.peerId)
|
let incoming = item.content.effectivelyIncoming(item.context.account.peerId)
|
||||||
|
|
||||||
|
var sourceReference: SourceReferenceMessageAttribute?
|
||||||
|
for attribute in item.content.firstMessage.attributes {
|
||||||
|
if let attribute = attribute as? SourceReferenceMessageAttribute {
|
||||||
|
sourceReference = attribute
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var isCrosspostFromChannel = false
|
||||||
|
if let _ = sourceReference {
|
||||||
|
if firstMessage.id.peerId != item.context.account.peerId {
|
||||||
|
isCrosspostFromChannel = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var effectiveAuthor: Peer?
|
var effectiveAuthor: Peer?
|
||||||
var ignoreForward = false
|
var ignoreForward = false
|
||||||
let displayAuthorInfo: Bool
|
let displayAuthorInfo: Bool
|
||||||
@ -398,6 +413,12 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
displayAuthorInfo = !mergedTop.merged && incoming && effectiveAuthor != nil
|
displayAuthorInfo = !mergedTop.merged && incoming && effectiveAuthor != nil
|
||||||
|
} else if isCrosspostFromChannel, let sourceReference = sourceReference, let source = firstMessage.peers[sourceReference.messageId.peerId] {
|
||||||
|
if firstMessage.forwardInfo?.author?.id == source.id {
|
||||||
|
ignoreForward = true
|
||||||
|
}
|
||||||
|
effectiveAuthor = source
|
||||||
|
displayAuthorInfo = !mergedTop.merged && incoming && effectiveAuthor != nil
|
||||||
} else {
|
} else {
|
||||||
effectiveAuthor = firstMessage.author
|
effectiveAuthor = firstMessage.author
|
||||||
displayAuthorInfo = !mergedTop.merged && incoming && peerId.isGroupOrChannel && effectiveAuthor != nil
|
displayAuthorInfo = !mergedTop.merged && incoming && peerId.isGroupOrChannel && effectiveAuthor != nil
|
||||||
@ -443,13 +464,14 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
|||||||
if item.message.flags.contains(.Failed) {
|
if item.message.flags.contains(.Failed) {
|
||||||
needShareButton = false
|
needShareButton = false
|
||||||
} else if item.message.id.peerId == item.context.account.peerId {
|
} else if item.message.id.peerId == item.context.account.peerId {
|
||||||
for attribute in item.content.firstMessage.attributes {
|
if let _ = sourceReference {
|
||||||
if let _ = attribute as? SourceReferenceMessageAttribute {
|
needShareButton = true
|
||||||
needShareButton = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if item.message.effectivelyIncoming(item.context.account.peerId) {
|
} else if item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||||
|
if let _ = sourceReference {
|
||||||
|
needShareButton = true
|
||||||
|
}
|
||||||
|
|
||||||
if let peer = item.message.peers[item.message.id.peerId] {
|
if let peer = item.message.peers[item.message.id.peerId] {
|
||||||
if let channel = peer as? TelegramChannel {
|
if let channel = peer as? TelegramChannel {
|
||||||
if case .broadcast = channel.info {
|
if case .broadcast = channel.info {
|
||||||
@ -536,11 +558,22 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
|||||||
|
|
||||||
var authorNameString: String?
|
var authorNameString: String?
|
||||||
let authorIsAdmin: Bool
|
let authorIsAdmin: Bool
|
||||||
|
var authorIsChannel: Bool = false
|
||||||
switch content {
|
switch content {
|
||||||
case let .message(message, _, _, attributes):
|
case let .message(message, _, _, attributes):
|
||||||
if let peer = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = peer.info {
|
if let peer = message.peers[message.id.peerId] as? TelegramChannel {
|
||||||
authorIsAdmin = false
|
if case .broadcast = peer.info {
|
||||||
|
authorIsAdmin = false
|
||||||
|
} else {
|
||||||
|
if isCrosspostFromChannel, let sourceReference = sourceReference, let _ = firstMessage.peers[sourceReference.messageId.peerId] as? TelegramChannel {
|
||||||
|
authorIsChannel = true
|
||||||
|
}
|
||||||
|
authorIsAdmin = attributes.isAdmin
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if isCrosspostFromChannel, let _ = firstMessage.forwardInfo?.source as? TelegramChannel {
|
||||||
|
authorIsChannel = true
|
||||||
|
}
|
||||||
authorIsAdmin = attributes.isAdmin
|
authorIsAdmin = attributes.isAdmin
|
||||||
}
|
}
|
||||||
case .group:
|
case .group:
|
||||||
@ -823,6 +856,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
|||||||
var adminBadgeString: NSAttributedString?
|
var adminBadgeString: NSAttributedString?
|
||||||
if authorIsAdmin {
|
if authorIsAdmin {
|
||||||
adminBadgeString = NSAttributedString(string: " \(item.presentationData.strings.Conversation_Admin)", font: inlineBotPrefixFont, textColor: incoming ? item.presentationData.theme.theme.chat.bubble.incomingSecondaryTextColor : item.presentationData.theme.theme.chat.bubble.outgoingSecondaryTextColor)
|
adminBadgeString = NSAttributedString(string: " \(item.presentationData.strings.Conversation_Admin)", font: inlineBotPrefixFont, textColor: incoming ? item.presentationData.theme.theme.chat.bubble.incomingSecondaryTextColor : item.presentationData.theme.theme.chat.bubble.outgoingSecondaryTextColor)
|
||||||
|
} else if authorIsChannel {
|
||||||
|
adminBadgeString = NSAttributedString(string: " \(item.presentationData.strings.Channel_Status)", font: inlineBotPrefixFont, textColor: incoming ? item.presentationData.theme.theme.chat.bubble.incomingSecondaryTextColor : item.presentationData.theme.theme.chat.bubble.outgoingSecondaryTextColor)
|
||||||
}
|
}
|
||||||
if let authorNameString = authorNameString, let authorNameColor = authorNameColor, let inlineBotNameString = inlineBotNameString {
|
if let authorNameString = authorNameString, let authorNameColor = authorNameColor, let inlineBotNameString = inlineBotNameString {
|
||||||
let mutableString = NSMutableAttributedString(string: "\(authorNameString) ", attributes: [NSAttributedStringKey.font: nameFont, NSAttributedStringKey.foregroundColor: authorNameColor])
|
let mutableString = NSMutableAttributedString(string: "\(authorNameString) ", attributes: [NSAttributedStringKey.font: nameFont, NSAttributedStringKey.foregroundColor: authorNameColor])
|
||||||
@ -1777,13 +1812,22 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
|||||||
case .tap:
|
case .tap:
|
||||||
if let avatarNode = self.accessoryItemNode as? ChatMessageAvatarAccessoryItemNode, avatarNode.frame.contains(location) {
|
if let avatarNode = self.accessoryItemNode as? ChatMessageAvatarAccessoryItemNode, avatarNode.frame.contains(location) {
|
||||||
if let item = self.item, let author = item.content.firstMessage.author {
|
if let item = self.item, let author = item.content.firstMessage.author {
|
||||||
let navigate: ChatControllerInteractionNavigateToPeer
|
var openPeerId = item.effectiveAuthorId ?? author.id
|
||||||
|
var navigate: ChatControllerInteractionNavigateToPeer
|
||||||
|
|
||||||
if item.content.firstMessage.id.peerId == item.context.account.peerId {
|
if item.content.firstMessage.id.peerId == item.context.account.peerId {
|
||||||
navigate = .chat(textInputState: nil, messageId: nil)
|
navigate = .chat(textInputState: nil, messageId: nil)
|
||||||
} else {
|
} else {
|
||||||
navigate = .info
|
navigate = .info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for attribute in item.content.firstMessage.attributes {
|
||||||
|
if let attribute = attribute as? SourceReferenceMessageAttribute {
|
||||||
|
openPeerId = attribute.messageId.peerId
|
||||||
|
navigate = .chat(textInputState: nil, messageId: attribute.messageId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
|
if item.effectiveAuthorId?.namespace == Namespaces.Peer.Empty {
|
||||||
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
|
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, self, avatarNode.frame)
|
||||||
} else {
|
} else {
|
||||||
@ -1794,7 +1838,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item.controllerInteraction.openPeer(item.effectiveAuthorId ?? author.id, navigate, item.message)
|
item.controllerInteraction.openPeer(openPeerId, navigate, item.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@ -91,6 +91,19 @@ private func mediaMergeableStyle(_ media: Media) -> ChatMessageMerge {
|
|||||||
private func messagesShouldBeMerged(accountPeerId: PeerId, _ lhs: Message, _ rhs: Message) -> ChatMessageMerge {
|
private func messagesShouldBeMerged(accountPeerId: PeerId, _ lhs: Message, _ rhs: Message) -> ChatMessageMerge {
|
||||||
var lhsEffectiveAuthor: Peer? = lhs.author
|
var lhsEffectiveAuthor: Peer? = lhs.author
|
||||||
var rhsEffectiveAuthor: Peer? = rhs.author
|
var rhsEffectiveAuthor: Peer? = rhs.author
|
||||||
|
for attribute in lhs.attributes {
|
||||||
|
if let attribute = attribute as? SourceReferenceMessageAttribute {
|
||||||
|
lhsEffectiveAuthor = lhs.peers[attribute.messageId.peerId]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for attribute in rhs.attributes {
|
||||||
|
if let attribute = attribute as? SourceReferenceMessageAttribute {
|
||||||
|
rhsEffectiveAuthor = rhs.peers[attribute.messageId.peerId]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if lhs.id.peerId == accountPeerId {
|
if lhs.id.peerId == accountPeerId {
|
||||||
if let forwardInfo = lhs.forwardInfo {
|
if let forwardInfo = lhs.forwardInfo {
|
||||||
lhsEffectiveAuthor = forwardInfo.author
|
lhsEffectiveAuthor = forwardInfo.author
|
||||||
@ -277,6 +290,12 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
|
|||||||
displayAuthorInfo = incoming && effectiveAuthor != nil
|
displayAuthorInfo = incoming && effectiveAuthor != nil
|
||||||
} else {
|
} else {
|
||||||
effectiveAuthor = content.firstMessage.author
|
effectiveAuthor = content.firstMessage.author
|
||||||
|
for attribute in content.firstMessage.attributes {
|
||||||
|
if let attribute = attribute as? SourceReferenceMessageAttribute {
|
||||||
|
effectiveAuthor = content.firstMessage.peers[attribute.messageId.peerId]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
displayAuthorInfo = incoming && peerId.isGroupOrChannel && effectiveAuthor != nil
|
displayAuthorInfo = incoming && peerId.isGroupOrChannel && effectiveAuthor != nil
|
||||||
}
|
}
|
||||||
/*case .group:
|
/*case .group:
|
||||||
|
|||||||
@ -59,6 +59,7 @@ final class ChatPanelInterfaceInteraction {
|
|||||||
let openCalendarSearch: () -> Void
|
let openCalendarSearch: () -> Void
|
||||||
let toggleMembersSearch: (Bool) -> Void
|
let toggleMembersSearch: (Bool) -> Void
|
||||||
let navigateToMessage: (MessageId) -> Void
|
let navigateToMessage: (MessageId) -> Void
|
||||||
|
let navigateToChat: (PeerId) -> Void
|
||||||
let openPeerInfo: () -> Void
|
let openPeerInfo: () -> Void
|
||||||
let togglePeerNotifications: () -> Void
|
let togglePeerNotifications: () -> Void
|
||||||
let sendContextResult: (ChatContextResultCollection, ChatContextResult) -> Void
|
let sendContextResult: (ChatContextResultCollection, ChatContextResult) -> Void
|
||||||
@ -97,7 +98,7 @@ final class ChatPanelInterfaceInteraction {
|
|||||||
let unarchiveChat: () -> Void
|
let unarchiveChat: () -> Void
|
||||||
let statuses: ChatPanelInterfaceInteractionStatuses?
|
let statuses: ChatPanelInterfaceInteractionStatuses?
|
||||||
|
|
||||||
init(setupReplyMessage: @escaping (MessageId) -> Void, setupEditMessage: @escaping (MessageId?) -> Void, beginMessageSelection: @escaping ([MessageId]) -> Void, deleteSelectedMessages: @escaping () -> Void, reportSelectedMessages: @escaping () -> Void, reportMessages: @escaping ([Message]) -> Void, deleteMessages: @escaping ([Message]) -> Void, forwardSelectedMessages: @escaping () -> Void, forwardCurrentForwardMessages: @escaping () -> Void, forwardMessages: @escaping ([Message]) -> Void, shareSelectedMessages: @escaping () -> Void, updateTextInputStateAndMode: @escaping ((ChatTextInputState, ChatInputMode) -> (ChatTextInputState, ChatInputMode)) -> Void, updateInputModeAndDismissedButtonKeyboardMessageId: @escaping ((ChatPresentationInterfaceState) -> (ChatInputMode, MessageId?)) -> Void, openStickers: @escaping () -> Void, editMessage: @escaping () -> Void, beginMessageSearch: @escaping (ChatSearchDomain, String) -> Void, dismissMessageSearch: @escaping () -> Void, updateMessageSearch: @escaping (String) -> Void, navigateMessageSearch: @escaping (ChatPanelSearchNavigationAction) -> Void, openCalendarSearch: @escaping () -> Void, toggleMembersSearch: @escaping (Bool) -> Void, navigateToMessage: @escaping (MessageId) -> Void, openPeerInfo: @escaping () -> Void, togglePeerNotifications: @escaping () -> Void, sendContextResult: @escaping (ChatContextResultCollection, ChatContextResult) -> Void, sendBotCommand: @escaping (Peer, String) -> Void, sendBotStart: @escaping (String?) -> Void, botSwitchChatWithPayload: @escaping (PeerId, String) -> Void, beginMediaRecording: @escaping (Bool) -> Void, finishMediaRecording: @escaping (ChatFinishMediaRecordingAction) -> Void, stopMediaRecording: @escaping () -> Void, lockMediaRecording: @escaping () -> Void, deleteRecordedMedia: @escaping () -> Void, sendRecordedMedia: @escaping () -> Void, displayRestrictedInfo: @escaping (ChatPanelRestrictionInfoSubject) -> Void, displayVideoUnmuteTip: @escaping (CGPoint?) -> Void, switchMediaRecordingMode: @escaping () -> Void, setupMessageAutoremoveTimeout: @escaping () -> Void, sendSticker: @escaping (FileMediaReference) -> Void, unblockPeer: @escaping () -> Void, pinMessage: @escaping (MessageId) -> Void, unpinMessage: @escaping () -> Void, reportPeer: @escaping () -> Void, presentPeerContact: @escaping () -> Void, dismissReportPeer: @escaping () -> Void, deleteChat: @escaping () -> Void, beginCall: @escaping () -> Void, toggleMessageStickerStarred: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: @escaping () -> NavigationController?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, navigateFeed: @escaping () -> Void, openGrouping: @escaping () -> Void, toggleSilentPost: @escaping () -> Void, requestUnvoteInMessage: @escaping (MessageId) -> Void, requestStopPollInMessage: @escaping (MessageId) -> Void, updateInputLanguage: @escaping ((String?) -> String?) -> Void, unarchiveChat: @escaping () -> Void, statuses: ChatPanelInterfaceInteractionStatuses?) {
|
init(setupReplyMessage: @escaping (MessageId) -> Void, setupEditMessage: @escaping (MessageId?) -> Void, beginMessageSelection: @escaping ([MessageId]) -> Void, deleteSelectedMessages: @escaping () -> Void, reportSelectedMessages: @escaping () -> Void, reportMessages: @escaping ([Message]) -> Void, deleteMessages: @escaping ([Message]) -> Void, forwardSelectedMessages: @escaping () -> Void, forwardCurrentForwardMessages: @escaping () -> Void, forwardMessages: @escaping ([Message]) -> Void, shareSelectedMessages: @escaping () -> Void, updateTextInputStateAndMode: @escaping ((ChatTextInputState, ChatInputMode) -> (ChatTextInputState, ChatInputMode)) -> Void, updateInputModeAndDismissedButtonKeyboardMessageId: @escaping ((ChatPresentationInterfaceState) -> (ChatInputMode, MessageId?)) -> Void, openStickers: @escaping () -> Void, editMessage: @escaping () -> Void, beginMessageSearch: @escaping (ChatSearchDomain, String) -> Void, dismissMessageSearch: @escaping () -> Void, updateMessageSearch: @escaping (String) -> Void, navigateMessageSearch: @escaping (ChatPanelSearchNavigationAction) -> Void, openCalendarSearch: @escaping () -> Void, toggleMembersSearch: @escaping (Bool) -> Void, navigateToMessage: @escaping (MessageId) -> Void, navigateToChat: @escaping (PeerId) -> Void, openPeerInfo: @escaping () -> Void, togglePeerNotifications: @escaping () -> Void, sendContextResult: @escaping (ChatContextResultCollection, ChatContextResult) -> Void, sendBotCommand: @escaping (Peer, String) -> Void, sendBotStart: @escaping (String?) -> Void, botSwitchChatWithPayload: @escaping (PeerId, String) -> Void, beginMediaRecording: @escaping (Bool) -> Void, finishMediaRecording: @escaping (ChatFinishMediaRecordingAction) -> Void, stopMediaRecording: @escaping () -> Void, lockMediaRecording: @escaping () -> Void, deleteRecordedMedia: @escaping () -> Void, sendRecordedMedia: @escaping () -> Void, displayRestrictedInfo: @escaping (ChatPanelRestrictionInfoSubject) -> Void, displayVideoUnmuteTip: @escaping (CGPoint?) -> Void, switchMediaRecordingMode: @escaping () -> Void, setupMessageAutoremoveTimeout: @escaping () -> Void, sendSticker: @escaping (FileMediaReference) -> Void, unblockPeer: @escaping () -> Void, pinMessage: @escaping (MessageId) -> Void, unpinMessage: @escaping () -> Void, reportPeer: @escaping () -> Void, presentPeerContact: @escaping () -> Void, dismissReportPeer: @escaping () -> Void, deleteChat: @escaping () -> Void, beginCall: @escaping () -> Void, toggleMessageStickerStarred: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, getNavigationController: @escaping () -> NavigationController?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, navigateFeed: @escaping () -> Void, openGrouping: @escaping () -> Void, toggleSilentPost: @escaping () -> Void, requestUnvoteInMessage: @escaping (MessageId) -> Void, requestStopPollInMessage: @escaping (MessageId) -> Void, updateInputLanguage: @escaping ((String?) -> String?) -> Void, unarchiveChat: @escaping () -> Void, statuses: ChatPanelInterfaceInteractionStatuses?) {
|
||||||
self.setupReplyMessage = setupReplyMessage
|
self.setupReplyMessage = setupReplyMessage
|
||||||
self.setupEditMessage = setupEditMessage
|
self.setupEditMessage = setupEditMessage
|
||||||
self.beginMessageSelection = beginMessageSelection
|
self.beginMessageSelection = beginMessageSelection
|
||||||
@ -120,6 +121,7 @@ final class ChatPanelInterfaceInteraction {
|
|||||||
self.openCalendarSearch = openCalendarSearch
|
self.openCalendarSearch = openCalendarSearch
|
||||||
self.toggleMembersSearch = toggleMembersSearch
|
self.toggleMembersSearch = toggleMembersSearch
|
||||||
self.navigateToMessage = navigateToMessage
|
self.navigateToMessage = navigateToMessage
|
||||||
|
self.navigateToChat = navigateToChat
|
||||||
self.openPeerInfo = openPeerInfo
|
self.openPeerInfo = openPeerInfo
|
||||||
self.togglePeerNotifications = togglePeerNotifications
|
self.togglePeerNotifications = togglePeerNotifications
|
||||||
self.sendContextResult = sendContextResult
|
self.sendContextResult = sendContextResult
|
||||||
|
|||||||
@ -331,6 +331,7 @@ final class ChatPresentationInterfaceState: Equatable {
|
|||||||
let pinnedMessage: Message?
|
let pinnedMessage: Message?
|
||||||
let peerIsBlocked: Bool
|
let peerIsBlocked: Bool
|
||||||
let peerIsMuted: Bool
|
let peerIsMuted: Bool
|
||||||
|
let peerDiscussionId: PeerId?
|
||||||
let canReportPeer: Bool
|
let canReportPeer: Bool
|
||||||
let callsAvailable: Bool
|
let callsAvailable: Bool
|
||||||
let callsPrivate: Bool
|
let callsPrivate: Bool
|
||||||
@ -370,6 +371,7 @@ final class ChatPresentationInterfaceState: Equatable {
|
|||||||
self.pinnedMessage = nil
|
self.pinnedMessage = nil
|
||||||
self.peerIsBlocked = false
|
self.peerIsBlocked = false
|
||||||
self.peerIsMuted = false
|
self.peerIsMuted = false
|
||||||
|
self.peerDiscussionId = nil
|
||||||
self.canReportPeer = false
|
self.canReportPeer = false
|
||||||
self.callsAvailable = false
|
self.callsAvailable = false
|
||||||
self.callsPrivate = false
|
self.callsPrivate = false
|
||||||
@ -390,7 +392,7 @@ final class ChatPresentationInterfaceState: Equatable {
|
|||||||
self.mode = mode
|
self.mode = mode
|
||||||
}
|
}
|
||||||
|
|
||||||
init(interfaceState: ChatInterfaceState, chatLocation: ChatLocation, renderedPeer: RenderedPeer?, isNotAccessible: Bool, explicitelyCanPinMessages: Bool, isContact: Bool, hasBots: Bool, isArchived: Bool, inputTextPanelState: ChatTextInputPanelState, editMessageState: ChatEditInterfaceMessageState?, recordedMediaPreview: ChatRecordedMediaPreview?, inputQueryResults: [ChatPresentationInputQueryKind: ChatPresentationInputQueryResult], inputMode: ChatInputMode, titlePanelContexts: [ChatTitlePanelContext], keyboardButtonsMessage: Message?, pinnedMessageId: MessageId?, pinnedMessage: Message?, peerIsBlocked: Bool, peerIsMuted: Bool, canReportPeer: Bool, callsAvailable: Bool, callsPrivate: Bool, chatHistoryState: ChatHistoryNodeHistoryState?, botStartPayload: String?, urlPreview: (String, TelegramMediaWebpage)?, editingUrlPreview: (String, TelegramMediaWebpage)?, search: ChatSearchData?, searchQuerySuggestionResult: ChatPresentationInputQueryResult?, chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, accountPeerId: PeerId, mode: ChatControllerPresentationMode) {
|
init(interfaceState: ChatInterfaceState, chatLocation: ChatLocation, renderedPeer: RenderedPeer?, isNotAccessible: Bool, explicitelyCanPinMessages: Bool, isContact: Bool, hasBots: Bool, isArchived: Bool, inputTextPanelState: ChatTextInputPanelState, editMessageState: ChatEditInterfaceMessageState?, recordedMediaPreview: ChatRecordedMediaPreview?, inputQueryResults: [ChatPresentationInputQueryKind: ChatPresentationInputQueryResult], inputMode: ChatInputMode, titlePanelContexts: [ChatTitlePanelContext], keyboardButtonsMessage: Message?, pinnedMessageId: MessageId?, pinnedMessage: Message?, peerIsBlocked: Bool, peerIsMuted: Bool, peerDiscussionId: PeerId?, canReportPeer: Bool, callsAvailable: Bool, callsPrivate: Bool, chatHistoryState: ChatHistoryNodeHistoryState?, botStartPayload: String?, urlPreview: (String, TelegramMediaWebpage)?, editingUrlPreview: (String, TelegramMediaWebpage)?, search: ChatSearchData?, searchQuerySuggestionResult: ChatPresentationInputQueryResult?, chatWallpaper: TelegramWallpaper, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, limitsConfiguration: LimitsConfiguration, fontSize: PresentationFontSize, accountPeerId: PeerId, mode: ChatControllerPresentationMode) {
|
||||||
self.interfaceState = interfaceState
|
self.interfaceState = interfaceState
|
||||||
self.chatLocation = chatLocation
|
self.chatLocation = chatLocation
|
||||||
self.renderedPeer = renderedPeer
|
self.renderedPeer = renderedPeer
|
||||||
@ -410,6 +412,7 @@ final class ChatPresentationInterfaceState: Equatable {
|
|||||||
self.pinnedMessage = pinnedMessage
|
self.pinnedMessage = pinnedMessage
|
||||||
self.peerIsBlocked = peerIsBlocked
|
self.peerIsBlocked = peerIsBlocked
|
||||||
self.peerIsMuted = peerIsMuted
|
self.peerIsMuted = peerIsMuted
|
||||||
|
self.peerDiscussionId = peerDiscussionId
|
||||||
self.canReportPeer = canReportPeer
|
self.canReportPeer = canReportPeer
|
||||||
self.callsAvailable = callsAvailable
|
self.callsAvailable = callsAvailable
|
||||||
self.callsPrivate = callsPrivate
|
self.callsPrivate = callsPrivate
|
||||||
@ -523,6 +526,10 @@ final class ChatPresentationInterfaceState: Equatable {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if lhs.peerDiscussionId != rhs.peerDiscussionId {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if lhs.chatHistoryState != rhs.chatHistoryState {
|
if lhs.chatHistoryState != rhs.chatHistoryState {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -593,31 +600,31 @@ final class ChatPresentationInterfaceState: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updatedInterfaceState(_ f: (ChatInterfaceState) -> ChatInterfaceState) -> ChatPresentationInterfaceState {
|
func updatedInterfaceState(_ f: (ChatInterfaceState) -> ChatInterfaceState) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: f(self.interfaceState), chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: f(self.interfaceState), chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedPeer(_ f: (RenderedPeer?) -> RenderedPeer?) -> ChatPresentationInterfaceState {
|
func updatedPeer(_ f: (RenderedPeer?) -> RenderedPeer?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: f(self.renderedPeer), isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: f(self.renderedPeer), isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedIsNotAccessible(_ isNotAccessible: Bool) -> ChatPresentationInterfaceState {
|
func updatedIsNotAccessible(_ isNotAccessible: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedExplicitelyCanPinMessages(_ explicitelyCanPinMessages: Bool) -> ChatPresentationInterfaceState {
|
func updatedExplicitelyCanPinMessages(_ explicitelyCanPinMessages: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedIsContact(_ isContact: Bool) -> ChatPresentationInterfaceState {
|
func updatedIsContact(_ isContact: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedHasBots(_ hasBots: Bool) -> ChatPresentationInterfaceState {
|
func updatedHasBots(_ hasBots: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedIsArchived(_ isArchived: Bool) -> ChatPresentationInterfaceState {
|
func updatedIsArchived(_ isArchived: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedInputQueryResult(queryKind: ChatPresentationInputQueryKind, _ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState {
|
func updatedInputQueryResult(queryKind: ChatPresentationInputQueryKind, _ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState {
|
||||||
@ -628,103 +635,107 @@ final class ChatPresentationInterfaceState: Equatable {
|
|||||||
} else {
|
} else {
|
||||||
inputQueryResults.removeValue(forKey: queryKind)
|
inputQueryResults.removeValue(forKey: queryKind)
|
||||||
}
|
}
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedInputTextPanelState(_ f: (ChatTextInputPanelState) -> ChatTextInputPanelState) -> ChatPresentationInterfaceState {
|
func updatedInputTextPanelState(_ f: (ChatTextInputPanelState) -> ChatTextInputPanelState) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: f(self.inputTextPanelState), editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: f(self.inputTextPanelState), editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedEditMessageState(_ editMessageState: ChatEditInterfaceMessageState?) -> ChatPresentationInterfaceState {
|
func updatedEditMessageState(_ editMessageState: ChatEditInterfaceMessageState?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedRecordedMediaPreview(_ recordedMediaPreview: ChatRecordedMediaPreview?) -> ChatPresentationInterfaceState {
|
func updatedRecordedMediaPreview(_ recordedMediaPreview: ChatRecordedMediaPreview?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedInputMode(_ f: (ChatInputMode) -> ChatInputMode) -> ChatPresentationInterfaceState {
|
func updatedInputMode(_ f: (ChatInputMode) -> ChatInputMode) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: f(self.inputMode), titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: f(self.inputMode), titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedTitlePanelContext(_ f: ([ChatTitlePanelContext]) -> [ChatTitlePanelContext]) -> ChatPresentationInterfaceState {
|
func updatedTitlePanelContext(_ f: ([ChatTitlePanelContext]) -> [ChatTitlePanelContext]) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: f(self.titlePanelContexts), keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: f(self.titlePanelContexts), keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedKeyboardButtonsMessage(_ message: Message?) -> ChatPresentationInterfaceState {
|
func updatedKeyboardButtonsMessage(_ message: Message?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: message, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: message, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> ChatPresentationInterfaceState {
|
func updatedPinnedMessageId(_ pinnedMessageId: MessageId?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedPinnedMessage(_ pinnedMessage: Message?) -> ChatPresentationInterfaceState {
|
func updatedPinnedMessage(_ pinnedMessage: Message?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedPeerIsBlocked(_ peerIsBlocked: Bool) -> ChatPresentationInterfaceState {
|
func updatedPeerIsBlocked(_ peerIsBlocked: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: peerIsBlocked, peerIsMuted: self.peerIsMuted, peerDiscussionId: self.peerDiscussionId, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedPeerIsMuted(_ peerIsMuted: Bool) -> ChatPresentationInterfaceState {
|
func updatedPeerIsMuted(_ peerIsMuted: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: peerIsMuted, peerDiscussionId: self.peerDiscussionId, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updatedPeerDiscussionId(_ peerDiscussionId: PeerId?) -> ChatPresentationInterfaceState {
|
||||||
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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: peerDiscussionId, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedCanReportPeer(_ canReportPeer: Bool) -> ChatPresentationInterfaceState {
|
func updatedCanReportPeer(_ canReportPeer: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedCallsAvailable(_ callsAvailable: Bool) -> ChatPresentationInterfaceState {
|
func updatedCallsAvailable(_ callsAvailable: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedCallsPrivate(_ callsPrivate: Bool) -> ChatPresentationInterfaceState {
|
func updatedCallsPrivate(_ callsPrivate: Bool) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedBotStartPayload(_ botStartPayload: String?) -> ChatPresentationInterfaceState {
|
func updatedBotStartPayload(_ botStartPayload: String?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedChatHistoryState(_ chatHistoryState: ChatHistoryNodeHistoryState?) -> ChatPresentationInterfaceState {
|
func updatedChatHistoryState(_ chatHistoryState: ChatHistoryNodeHistoryState?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedUrlPreview(_ urlPreview: (String, TelegramMediaWebpage)?) -> ChatPresentationInterfaceState {
|
func updatedUrlPreview(_ urlPreview: (String, TelegramMediaWebpage)?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedEditingUrlPreview(_ editingUrlPreview: (String, TelegramMediaWebpage)?) -> ChatPresentationInterfaceState {
|
func updatedEditingUrlPreview(_ editingUrlPreview: (String, TelegramMediaWebpage)?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedSearch(_ search: ChatSearchData?) -> ChatPresentationInterfaceState {
|
func updatedSearch(_ search: ChatSearchData?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedSearchQuerySuggestionResult(_ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState {
|
func updatedSearchQuerySuggestionResult(_ f: (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult?) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: f(self.searchQuerySuggestionResult), chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: f(self.searchQuerySuggestionResult), chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedMode(_ mode: ChatControllerPresentationMode) -> ChatPresentationInterfaceState {
|
func updatedMode(_ mode: ChatControllerPresentationMode) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedTheme(_ theme: PresentationTheme) -> ChatPresentationInterfaceState {
|
func updatedTheme(_ theme: PresentationTheme) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedStrings(_ strings: PresentationStrings) -> ChatPresentationInterfaceState {
|
func updatedStrings(_ strings: PresentationStrings) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedDateTimeFormat(_ dateTimeFormat: PresentationDateTimeFormat) -> ChatPresentationInterfaceState {
|
func updatedDateTimeFormat(_ dateTimeFormat: PresentationDateTimeFormat) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: self.chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatedChatWallpaper(_ chatWallpaper: TelegramWallpaper) -> ChatPresentationInterfaceState {
|
func updatedChatWallpaper(_ chatWallpaper: TelegramWallpaper) -> ChatPresentationInterfaceState {
|
||||||
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, inputQueryResults: self.inputQueryResults, inputMode: self.inputMode, titlePanelContexts: self.titlePanelContexts, keyboardButtonsMessage: self.keyboardButtonsMessage, pinnedMessageId: self.pinnedMessageId, pinnedMessage: self.pinnedMessage, peerIsBlocked: self.peerIsBlocked, peerIsMuted: self.peerIsMuted, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
return ChatPresentationInterfaceState(interfaceState: self.interfaceState, chatLocation: self.chatLocation, renderedPeer: self.renderedPeer, isNotAccessible: self.isNotAccessible, explicitelyCanPinMessages: self.explicitelyCanPinMessages, isContact: self.isContact, hasBots: self.hasBots, isArchived: self.isArchived, inputTextPanelState: self.inputTextPanelState, editMessageState: self.editMessageState, recordedMediaPreview: self.recordedMediaPreview, 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, canReportPeer: self.canReportPeer, callsAvailable: self.callsAvailable, callsPrivate: self.callsPrivate, chatHistoryState: self.chatHistoryState, botStartPayload: self.botStartPayload, urlPreview: self.urlPreview, editingUrlPreview: self.editingUrlPreview, search: self.search, searchQuerySuggestionResult: self.searchQuerySuggestionResult, chatWallpaper: chatWallpaper, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, nameDisplayOrder: self.nameDisplayOrder, limitsConfiguration: self.limitsConfiguration, fontSize: self.fontSize, accountPeerId: self.accountPeerId, mode: self.mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,7 @@ final class ChatRecentActionsController: TelegramController {
|
|||||||
}, openCalendarSearch: {
|
}, openCalendarSearch: {
|
||||||
}, toggleMembersSearch: { _ in
|
}, toggleMembersSearch: { _ in
|
||||||
}, navigateToMessage: { _ in
|
}, navigateToMessage: { _ in
|
||||||
|
}, navigateToChat: { _ in
|
||||||
}, openPeerInfo: {
|
}, openPeerInfo: {
|
||||||
}, togglePeerNotifications: {
|
}, togglePeerNotifications: {
|
||||||
}, sendContextResult: { _, _ in
|
}, sendContextResult: { _, _ in
|
||||||
|
|||||||
@ -857,6 +857,67 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
|||||||
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.author, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: message.author, text: message.text, attributes: attributes, media: message.media, peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||||
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(isAdmin: false, isContact: false)), additionalContent: nil)
|
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: filterOriginalMessageFlags(message), read: true, selection: .none, attributes: ChatMessageEntryAttributes(isAdmin: false, isContact: false)), additionalContent: nil)
|
||||||
}
|
}
|
||||||
|
case let .linkedPeerUpdated(_, updated):
|
||||||
|
var peers = SimpleDictionary<PeerId, Peer>()
|
||||||
|
var author: Peer?
|
||||||
|
if let peer = self.entry.peers[self.entry.event.peerId] {
|
||||||
|
author = peer
|
||||||
|
peers[peer.id] = peer
|
||||||
|
}
|
||||||
|
var text: String = ""
|
||||||
|
var entities: [MessageTextEntity] = []
|
||||||
|
|
||||||
|
if let updated = updated {
|
||||||
|
appendAttributedText(text: self.presentationData.strings.Channel_AdminLog_MessageChangedLinkedGroup(author?.displayTitle ?? "", updated.displayTitle), generateEntities: { index in
|
||||||
|
if index == 0, let author = author {
|
||||||
|
return [.TextMention(peerId: author.id)]
|
||||||
|
} else if index == 1 {
|
||||||
|
return [.TextMention(peerId: updated.id)]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}, to: &text, entities: &entities)
|
||||||
|
} else {
|
||||||
|
appendAttributedText(text: self.presentationData.strings.Channel_AdminLog_MessageChangedUnlinkedGroup(author?.displayTitle ?? ""), generateEntities: { index in
|
||||||
|
if index == 0, let author = author {
|
||||||
|
return [.TextMention(peerId: author.id)]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}, to: &text, entities: &entities)
|
||||||
|
}
|
||||||
|
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||||
|
|
||||||
|
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||||
|
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(isAdmin: false, isContact: false)))
|
||||||
|
case let .togglePreHistoryHidden(value):
|
||||||
|
var peers = SimpleDictionary<PeerId, Peer>()
|
||||||
|
var author: Peer?
|
||||||
|
if let peer = self.entry.peers[self.entry.event.peerId] {
|
||||||
|
author = peer
|
||||||
|
peers[peer.id] = peer
|
||||||
|
}
|
||||||
|
|
||||||
|
var text: String = ""
|
||||||
|
var entities: [MessageTextEntity] = []
|
||||||
|
|
||||||
|
if !value {
|
||||||
|
appendAttributedText(text: self.presentationData.strings.Channel_AdminLog_MessageGroupPreHistoryVisible(author?.displayTitle ?? ""), generateEntities: { index in
|
||||||
|
if index == 0, let author = author {
|
||||||
|
return [.TextMention(peerId: author.id)]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}, to: &text, entities: &entities)
|
||||||
|
} else {
|
||||||
|
appendAttributedText(text: self.presentationData.strings.Channel_AdminLog_MessageGroupPreHistoryHidden(author?.displayTitle ?? ""), generateEntities: { index in
|
||||||
|
if index == 0, let author = author {
|
||||||
|
return [.TextMention(peerId: author.id)]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}, to: &text, entities: &entities)
|
||||||
|
}
|
||||||
|
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||||
|
|
||||||
|
let message = Message(stableId: self.entry.stableId, stableVersion: 0, id: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(bitPattern: self.entry.stableId)), globallyUniqueId: self.entry.event.id, groupingKey: nil, groupInfo: nil, timestamp: self.entry.event.date, flags: [.Incoming], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: author, text: "", attributes: [], media: [TelegramMediaAction(action: action)], peers: peers, associatedMessages: SimpleDictionary(), associatedMessageIds: [])
|
||||||
|
return ChatMessageItem(presentationData: self.presentationData, context: context, chatLocation: .peer(peer.id), associatedData: ChatMessageItemAssociatedData(automaticDownloadPeerType: .channel, automaticDownloadNetworkType: .cellular, isRecentActions: true), controllerInteraction: controllerInteraction, content: .message(message: message, read: true, selection: .none, attributes: ChatMessageEntryAttributes(isAdmin: false, isContact: false)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -219,8 +219,8 @@ private func createGroupEntries(presentationData: PresentationData, state: Creat
|
|||||||
return entries
|
return entries
|
||||||
}
|
}
|
||||||
|
|
||||||
public func createGroupController(context: AccountContext, peerIds: [PeerId]) -> ViewController {
|
public func createGroupController(context: AccountContext, peerIds: [PeerId], initialTitle: String? = nil, supergroup: Bool = false, completion: ((PeerId) -> Void)? = nil) -> ViewController {
|
||||||
let initialState = CreateGroupState(creating: false, editingName: .title(title: "", type: .group), avatar: nil)
|
let initialState = CreateGroupState(creating: false, editingName: .title(title: initialTitle ?? "", type: .group), avatar: nil)
|
||||||
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
||||||
let stateValue = Atomic(value: initialState)
|
let stateValue = Atomic(value: initialState)
|
||||||
let updateState: ((CreateGroupState) -> CreateGroupState) -> Void = { f in
|
let updateState: ((CreateGroupState) -> CreateGroupState) -> Void = { f in
|
||||||
@ -228,6 +228,7 @@ public func createGroupController(context: AccountContext, peerIds: [PeerId]) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
var replaceControllerImpl: ((ViewController) -> Void)?
|
var replaceControllerImpl: ((ViewController) -> Void)?
|
||||||
|
var dismissImpl: (() -> Void)?
|
||||||
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
||||||
var endEditingImpl: (() -> Void)?
|
var endEditingImpl: (() -> Void)?
|
||||||
|
|
||||||
@ -255,7 +256,16 @@ public func createGroupController(context: AccountContext, peerIds: [PeerId]) ->
|
|||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
endEditingImpl?()
|
endEditingImpl?()
|
||||||
actionsDisposable.add((createGroup(account: context.account, title: title, peerIds: peerIds)
|
|
||||||
|
let createSignal: Signal<PeerId?, CreateGroupError>
|
||||||
|
if supergroup {
|
||||||
|
createSignal = createSupergroup(account: context.account, title: title, description: nil)
|
||||||
|
|> introduceError(CreateGroupError.self)
|
||||||
|
} else {
|
||||||
|
createSignal = createGroup(account: context.account, title: title, peerIds: peerIds)
|
||||||
|
}
|
||||||
|
|
||||||
|
actionsDisposable.add((createSignal
|
||||||
|> deliverOnMainQueue
|
|> deliverOnMainQueue
|
||||||
|> afterDisposed {
|
|> afterDisposed {
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
@ -275,8 +285,14 @@ public func createGroupController(context: AccountContext, peerIds: [PeerId]) ->
|
|||||||
return mapResourceToAvatarSizes(postbox: context.account.postbox, resource: resource, representations: representations)
|
return mapResourceToAvatarSizes(postbox: context.account.postbox, resource: resource, representations: representations)
|
||||||
}).start()
|
}).start()
|
||||||
}
|
}
|
||||||
let controller = ChatController(context: context, chatLocation: .peer(peerId))
|
|
||||||
replaceControllerImpl?(controller)
|
if let completion = completion {
|
||||||
|
dismissImpl?()
|
||||||
|
completion(peerId)
|
||||||
|
} else {
|
||||||
|
let controller = ChatController(context: context, chatLocation: .peer(peerId))
|
||||||
|
replaceControllerImpl?(controller)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, error: { error in
|
}, error: { error in
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
@ -392,6 +408,11 @@ public func createGroupController(context: AccountContext, peerIds: [PeerId]) ->
|
|||||||
replaceControllerImpl = { [weak controller] value in
|
replaceControllerImpl = { [weak controller] value in
|
||||||
(controller?.navigationController as? NavigationController)?.replaceAllButRootController(value, animated: true)
|
(controller?.navigationController as? NavigationController)?.replaceAllButRootController(value, animated: true)
|
||||||
}
|
}
|
||||||
|
dismissImpl = { [weak controller] in
|
||||||
|
if let controller = controller {
|
||||||
|
(controller.navigationController as? NavigationController)?.filterController(controller, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
presentControllerImpl = { [weak controller] c, a in
|
presentControllerImpl = { [weak controller] c, a in
|
||||||
controller?.present(c, in: .window(.root), with: a)
|
controller?.present(c, in: .window(.root), with: a)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,8 +34,9 @@ private final class GroupInfoArguments {
|
|||||||
let aboutLinkAction: (TextLinkItemActionType, TextLinkItem) -> Void
|
let aboutLinkAction: (TextLinkItemActionType, TextLinkItem) -> Void
|
||||||
let openStickerPackSetup: () -> Void
|
let openStickerPackSetup: () -> Void
|
||||||
let openGroupTypeSetup: () -> Void
|
let openGroupTypeSetup: () -> Void
|
||||||
|
let openLinkedChannelSetup: () -> Void
|
||||||
|
|
||||||
init(context: AccountContext, avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext, tapAvatarAction: @escaping () -> Void, changeProfilePhoto: @escaping () -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, changeNotificationMuteSettings: @escaping () -> Void, openPreHistory: @escaping () -> Void, openSharedMedia: @escaping () -> Void, openAdministrators: @escaping () -> Void, openPermissions: @escaping () -> Void, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updateEditingDescriptionText: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addMember: @escaping () -> Void, promotePeer: @escaping (RenderedChannelParticipant) -> Void, restrictPeer: @escaping (RenderedChannelParticipant) -> Void, removePeer: @escaping (PeerId) -> Void, leave: @escaping () -> Void, displayUsernameShareMenu: @escaping (String) -> Void, displayUsernameContextMenu: @escaping (String) -> Void, displayAboutContextMenu: @escaping (String) -> Void, aboutLinkAction: @escaping (TextLinkItemActionType, TextLinkItem) -> Void, openStickerPackSetup: @escaping () -> Void, openGroupTypeSetup: @escaping () -> Void) {
|
init(context: AccountContext, avatarAndNameInfoContext: ItemListAvatarAndNameInfoItemContext, tapAvatarAction: @escaping () -> Void, changeProfilePhoto: @escaping () -> Void, pushController: @escaping (ViewController) -> Void, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, changeNotificationMuteSettings: @escaping () -> Void, openPreHistory: @escaping () -> Void, openSharedMedia: @escaping () -> Void, openAdministrators: @escaping () -> Void, openPermissions: @escaping () -> Void, updateEditingName: @escaping (ItemListAvatarAndNameInfoItemName) -> Void, updateEditingDescriptionText: @escaping (String) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, addMember: @escaping () -> Void, promotePeer: @escaping (RenderedChannelParticipant) -> Void, restrictPeer: @escaping (RenderedChannelParticipant) -> Void, removePeer: @escaping (PeerId) -> Void, leave: @escaping () -> Void, displayUsernameShareMenu: @escaping (String) -> Void, displayUsernameContextMenu: @escaping (String) -> Void, displayAboutContextMenu: @escaping (String) -> Void, aboutLinkAction: @escaping (TextLinkItemActionType, TextLinkItem) -> Void, openStickerPackSetup: @escaping () -> Void, openGroupTypeSetup: @escaping () -> Void, openLinkedChannelSetup: @escaping () -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.avatarAndNameInfoContext = avatarAndNameInfoContext
|
self.avatarAndNameInfoContext = avatarAndNameInfoContext
|
||||||
self.tapAvatarAction = tapAvatarAction
|
self.tapAvatarAction = tapAvatarAction
|
||||||
@ -61,6 +62,7 @@ private final class GroupInfoArguments {
|
|||||||
self.aboutLinkAction = aboutLinkAction
|
self.aboutLinkAction = aboutLinkAction
|
||||||
self.openStickerPackSetup = openStickerPackSetup
|
self.openStickerPackSetup = openStickerPackSetup
|
||||||
self.openGroupTypeSetup = openGroupTypeSetup
|
self.openGroupTypeSetup = openGroupTypeSetup
|
||||||
|
self.openLinkedChannelSetup = openLinkedChannelSetup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +140,7 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
case notifications(PresentationTheme, String, String)
|
case notifications(PresentationTheme, String, String)
|
||||||
case stickerPack(PresentationTheme, String, String)
|
case stickerPack(PresentationTheme, String, String)
|
||||||
case groupTypeSetup(PresentationTheme, String, String)
|
case groupTypeSetup(PresentationTheme, String, String)
|
||||||
|
case linkedChannelSetup(PresentationTheme, String, String)
|
||||||
case preHistory(PresentationTheme, String, String)
|
case preHistory(PresentationTheme, String, String)
|
||||||
case administrators(PresentationTheme, String, String)
|
case administrators(PresentationTheme, String, String)
|
||||||
case permissions(PresentationTheme, String, String)
|
case permissions(PresentationTheme, String, String)
|
||||||
@ -151,7 +154,7 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
return GroupInfoSection.info.rawValue
|
return GroupInfoSection.info.rawValue
|
||||||
case .aboutHeader, .about, .link:
|
case .aboutHeader, .about, .link:
|
||||||
return GroupInfoSection.about.rawValue
|
return GroupInfoSection.about.rawValue
|
||||||
case .groupTypeSetup, .preHistory, .stickerPack:
|
case .groupTypeSetup, .linkedChannelSetup, .preHistory, .stickerPack:
|
||||||
return GroupInfoSection.infoManagement.rawValue
|
return GroupInfoSection.infoManagement.rawValue
|
||||||
case .sharedMedia, .notifications:
|
case .sharedMedia, .notifications:
|
||||||
return GroupInfoSection.sharedMediaAndNotifications.rawValue
|
return GroupInfoSection.sharedMediaAndNotifications.rawValue
|
||||||
@ -285,6 +288,12 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
case let .linkedChannelSetup(lhsTheme, lhsTitle, lhsText):
|
||||||
|
if case let .linkedChannelSetup(rhsTheme, rhsTitle, rhsText) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsText == rhsText {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
case let .permissions(lhsTheme, lhsTitle, lhsText):
|
case let .permissions(lhsTheme, lhsTitle, lhsText):
|
||||||
if case let .permissions(rhsTheme, rhsTitle, rhsText) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsText == rhsText {
|
if case let .permissions(rhsTheme, rhsTitle, rhsText) = rhs, lhsTheme === rhsTheme, lhsTitle == rhsTitle, lhsText == rhsText {
|
||||||
return true
|
return true
|
||||||
@ -383,12 +392,14 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
return 6
|
return 6
|
||||||
case .groupTypeSetup:
|
case .groupTypeSetup:
|
||||||
return 8
|
return 8
|
||||||
case .preHistory:
|
case .linkedChannelSetup:
|
||||||
return 9
|
return 9
|
||||||
case .stickerPack:
|
case .preHistory:
|
||||||
return 10
|
return 10
|
||||||
case .notifications:
|
case .stickerPack:
|
||||||
return 11
|
return 11
|
||||||
|
case .notifications:
|
||||||
|
return 12
|
||||||
case .sharedMedia:
|
case .sharedMedia:
|
||||||
return 13
|
return 13
|
||||||
case .permissions:
|
case .permissions:
|
||||||
@ -458,6 +469,10 @@ private enum GroupInfoEntry: ItemListNodeEntry {
|
|||||||
return ItemListDisclosureItem(theme: theme, title: title, label: text, sectionId: self.section, style: .blocks, action: {
|
return ItemListDisclosureItem(theme: theme, title: title, label: text, sectionId: self.section, style: .blocks, action: {
|
||||||
arguments.openGroupTypeSetup()
|
arguments.openGroupTypeSetup()
|
||||||
})
|
})
|
||||||
|
case let .linkedChannelSetup(theme, title, text):
|
||||||
|
return ItemListDisclosureItem(theme: theme, title: title, label: text, sectionId: self.section, style: .blocks, action: {
|
||||||
|
arguments.openLinkedChannelSetup()
|
||||||
|
})
|
||||||
case let .groupDescriptionSetup(theme, placeholder, text):
|
case let .groupDescriptionSetup(theme, placeholder, text):
|
||||||
return ItemListMultilineInputItem(theme: theme, text: text, placeholder: placeholder, maxLength: ItemListMultilineInputItemTextLimit(value: 255, display: true), sectionId: self.section, style: .blocks, textUpdated: { updatedText in
|
return ItemListMultilineInputItem(theme: theme, text: text, placeholder: placeholder, maxLength: ItemListMultilineInputItemTextLimit(value: 255, display: true), sectionId: self.section, style: .blocks, textUpdated: { updatedText in
|
||||||
arguments.updateEditingDescriptionText(updatedText)
|
arguments.updateEditingDescriptionText(updatedText)
|
||||||
@ -766,6 +781,15 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa
|
|||||||
if isCreator {
|
if isCreator {
|
||||||
if cachedChannelData.flags.contains(.canChangeUsername) {
|
if cachedChannelData.flags.contains(.canChangeUsername) {
|
||||||
entries.append(GroupInfoEntry.groupTypeSetup(presentationData.theme, presentationData.strings.GroupInfo_GroupType, isPublic ? presentationData.strings.Channel_Setup_TypePublic : presentationData.strings.Channel_Setup_TypePrivate))
|
entries.append(GroupInfoEntry.groupTypeSetup(presentationData.theme, presentationData.strings.GroupInfo_GroupType, isPublic ? presentationData.strings.Channel_Setup_TypePublic : presentationData.strings.Channel_Setup_TypePrivate))
|
||||||
|
if let linkedDiscussionPeerId = cachedChannelData.linkedDiscussionPeerId, let peer = view.peers[linkedDiscussionPeerId] {
|
||||||
|
let peerTitle: String
|
||||||
|
if let addressName = peer.addressName, !addressName.isEmpty {
|
||||||
|
peerTitle = "@\(addressName)"
|
||||||
|
} else {
|
||||||
|
peerTitle = peer.displayTitle
|
||||||
|
}
|
||||||
|
entries.append(GroupInfoEntry.linkedChannelSetup(presentationData.theme, presentationData.strings.Group_LinkedChannel, peerTitle))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !isPublic {
|
if !isPublic {
|
||||||
entries.append(GroupInfoEntry.preHistory(presentationData.theme, presentationData.strings.GroupInfo_GroupHistory, cachedChannelData.flags.contains(.preHistoryEnabled) ? presentationData.strings.GroupInfo_GroupHistoryVisible : presentationData.strings.GroupInfo_GroupHistoryHidden))
|
entries.append(GroupInfoEntry.preHistory(presentationData.theme, presentationData.strings.GroupInfo_GroupHistory, cachedChannelData.flags.contains(.preHistoryEnabled) ? presentationData.strings.GroupInfo_GroupHistoryVisible : presentationData.strings.GroupInfo_GroupHistoryHidden))
|
||||||
@ -1239,7 +1263,7 @@ public func groupInfoController(context: AccountContext, peerId originalPeerId:
|
|||||||
let peerViewSignal = actualPeerId.get()
|
let peerViewSignal = actualPeerId.get()
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|> mapToSignal { peerId -> Signal<PeerView, NoError> in
|
|> mapToSignal { peerId -> Signal<PeerView, NoError> in
|
||||||
return context.account.viewTracker.peerView(peerId)
|
return context.account.viewTracker.peerView(peerId, updateData: true)
|
||||||
}
|
}
|
||||||
peerView.set(peerViewSignal)
|
peerView.set(peerViewSignal)
|
||||||
|
|
||||||
@ -1857,6 +1881,12 @@ public func groupInfoController(context: AccountContext, peerId originalPeerId:
|
|||||||
upgradedToSupergroupImpl?(updatedPeerId, f)
|
upgradedToSupergroupImpl?(updatedPeerId, f)
|
||||||
}), ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet))
|
}), ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet))
|
||||||
})
|
})
|
||||||
|
}, openLinkedChannelSetup: {
|
||||||
|
let _ = (peerView.get()
|
||||||
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue).start(next: { peerView in
|
||||||
|
pushControllerImpl?(channelDiscussionGroupSetupController(context: context, peerId: peerView.peerId))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
let loadMoreControl = Atomic<(PeerId, PeerChannelMemberCategoryControl)?>(value: nil)
|
let loadMoreControl = Atomic<(PeerId, PeerChannelMemberCategoryControl)?>(value: nil)
|
||||||
|
|||||||
@ -330,6 +330,7 @@ public class PeerMediaCollectionController: TelegramController {
|
|||||||
}, openCalendarSearch: {
|
}, openCalendarSearch: {
|
||||||
}, toggleMembersSearch: { _ in
|
}, toggleMembersSearch: { _ in
|
||||||
}, navigateToMessage: { _ in
|
}, navigateToMessage: { _ in
|
||||||
|
}, navigateToChat: { _ in
|
||||||
}, openPeerInfo: {
|
}, openPeerInfo: {
|
||||||
}, togglePeerNotifications: {
|
}, togglePeerNotifications: {
|
||||||
}, sendContextResult: { _, _ in
|
}, sendContextResult: { _, _ in
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -343,7 +343,7 @@ private func stringForSelectiveSettings(strings: PresentationStrings, settings:
|
|||||||
private func privacyAndSecurityControllerEntries(presentationData: PresentationData, state: PrivacyAndSecurityControllerState, privacySettings: AccountPrivacySettings?, accessChallengeData: PostboxAccessChallengeData, blockedPeerCount: Int?, activeSessionsCount: Int, hasTwoStepAuth: Bool) -> [PrivacyAndSecurityEntry] {
|
private func privacyAndSecurityControllerEntries(presentationData: PresentationData, state: PrivacyAndSecurityControllerState, privacySettings: AccountPrivacySettings?, accessChallengeData: PostboxAccessChallengeData, blockedPeerCount: Int?, activeSessionsCount: Int, hasTwoStepAuth: Bool) -> [PrivacyAndSecurityEntry] {
|
||||||
var entries: [PrivacyAndSecurityEntry] = []
|
var entries: [PrivacyAndSecurityEntry] = []
|
||||||
|
|
||||||
entries.append(.blockedPeers(presentationData.theme, presentationData.strings.Settings_BlockedUsers, blockedPeerCount == nil ? "" : "\(blockedPeerCount!)"))
|
entries.append(.blockedPeers(presentationData.theme, presentationData.strings.Settings_BlockedUsers, blockedPeerCount == nil ? "" : (blockedPeerCount == 0 ? presentationData.strings.PrivacySettings_BlockedPeersEmpty : "\(blockedPeerCount!)")))
|
||||||
entries.append(.activeSessions(presentationData.theme, presentationData.strings.PrivacySettings_AuthSessions, activeSessionsCount == 0 ? "" : "\(activeSessionsCount)"))
|
entries.append(.activeSessions(presentationData.theme, presentationData.strings.PrivacySettings_AuthSessions, activeSessionsCount == 0 ? "" : "\(activeSessionsCount)"))
|
||||||
|
|
||||||
let passcodeValue: String
|
let passcodeValue: String
|
||||||
@ -617,7 +617,7 @@ public func privacyAndSecurityController(context: AccountContext, initialSetting
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}, openTwoStepVerification: {
|
}, openTwoStepVerification: {
|
||||||
pushControllerImpl?(twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: true, data: nil)))
|
pushControllerImpl?(twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: false, data: nil)))
|
||||||
}, openActiveSessions: {
|
}, openActiveSessions: {
|
||||||
pushControllerImpl?(recentSessionsController(context: context, activeSessionsContext: activeSessionsContext))
|
pushControllerImpl?(recentSessionsController(context: context, activeSessionsContext: activeSessionsContext))
|
||||||
}, setupAccountAutoremove: {
|
}, setupAccountAutoremove: {
|
||||||
|
|||||||
Binary file not shown.
@ -499,7 +499,7 @@ private func selectivePrivacySettingsControllerEntries(presentationData: Present
|
|||||||
enableForText = presentationData.strings.Privacy_GroupsAndChannels_AlwaysAllow
|
enableForText = presentationData.strings.Privacy_GroupsAndChannels_AlwaysAllow
|
||||||
case .phoneNumber:
|
case .phoneNumber:
|
||||||
settingTitle = presentationData.strings.PrivacyPhoneNumberSettings_WhoCanSeeMyPhoneNumber
|
settingTitle = presentationData.strings.PrivacyPhoneNumberSettings_WhoCanSeeMyPhoneNumber
|
||||||
settingInfoText = presentationData.strings.PrivacyLastSeenSettings_CustomHelp
|
settingInfoText = presentationData.strings.PrivacyPhoneNumberSettings_CustomHelp
|
||||||
disableForText = presentationData.strings.PrivacyLastSeenSettings_NeverShareWith
|
disableForText = presentationData.strings.PrivacyLastSeenSettings_NeverShareWith
|
||||||
enableForText = presentationData.strings.PrivacyLastSeenSettings_AlwaysShareWith
|
enableForText = presentationData.strings.PrivacyLastSeenSettings_AlwaysShareWith
|
||||||
}
|
}
|
||||||
|
|||||||
@ -274,8 +274,8 @@ private enum SettingsEntry: ItemListNodeEntry {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case let .privacyAndSecurity(lhsTheme, lhsImage, lhsText, _):
|
case let .privacyAndSecurity(lhsTheme, lhsImage, lhsText, lhsSettings):
|
||||||
if case let .privacyAndSecurity(rhsTheme, rhsImage, rhsText, _) = rhs, lhsTheme === rhsTheme, lhsImage === rhsImage, lhsText == rhsText {
|
if case let .privacyAndSecurity(rhsTheme, rhsImage, rhsText, rhsSettings) = rhs, lhsTheme === rhsTheme, lhsImage === rhsImage, lhsText == rhsText, lhsSettings == rhsSettings {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@ -277,7 +277,8 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode:
|
|||||||
} else {
|
} else {
|
||||||
dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.access(configuration: nil))
|
dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.access(configuration: nil))
|
||||||
|> then(remoteDataPromise.get()))
|
|> then(remoteDataPromise.get()))
|
||||||
remoteDataPromise.set(twoStepVerificationConfiguration(account: context.account) |> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil)) })
|
remoteDataPromise.set(twoStepVerificationConfiguration(account: context.account)
|
||||||
|
|> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil)) })
|
||||||
}
|
}
|
||||||
case let .manage(password, email, pendingEmail, hasSecureValues):
|
case let .manage(password, email, pendingEmail, hasSecureValues):
|
||||||
dataPromise.set(.single(.manage(password: password, emailSet: !email.isEmpty, pendingEmail: pendingEmail, hasSecureValues: hasSecureValues)))
|
dataPromise.set(.single(.manage(password: password, emailSet: !email.isEmpty, pendingEmail: pendingEmail, hasSecureValues: hasSecureValues)))
|
||||||
|
|||||||
@ -618,7 +618,7 @@ private func userInfoEntries(account: Account, presentationData: PresentationDat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
entries.append(UserInfoEntry.requestPhoneNumber(presentationData.theme, "phone", "Request Number"))
|
//entries.append(UserInfoEntry.requestPhoneNumber(presentationData.theme, "phone", "Request Number"))
|
||||||
}
|
}
|
||||||
|
|
||||||
let aboutTitle: String
|
let aboutTitle: String
|
||||||
@ -796,7 +796,7 @@ public func userInfoController(context: AccountContext, peerId: PeerId, mode: Us
|
|||||||
let cachedAvatarEntries = Atomic<Promise<[AvatarGalleryEntry]>?>(value: nil)
|
let cachedAvatarEntries = Atomic<Promise<[AvatarGalleryEntry]>?>(value: nil)
|
||||||
|
|
||||||
let peerView = Promise<(PeerView, CachedPeerData?)>()
|
let peerView = Promise<(PeerView, CachedPeerData?)>()
|
||||||
peerView.set(context.account.viewTracker.peerView(peerId) |> mapToSignal({ view -> Signal<(PeerView, CachedPeerData?), NoError> in
|
peerView.set(context.account.viewTracker.peerView(peerId, updateData: true) |> mapToSignal({ view -> Signal<(PeerView, CachedPeerData?), NoError> in
|
||||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||||
if let peer = peerViewMainPeer(view) {
|
if let peer = peerViewMainPeer(view) {
|
||||||
return context.account.viewTracker.peerView(peer.id) |> map({ secretChatView -> (PeerView, CachedPeerData?) in
|
return context.account.viewTracker.peerView(peer.id) |> map({ secretChatView -> (PeerView, CachedPeerData?) in
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user