mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-15 18:59:54 +00:00
Monoforums
This commit is contained in:
parent
d2d16117f2
commit
0d56fcc294
@ -212,7 +212,7 @@ public final class SelectablePeerNode: ASDisplayNode {
|
|||||||
public func setup(accountPeerId: EnginePeer.Id, postbox: Postbox, network: Network, energyUsageSettings: EnergyUsageSettings, contentSettings: ContentSettings, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, resolveInlineStickers: @escaping ([Int64]) -> Signal<[Int64: TelegramMediaFile], NoError>, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer, requiresPremiumForMessaging: Bool, requiresStars: Int64? = nil, customTitle: String? = nil, iconId: Int64? = nil, iconColor: Int32? = nil, online: Bool = false, numberOfLines: Int = 2, synchronousLoad: Bool) {
|
public func setup(accountPeerId: EnginePeer.Id, postbox: Postbox, network: Network, energyUsageSettings: EnergyUsageSettings, contentSettings: ContentSettings, animationCache: AnimationCache, animationRenderer: MultiAnimationRenderer, resolveInlineStickers: @escaping ([Int64]) -> Signal<[Int64: TelegramMediaFile], NoError>, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer, requiresPremiumForMessaging: Bool, requiresStars: Int64? = nil, customTitle: String? = nil, iconId: Int64? = nil, iconColor: Int32? = nil, online: Bool = false, numberOfLines: Int = 2, synchronousLoad: Bool) {
|
||||||
let isFirstTime = self.peer == nil
|
let isFirstTime = self.peer == nil
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
guard let mainPeer = peer.chatMainPeer else {
|
guard let mainPeer = peer.chatOrMonoforumMainPeer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,8 +226,10 @@ public final class SelectablePeerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var isForum = false
|
var isForum = false
|
||||||
if let peer = peer.chatMainPeer, case let .channel(channel) = peer, channel.isForumOrMonoForum {
|
var isMonoforum = false
|
||||||
isForum = true
|
if let peer = peer.chatMainPeer, case let .channel(channel) = peer {
|
||||||
|
isForum = channel.isForum
|
||||||
|
isMonoforum = channel.isMonoForum
|
||||||
}
|
}
|
||||||
|
|
||||||
let text: String
|
let text: String
|
||||||
@ -246,7 +248,15 @@ public final class SelectablePeerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
self.textNode.maximumNumberOfLines = numberOfLines
|
self.textNode.maximumNumberOfLines = numberOfLines
|
||||||
self.textNode.attributedText = NSAttributedString(string: customTitle ?? text, font: textFont, textColor: self.currentSelected ? self.theme.selectedTextColor : defaultColor, paragraphAlignment: .center)
|
self.textNode.attributedText = NSAttributedString(string: customTitle ?? text, font: textFont, textColor: self.currentSelected ? self.theme.selectedTextColor : defaultColor, paragraphAlignment: .center)
|
||||||
self.avatarNode.setPeer(accountPeerId: accountPeerId, postbox: postbox, network: network, contentSettings: contentSettings, theme: theme, peer: mainPeer, overrideImage: overrideImage, emptyColor: self.theme.avatarPlaceholderColor, clipStyle: isForum ? .roundedRect : .round, synchronousLoad: synchronousLoad)
|
let clipStyle: AvatarNodeClipStyle
|
||||||
|
if isMonoforum {
|
||||||
|
clipStyle = .bubble
|
||||||
|
} else if isForum {
|
||||||
|
clipStyle = .roundedRect
|
||||||
|
} else {
|
||||||
|
clipStyle = .round
|
||||||
|
}
|
||||||
|
self.avatarNode.setPeer(accountPeerId: accountPeerId, postbox: postbox, network: network, contentSettings: contentSettings, theme: theme, peer: mainPeer, overrideImage: overrideImage, emptyColor: self.theme.avatarPlaceholderColor, clipStyle: clipStyle, synchronousLoad: synchronousLoad)
|
||||||
|
|
||||||
if let requiresStars {
|
if let requiresStars {
|
||||||
let avatarBadgeOutline: UIImageView
|
let avatarBadgeOutline: UIImageView
|
||||||
|
|||||||
@ -760,9 +760,14 @@ final class ShareControllerNode: ViewControllerTracingNode, ASScrollViewDelegate
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isMonoforum = false
|
||||||
|
if case let .channel(channel) = mainPeer {
|
||||||
|
isMonoforum = channel.isMonoForum
|
||||||
|
}
|
||||||
|
|
||||||
var didPresent = false
|
var didPresent = false
|
||||||
var presentImpl: (() -> Void)?
|
var presentImpl: (() -> Void)?
|
||||||
let threads = threadList(accountPeerId: context.accountPeerId, postbox: context.stateManager.postbox, peerId: mainPeer.id)
|
let threads = threadList(accountPeerId: context.accountPeerId, postbox: context.stateManager.postbox, peerId: mainPeer.id, isMonoforum: isMonoforum)
|
||||||
|> deliverOnMainQueue
|
|> deliverOnMainQueue
|
||||||
|> beforeNext { _ in
|
|> beforeNext { _ in
|
||||||
if !didPresent {
|
if !didPresent {
|
||||||
@ -1933,78 +1938,162 @@ private final class ShareContextReferenceContentSource: ContextReferenceContentS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func threadList(accountPeerId: EnginePeer.Id, postbox: Postbox, peerId: EnginePeer.Id) -> Signal<EngineChatList, NoError> {
|
private func threadList(accountPeerId: EnginePeer.Id, postbox: Postbox, peerId: EnginePeer.Id, isMonoforum: Bool) -> Signal<EngineChatList, NoError> {
|
||||||
let viewKey: PostboxViewKey = .messageHistoryThreadIndex(
|
if isMonoforum {
|
||||||
id: peerId,
|
let viewKey: PostboxViewKey = .savedMessagesIndex(peerId: peerId)
|
||||||
summaryComponents: ChatListEntrySummaryComponents(
|
let interfaceStateKey: PostboxViewKey = .chatInterfaceState(peerId: peerId)
|
||||||
components: [:]
|
|
||||||
)
|
return postbox.combinedView(keys: [viewKey, interfaceStateKey])
|
||||||
)
|
|> map { views -> EngineChatList in
|
||||||
|
guard let view = views.views[viewKey] as? MessageHistorySavedMessagesIndexView else {
|
||||||
return postbox.combinedView(keys: [viewKey])
|
preconditionFailure()
|
||||||
|> mapToSignal { view -> Signal<CombinedView, NoError> in
|
}
|
||||||
return postbox.transaction { transaction -> CombinedView in
|
|
||||||
if let peer = transaction.getPeer(accountPeerId) {
|
var draft: EngineChatList.Draft?
|
||||||
transaction.updatePeersInternal([peer]) { current, _ in
|
if let interfaceStateView = views.views[interfaceStateKey] as? ChatInterfaceStateView {
|
||||||
return current ?? peer
|
if let embeddedState = interfaceStateView.value, let _ = embeddedState.overrideChatTimestamp {
|
||||||
|
if let opaqueState = _internal_decodeStoredChatInterfaceState(state: embeddedState) {
|
||||||
|
if let text = opaqueState.synchronizeableInputState?.text {
|
||||||
|
draft = EngineChatList.Draft(text: text, entities: opaqueState.synchronizeableInputState?.entities ?? [])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return view
|
|
||||||
}
|
var items: [EngineChatList.Item] = []
|
||||||
}
|
for item in view.items {
|
||||||
|> map { views -> EngineChatList in
|
guard let sourcePeer = item.peer else {
|
||||||
guard let view = views.views[viewKey] as? MessageHistoryThreadIndexView else {
|
continue
|
||||||
preconditionFailure()
|
}
|
||||||
}
|
|
||||||
|
let sourceId = PeerId(item.id)
|
||||||
var items: [EngineChatList.Item] = []
|
|
||||||
for item in view.items {
|
var messages: [EngineMessage] = []
|
||||||
guard let peer = view.peer else {
|
if let topMessage = item.topMessage {
|
||||||
continue
|
messages.append(EngineMessage(topMessage))
|
||||||
}
|
}
|
||||||
guard let data = item.info.get(MessageHistoryThreadData.self) else {
|
|
||||||
continue
|
let mappedMessageIndex = MessageIndex(id: MessageId(peerId: sourceId, namespace: item.index.id.namespace, id: item.index.id.id), timestamp: item.index.timestamp)
|
||||||
|
|
||||||
|
let readCounters = EnginePeerReadCounters(state: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 0, maxKnownId: 0, count: Int32(item.unreadCount), markedUnread: item.markedUnread))]), isMuted: false)
|
||||||
|
|
||||||
|
var itemDraft: EngineChatList.Draft?
|
||||||
|
if let embeddedState = item.embeddedInterfaceState, let _ = embeddedState.overrideChatTimestamp {
|
||||||
|
if let opaqueState = _internal_decodeStoredChatInterfaceState(state: embeddedState) {
|
||||||
|
if let text = opaqueState.synchronizeableInputState?.text {
|
||||||
|
itemDraft = EngineChatList.Draft(text: text, entities: opaqueState.synchronizeableInputState?.entities ?? [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
items.append(EngineChatList.Item(
|
||||||
|
id: .chatList(sourceId),
|
||||||
|
index: .chatList(ChatListIndex(pinningIndex: item.pinnedIndex.flatMap(UInt16.init), messageIndex: mappedMessageIndex)),
|
||||||
|
messages: messages,
|
||||||
|
readCounters: readCounters,
|
||||||
|
isMuted: false,
|
||||||
|
draft: sourceId == accountPeerId ? draft : itemDraft,
|
||||||
|
threadData: nil,
|
||||||
|
renderedPeer: EngineRenderedPeer(peer: EnginePeer(sourcePeer)),
|
||||||
|
presence: nil,
|
||||||
|
hasUnseenMentions: false,
|
||||||
|
hasUnseenReactions: false,
|
||||||
|
forumTopicData: nil,
|
||||||
|
topForumTopicItems: [],
|
||||||
|
hasFailed: false,
|
||||||
|
isContact: false,
|
||||||
|
autoremoveTimeout: nil,
|
||||||
|
storyStats: nil,
|
||||||
|
displayAsTopicList: false,
|
||||||
|
isPremiumRequiredToMessage: false,
|
||||||
|
mediaDraftContentType: nil
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
let pinnedIndex: EngineChatList.Item.PinnedIndex
|
let list = EngineChatList(
|
||||||
if let index = item.pinnedIndex {
|
items: items.reversed(),
|
||||||
pinnedIndex = .index(index)
|
groupItems: [],
|
||||||
} else {
|
additionalItems: [],
|
||||||
pinnedIndex = .none
|
hasEarlier: false,
|
||||||
}
|
hasLater: false,
|
||||||
|
isLoading: view.isLoading
|
||||||
|
)
|
||||||
|
|
||||||
items.append(EngineChatList.Item(
|
return list
|
||||||
id: .forum(item.id),
|
|
||||||
index: .forum(pinnedIndex: pinnedIndex, timestamp: item.index.timestamp, threadId: item.id, namespace: item.index.id.namespace, id: item.index.id.id),
|
|
||||||
messages: item.topMessage.flatMap { [EngineMessage($0)] } ?? [],
|
|
||||||
readCounters: nil,
|
|
||||||
isMuted: false,
|
|
||||||
draft: nil,
|
|
||||||
threadData: data,
|
|
||||||
renderedPeer: EngineRenderedPeer(peer: EnginePeer(peer)),
|
|
||||||
presence: nil,
|
|
||||||
hasUnseenMentions: false,
|
|
||||||
hasUnseenReactions: false,
|
|
||||||
forumTopicData: nil,
|
|
||||||
topForumTopicItems: [],
|
|
||||||
hasFailed: false,
|
|
||||||
isContact: false,
|
|
||||||
autoremoveTimeout: nil,
|
|
||||||
storyStats: nil,
|
|
||||||
displayAsTopicList: false,
|
|
||||||
isPremiumRequiredToMessage: false,
|
|
||||||
mediaDraftContentType: nil
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
let list = EngineChatList(
|
let viewKey: PostboxViewKey = .messageHistoryThreadIndex(
|
||||||
items: items,
|
id: peerId,
|
||||||
groupItems: [],
|
summaryComponents: ChatListEntrySummaryComponents(
|
||||||
additionalItems: [],
|
components: [:]
|
||||||
hasEarlier: false,
|
)
|
||||||
hasLater: false,
|
|
||||||
isLoading: view.isLoading
|
|
||||||
)
|
)
|
||||||
return list
|
|
||||||
|
return postbox.combinedView(keys: [viewKey])
|
||||||
|
|> mapToSignal { view -> Signal<CombinedView, NoError> in
|
||||||
|
return postbox.transaction { transaction -> CombinedView in
|
||||||
|
if let peer = transaction.getPeer(accountPeerId) {
|
||||||
|
transaction.updatePeersInternal([peer]) { current, _ in
|
||||||
|
return current ?? peer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> map { views -> EngineChatList in
|
||||||
|
guard let view = views.views[viewKey] as? MessageHistoryThreadIndexView else {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
|
||||||
|
var items: [EngineChatList.Item] = []
|
||||||
|
for item in view.items {
|
||||||
|
guard let peer = view.peer else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
guard let data = item.info.get(MessageHistoryThreadData.self) else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
let pinnedIndex: EngineChatList.Item.PinnedIndex
|
||||||
|
if let index = item.pinnedIndex {
|
||||||
|
pinnedIndex = .index(index)
|
||||||
|
} else {
|
||||||
|
pinnedIndex = .none
|
||||||
|
}
|
||||||
|
|
||||||
|
items.append(EngineChatList.Item(
|
||||||
|
id: .forum(item.id),
|
||||||
|
index: .forum(pinnedIndex: pinnedIndex, timestamp: item.index.timestamp, threadId: item.id, namespace: item.index.id.namespace, id: item.index.id.id),
|
||||||
|
messages: item.topMessage.flatMap { [EngineMessage($0)] } ?? [],
|
||||||
|
readCounters: nil,
|
||||||
|
isMuted: false,
|
||||||
|
draft: nil,
|
||||||
|
threadData: data,
|
||||||
|
renderedPeer: EngineRenderedPeer(peer: EnginePeer(peer)),
|
||||||
|
presence: nil,
|
||||||
|
hasUnseenMentions: false,
|
||||||
|
hasUnseenReactions: false,
|
||||||
|
forumTopicData: nil,
|
||||||
|
topForumTopicItems: [],
|
||||||
|
hasFailed: false,
|
||||||
|
isContact: false,
|
||||||
|
autoremoveTimeout: nil,
|
||||||
|
storyStats: nil,
|
||||||
|
displayAsTopicList: false,
|
||||||
|
isPremiumRequiredToMessage: false,
|
||||||
|
mediaDraftContentType: nil
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
let list = EngineChatList(
|
||||||
|
items: items,
|
||||||
|
groupItems: [],
|
||||||
|
additionalItems: [],
|
||||||
|
hasEarlier: false,
|
||||||
|
hasLater: false,
|
||||||
|
isLoading: view.isLoading
|
||||||
|
)
|
||||||
|
return list
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,14 +16,14 @@ final class ShareControllerInteraction {
|
|||||||
var selectedPeerIds = Set<EnginePeer.Id>()
|
var selectedPeerIds = Set<EnginePeer.Id>()
|
||||||
var selectedPeers: [EngineRenderedPeer] = []
|
var selectedPeers: [EngineRenderedPeer] = []
|
||||||
|
|
||||||
var selectedTopics: [EnginePeer.Id: (Int64, MessageHistoryThreadData)] = [:]
|
var selectedTopics: [EnginePeer.Id: (Int64, MessageHistoryThreadData?)] = [:]
|
||||||
|
|
||||||
let togglePeer: (EngineRenderedPeer, Bool) -> Void
|
let togglePeer: (EngineRenderedPeer, Bool) -> Void
|
||||||
let selectTopic: (EngineRenderedPeer, Int64, MessageHistoryThreadData) -> Void
|
let selectTopic: (EngineRenderedPeer, Int64, MessageHistoryThreadData?) -> Void
|
||||||
let shareStory: (() -> Void)?
|
let shareStory: (() -> Void)?
|
||||||
let disabledPeerSelected: (EngineRenderedPeer) -> Void
|
let disabledPeerSelected: (EngineRenderedPeer) -> Void
|
||||||
|
|
||||||
init(togglePeer: @escaping (EngineRenderedPeer, Bool) -> Void, selectTopic: @escaping (EngineRenderedPeer, Int64, MessageHistoryThreadData) -> Void, shareStory: (() -> Void)?, disabledPeerSelected: @escaping (EngineRenderedPeer) -> Void) {
|
init(togglePeer: @escaping (EngineRenderedPeer, Bool) -> Void, selectTopic: @escaping (EngineRenderedPeer, Int64, MessageHistoryThreadData?) -> Void, shareStory: (() -> Void)?, disabledPeerSelected: @escaping (EngineRenderedPeer) -> Void) {
|
||||||
self.togglePeer = togglePeer
|
self.togglePeer = togglePeer
|
||||||
self.selectTopic = selectTopic
|
self.selectTopic = selectTopic
|
||||||
self.shareStory = shareStory
|
self.shareStory = shareStory
|
||||||
|
|||||||
@ -12,22 +12,25 @@ import AccountContext
|
|||||||
import ShimmerEffect
|
import ShimmerEffect
|
||||||
import ComponentFlow
|
import ComponentFlow
|
||||||
import EmojiStatusComponent
|
import EmojiStatusComponent
|
||||||
|
import AvatarNode
|
||||||
|
|
||||||
final class ShareTopicGridItem: GridItem {
|
final class ShareTopicGridItem: GridItem {
|
||||||
let environment: ShareControllerEnvironment
|
let environment: ShareControllerEnvironment
|
||||||
let context: ShareControllerAccountContext
|
let context: ShareControllerAccountContext
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
|
let basePeer: EnginePeer
|
||||||
let peer: EngineRenderedPeer?
|
let peer: EngineRenderedPeer?
|
||||||
let id: Int64
|
let id: Int64
|
||||||
let threadInfo: MessageHistoryThreadData
|
let threadInfo: MessageHistoryThreadData?
|
||||||
let controllerInteraction: ShareControllerInteraction
|
let controllerInteraction: ShareControllerInteraction
|
||||||
|
|
||||||
let section: GridSection?
|
let section: GridSection?
|
||||||
|
|
||||||
init(environment: ShareControllerEnvironment, context: ShareControllerAccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, id: Int64, threadInfo: MessageHistoryThreadData, controllerInteraction: ShareControllerInteraction) {
|
init(environment: ShareControllerEnvironment, context: ShareControllerAccountContext, theme: PresentationTheme, strings: PresentationStrings, basePeer: EnginePeer, peer: EngineRenderedPeer?, id: Int64, threadInfo: MessageHistoryThreadData?, controllerInteraction: ShareControllerInteraction) {
|
||||||
self.environment = environment
|
self.environment = environment
|
||||||
self.context = context
|
self.context = context
|
||||||
|
self.basePeer = basePeer
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
@ -52,6 +55,7 @@ final class ShareTopicGridItemNode: GridItemNode {
|
|||||||
|
|
||||||
private let iconView: ComponentView<Empty>
|
private let iconView: ComponentView<Empty>
|
||||||
private let textNode: ImmediateTextNode
|
private let textNode: ImmediateTextNode
|
||||||
|
private var avatarNode: AvatarNode?
|
||||||
|
|
||||||
private var placeholderNode: ShimmerEffectNode?
|
private var placeholderNode: ShimmerEffectNode?
|
||||||
private var absoluteLocation: (CGRect, CGSize)?
|
private var absoluteLocation: (CGRect, CGSize)?
|
||||||
@ -80,7 +84,11 @@ final class ShareTopicGridItemNode: GridItemNode {
|
|||||||
|
|
||||||
@objc private func tapped() {
|
@objc private func tapped() {
|
||||||
if let item = self.currentItem, let peer = item.peer {
|
if let item = self.currentItem, let peer = item.peer {
|
||||||
item.controllerInteraction.selectTopic(peer, item.id, item.threadInfo)
|
if let threadInfo = item.threadInfo {
|
||||||
|
item.controllerInteraction.selectTopic(peer, item.id, threadInfo)
|
||||||
|
} else {
|
||||||
|
item.controllerInteraction.selectTopic(EngineRenderedPeer(peer: item.basePeer), item.id, nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,40 +108,59 @@ final class ShareTopicGridItemNode: GridItemNode {
|
|||||||
}
|
}
|
||||||
self.currentItem = item
|
self.currentItem = item
|
||||||
|
|
||||||
self.textNode.attributedText = NSAttributedString(string: item.threadInfo.info.title, font: Font.regular(11.0), textColor: item.theme.actionSheet.primaryTextColor)
|
if let threadInfo = item.threadInfo {
|
||||||
|
self.textNode.attributedText = NSAttributedString(string: threadInfo.info.title, font: Font.regular(11.0), textColor: item.theme.actionSheet.primaryTextColor)
|
||||||
|
|
||||||
|
let iconContent: EmojiStatusComponent.Content
|
||||||
|
if let fileId = threadInfo.info.icon {
|
||||||
|
iconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 96.0, height: 96.0), placeholderColor: item.theme.actionSheet.disabledActionTextColor, themeColor: item.theme.actionSheet.primaryTextColor, loopMode: .count(0))
|
||||||
|
} else {
|
||||||
|
iconContent = .topic(title: String(threadInfo.info.title.prefix(1)), color: threadInfo.info.iconColor, size: CGSize(width: 64.0, height: 64.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
let iconSize = self.iconView.update(
|
||||||
|
transition: .easeInOut(duration: 0.2),
|
||||||
|
component: AnyComponent(EmojiStatusComponent(
|
||||||
|
postbox: item.context.stateManager.postbox,
|
||||||
|
energyUsageSettings: item.environment.energyUsageSettings,
|
||||||
|
resolveInlineStickers: item.context.resolveInlineStickers,
|
||||||
|
animationCache: item.context.animationCache,
|
||||||
|
animationRenderer: item.context.animationRenderer,
|
||||||
|
content: iconContent,
|
||||||
|
isVisibleForAnimations: true,
|
||||||
|
action: nil
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: 54.0, height: 54.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
if let iconComponentView = self.iconView.view {
|
||||||
|
if iconComponentView.superview == nil {
|
||||||
|
self.view.addSubview(iconComponentView)
|
||||||
|
}
|
||||||
|
iconComponentView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - iconSize.width) / 2.0), y: 7.0), size: iconSize)
|
||||||
|
}
|
||||||
|
} else if let peer = item.peer, let mainPeer = peer.chatMainPeer {
|
||||||
|
self.textNode.attributedText = NSAttributedString(string: mainPeer.compactDisplayTitle, font: Font.regular(11.0), textColor: item.theme.actionSheet.primaryTextColor)
|
||||||
|
|
||||||
|
let avatarNode: AvatarNode
|
||||||
|
if let current = self.avatarNode {
|
||||||
|
avatarNode = current
|
||||||
|
} else {
|
||||||
|
avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 12.0))
|
||||||
|
self.avatarNode = avatarNode
|
||||||
|
self.addSubnode(avatarNode)
|
||||||
|
}
|
||||||
|
let iconSize = CGSize(width: 54.0, height: 54.0)
|
||||||
|
avatarNode.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - iconSize.width) / 2.0), y: 7.0), size: iconSize)
|
||||||
|
avatarNode.updateSize(size: iconSize)
|
||||||
|
|
||||||
|
avatarNode.setPeer(accountPeerId: item.context.accountPeerId, postbox: item.context.stateManager.postbox, network: item.context.stateManager.network, contentSettings: ContentSettings.default, theme: item.theme, peer: mainPeer, overrideImage: nil, emptyColor: item.theme.list.mediaPlaceholderColor, clipStyle: .round, synchronousLoad: false)
|
||||||
|
}
|
||||||
|
|
||||||
let textSize = self.textNode.updateLayout(size)
|
let textSize = self.textNode.updateLayout(size)
|
||||||
let textFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: 4.0 + 60.0 + 4.0), size: textSize)
|
let textFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: 4.0 + 60.0 + 4.0), size: textSize)
|
||||||
self.textNode.frame = textFrame
|
self.textNode.frame = textFrame
|
||||||
|
|
||||||
let iconContent: EmojiStatusComponent.Content
|
|
||||||
if let fileId = item.threadInfo.info.icon {
|
|
||||||
iconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 96.0, height: 96.0), placeholderColor: item.theme.actionSheet.disabledActionTextColor, themeColor: item.theme.actionSheet.primaryTextColor, loopMode: .count(0))
|
|
||||||
} else {
|
|
||||||
iconContent = .topic(title: String(item.threadInfo.info.title.prefix(1)), color: item.threadInfo.info.iconColor, size: CGSize(width: 64.0, height: 64.0))
|
|
||||||
}
|
|
||||||
|
|
||||||
let iconSize = self.iconView.update(
|
|
||||||
transition: .easeInOut(duration: 0.2),
|
|
||||||
component: AnyComponent(EmojiStatusComponent(
|
|
||||||
postbox: item.context.stateManager.postbox,
|
|
||||||
energyUsageSettings: item.environment.energyUsageSettings,
|
|
||||||
resolveInlineStickers: item.context.resolveInlineStickers,
|
|
||||||
animationCache: item.context.animationCache,
|
|
||||||
animationRenderer: item.context.animationRenderer,
|
|
||||||
content: iconContent,
|
|
||||||
isVisibleForAnimations: true,
|
|
||||||
action: nil
|
|
||||||
)),
|
|
||||||
environment: {},
|
|
||||||
containerSize: CGSize(width: 54.0, height: 54.0)
|
|
||||||
)
|
|
||||||
|
|
||||||
if let iconComponentView = self.iconView.view {
|
|
||||||
if iconComponentView.superview == nil {
|
|
||||||
self.view.addSubview(iconComponentView)
|
|
||||||
}
|
|
||||||
iconComponentView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - iconSize.width) / 2.0), y: 7.0), size: iconSize)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func layout() {
|
override func layout() {
|
||||||
|
|||||||
@ -18,9 +18,10 @@ private let subtitleFont = Font.regular(12.0)
|
|||||||
|
|
||||||
private struct ShareTopicEntry: Comparable, Identifiable {
|
private struct ShareTopicEntry: Comparable, Identifiable {
|
||||||
let index: Int32
|
let index: Int32
|
||||||
|
let basePeer: EnginePeer
|
||||||
let peer: EngineRenderedPeer
|
let peer: EngineRenderedPeer
|
||||||
let id: Int64
|
let id: Int64
|
||||||
let threadData: MessageHistoryThreadData
|
let threadData: MessageHistoryThreadData?
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
|
|
||||||
@ -32,6 +33,9 @@ private struct ShareTopicEntry: Comparable, Identifiable {
|
|||||||
if lhs.index != rhs.index {
|
if lhs.index != rhs.index {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.basePeer != rhs.basePeer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if lhs.peer != rhs.peer {
|
if lhs.peer != rhs.peer {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -53,7 +57,7 @@ private struct ShareTopicEntry: Comparable, Identifiable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func item(environment: ShareControllerEnvironment, context: ShareControllerAccountContext, interfaceInteraction: ShareControllerInteraction) -> GridItem {
|
func item(environment: ShareControllerEnvironment, context: ShareControllerAccountContext, interfaceInteraction: ShareControllerInteraction) -> GridItem {
|
||||||
return ShareTopicGridItem(environment: environment, context: context, theme: self.theme, strings: self.strings, peer: self.peer, id: self.id, threadInfo: self.threadData, controllerInteraction: interfaceInteraction)
|
return ShareTopicGridItem(environment: environment, context: context, theme: self.theme, strings: self.strings, basePeer: self.basePeer, peer: self.peer, id: self.id, threadInfo: self.threadData, controllerInteraction: interfaceInteraction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +209,10 @@ final class ShareTopicsContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
|
|
||||||
for topic in topics {
|
for topic in topics {
|
||||||
if case let .forum(_, _, threadId, _, _) = topic.index, let threadData = topic.threadData {
|
if case let .forum(_, _, threadId, _, _) = topic.index, let threadData = topic.threadData {
|
||||||
entries.append(ShareTopicEntry(index: index, peer: EngineRenderedPeer(peer: peer), id: threadId, threadData: threadData, theme: theme, strings: strings))
|
entries.append(ShareTopicEntry(index: index, basePeer: peer, peer: EngineRenderedPeer(peer: peer), id: threadId, threadData: threadData, theme: theme, strings: strings))
|
||||||
|
index += 1
|
||||||
|
} else if case .chatList = topic.index {
|
||||||
|
entries.append(ShareTopicEntry(index: index, basePeer: peer, peer: topic.renderedPeer, id: topic.renderedPeer.peerId.toInt64(), threadData: nil, theme: theme, strings: strings))
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -204,6 +204,11 @@ public extension TelegramEngine.EngineData.Item {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
peers[mainPeer.id] = EnginePeer(mainPeer)
|
peers[mainPeer.id] = EnginePeer(mainPeer)
|
||||||
|
} else if let channel = peer as? TelegramChannel, channel.isMonoForum, let linkedMonoforumId = channel.linkedMonoforumId {
|
||||||
|
guard let mainChannel = view.peers[linkedMonoforumId] else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
peers[mainChannel.id] = EnginePeer(mainChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
return EngineRenderedPeer(peerId: self.id, peers: peers, associatedMedia: view.media)
|
return EngineRenderedPeer(peerId: self.id, peers: peers, associatedMedia: view.media)
|
||||||
|
|||||||
@ -169,7 +169,7 @@ extension ChatControllerImpl {
|
|||||||
|
|
||||||
let _ = (self.context.engine.data.get(
|
let _ = (self.context.engine.data.get(
|
||||||
EngineDataList(
|
EngineDataList(
|
||||||
peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init)
|
peerIds.map(TelegramEngine.EngineData.Item.Peer.RenderedPeer.init)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peerList in
|
|> deliverOnMainQueue).startStandalone(next: { [weak self] peerList in
|
||||||
@ -184,17 +184,17 @@ extension ChatControllerImpl {
|
|||||||
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many
|
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many
|
||||||
savedMessages = true
|
savedMessages = true
|
||||||
} else {
|
} else {
|
||||||
if peers.count == 1, let peer = peers.first {
|
if peers.count == 1, let peer = peers.first?.chatOrMonoforumMainPeer {
|
||||||
var peerName = peer.id == self.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
var peerName = peer.id == self.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||||
peerName = peerName.replacingOccurrences(of: "**", with: "")
|
peerName = peerName.replacingOccurrences(of: "**", with: "")
|
||||||
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
|
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_Chat_One(peerName).string : presentationData.strings.Conversation_ForwardTooltip_Chat_Many(peerName).string
|
||||||
} else if peers.count == 2, let firstPeer = peers.first, let secondPeer = peers.last {
|
} else if peers.count == 2, let firstPeer = peers.first?.chatOrMonoforumMainPeer, let secondPeer = peers.last?.chatOrMonoforumMainPeer {
|
||||||
var firstPeerName = firstPeer.id == self.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
var firstPeerName = firstPeer.id == self.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : firstPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||||
firstPeerName = firstPeerName.replacingOccurrences(of: "**", with: "")
|
firstPeerName = firstPeerName.replacingOccurrences(of: "**", with: "")
|
||||||
var secondPeerName = secondPeer.id == self.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
var secondPeerName = secondPeer.id == self.context.account.peerId ? presentationData.strings.DialogList_SavedMessages : secondPeer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||||
secondPeerName = secondPeerName.replacingOccurrences(of: "**", with: "")
|
secondPeerName = secondPeerName.replacingOccurrences(of: "**", with: "")
|
||||||
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
|
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_TwoChats_One(firstPeerName, secondPeerName).string : presentationData.strings.Conversation_ForwardTooltip_TwoChats_Many(firstPeerName, secondPeerName).string
|
||||||
} else if let peer = peers.first {
|
} else if let peer = peers.first?.chatOrMonoforumMainPeer {
|
||||||
var peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
var peerName = peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
|
||||||
peerName = peerName.replacingOccurrences(of: "**", with: "")
|
peerName = peerName.replacingOccurrences(of: "**", with: "")
|
||||||
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(peers.count - 1)").string
|
text = messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_ManyChats_One(peerName, "\(peers.count - 1)").string : presentationData.strings.Conversation_ForwardTooltip_ManyChats_Many(peerName, "\(peers.count - 1)").string
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user