mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-21 10:41:12 +00:00
[WIP] Monoforums
This commit is contained in:
parent
b752a49432
commit
1a56afcb48
@ -142,7 +142,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
|
|||||||
let primaryPeer: EnginePeer
|
let primaryPeer: EnginePeer
|
||||||
var chatPeer: EnginePeer?
|
var chatPeer: EnginePeer?
|
||||||
let maybeChatPeer = EnginePeer(peer.peer.peers[peer.peer.peerId]!)
|
let maybeChatPeer = EnginePeer(peer.peer.peers[peer.peer.peerId]!)
|
||||||
if let associatedPeerId = maybeChatPeer._asPeer().associatedPeerId, let associatedPeer = peer.peer.peers[associatedPeerId] {
|
if case .secretChat = maybeChatPeer, let associatedPeerId = maybeChatPeer._asPeer().associatedPeerId, let associatedPeer = peer.peer.peers[associatedPeerId] {
|
||||||
primaryPeer = EnginePeer(associatedPeer)
|
primaryPeer = EnginePeer(associatedPeer)
|
||||||
chatPeer = maybeChatPeer
|
chatPeer = maybeChatPeer
|
||||||
} else {
|
} else {
|
||||||
@ -1154,7 +1154,7 @@ public enum ChatListSearchEntry: Comparable, Identifiable {
|
|||||||
|
|
||||||
if message.id.peerId == peerId {
|
if message.id.peerId == peerId {
|
||||||
if let threadId = message.threadId, let threadInfo = threadInfo {
|
if let threadId = message.threadId, let threadInfo = threadInfo {
|
||||||
chatThreadInfo = ChatListItemContent.ThreadInfo(id: threadId, info: threadInfo, isOwnedByMe: false, isClosed: false, isHidden: false)
|
chatThreadInfo = ChatListItemContent.ThreadInfo(id: threadId, info: threadInfo, isOwnedByMe: false, isClosed: false, isHidden: false, threadPeer: nil)
|
||||||
index = .forum(pinnedIndex: .none, timestamp: message.index.timestamp, threadId: threadId, namespace: message.index.id.namespace, id: message.index.id.id)
|
index = .forum(pinnedIndex: .none, timestamp: message.index.timestamp, threadId: threadId, namespace: message.index.id.namespace, id: message.index.id.id)
|
||||||
} else {
|
} else {
|
||||||
index = .chatList(EngineChatList.Item.Index.ChatList(pinningIndex: nil, messageIndex: message.index))
|
index = .chatList(EngineChatList.Item.Index.ChatList(pinningIndex: nil, messageIndex: message.index))
|
||||||
@ -2748,7 +2748,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||||||
|
|
||||||
for thread in allAndFoundThreads {
|
for thread in allAndFoundThreads {
|
||||||
if let peer = thread.renderedPeer.peer, let threadData = thread.threadData, case let .forum(_, _, id, _, _) = thread.index {
|
if let peer = thread.renderedPeer.peer, let threadData = thread.threadData, case let .forum(_, _, id, _, _) = thread.index {
|
||||||
entries.append(.topic(peer, ChatListItemContent.ThreadInfo(id: id, info: threadData.info, isOwnedByMe: threadData.isOwnedByMe, isClosed: threadData.isClosed, isHidden: threadData.isHidden), index, presentationData.theme, presentationData.strings, .none))
|
entries.append(.topic(peer, ChatListItemContent.ThreadInfo(id: id, info: threadData.info, isOwnedByMe: threadData.isOwnedByMe, isClosed: threadData.isClosed, isHidden: threadData.isHidden, threadPeer: nil), index, presentationData.theme, presentationData.strings, .none))
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,19 +32,43 @@ import MultilineTextWithEntitiesComponent
|
|||||||
import ShimmerEffect
|
import ShimmerEffect
|
||||||
|
|
||||||
public enum ChatListItemContent {
|
public enum ChatListItemContent {
|
||||||
public struct ThreadInfo: Equatable {
|
public final class ThreadInfo: Equatable {
|
||||||
public var id: Int64
|
public let id: Int64
|
||||||
public var info: EngineMessageHistoryThread.Info
|
public let info: EngineMessageHistoryThread.Info
|
||||||
public var isOwnedByMe: Bool
|
public let isOwnedByMe: Bool
|
||||||
public var isClosed: Bool
|
public let isClosed: Bool
|
||||||
public var isHidden: Bool
|
public let isHidden: Bool
|
||||||
|
public let threadPeer: EnginePeer?
|
||||||
|
|
||||||
public init(id: Int64, info: EngineMessageHistoryThread.Info, isOwnedByMe: Bool, isClosed: Bool, isHidden: Bool) {
|
public init(id: Int64, info: EngineMessageHistoryThread.Info, isOwnedByMe: Bool, isClosed: Bool, isHidden: Bool, threadPeer: EnginePeer?) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.info = info
|
self.info = info
|
||||||
self.isOwnedByMe = isOwnedByMe
|
self.isOwnedByMe = isOwnedByMe
|
||||||
self.isClosed = isClosed
|
self.isClosed = isClosed
|
||||||
self.isHidden = isHidden
|
self.isHidden = isHidden
|
||||||
|
self.threadPeer = threadPeer
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: ThreadInfo, rhs: ThreadInfo) -> Bool {
|
||||||
|
if lhs.id != rhs.id {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.info != rhs.info {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.isOwnedByMe != rhs.isOwnedByMe {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.isClosed != rhs.isClosed {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.isHidden != rhs.isHidden {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.threadPeer != rhs.threadPeer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,23 +977,25 @@ private let loginCodeRegex = try? NSRegularExpression(pattern: "\\b\\d{5,8}\\b",
|
|||||||
public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||||
final class TopicItemNode: ASDisplayNode {
|
final class TopicItemNode: ASDisplayNode {
|
||||||
let topicTitleNode: TextNode
|
let topicTitleNode: TextNode
|
||||||
let titleTopicIconView: ComponentHostView<Empty>
|
let titleTopicIconView: ComponentHostView<Empty>?
|
||||||
var titleTopicIconComponent: EmojiStatusComponent
|
var titleTopicIconComponent: EmojiStatusComponent?
|
||||||
|
|
||||||
var visibilityStatus: Bool = false {
|
var visibilityStatus: Bool = false {
|
||||||
didSet {
|
didSet {
|
||||||
if self.visibilityStatus != oldValue {
|
if self.visibilityStatus != oldValue {
|
||||||
let _ = self.titleTopicIconView.update(
|
if let titleTopicIconView = self.titleTopicIconView, let titleTopicIconComponent = self.titleTopicIconComponent {
|
||||||
|
let _ = titleTopicIconView.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(self.titleTopicIconComponent.withVisibleForAnimations(self.visibilityStatus)),
|
component: AnyComponent(titleTopicIconComponent.withVisibleForAnimations(self.visibilityStatus)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: self.titleTopicIconView.bounds.size
|
containerSize: titleTopicIconView.bounds.size
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private init(topicTitleNode: TextNode, titleTopicIconView: ComponentHostView<Empty>, titleTopicIconComponent: EmojiStatusComponent) {
|
private init(topicTitleNode: TextNode, titleTopicIconView: ComponentHostView<Empty>?, titleTopicIconComponent: EmojiStatusComponent?) {
|
||||||
self.topicTitleNode = topicTitleNode
|
self.topicTitleNode = topicTitleNode
|
||||||
self.titleTopicIconView = titleTopicIconView
|
self.titleTopicIconView = titleTopicIconView
|
||||||
self.titleTopicIconComponent = titleTopicIconComponent
|
self.titleTopicIconComponent = titleTopicIconComponent
|
||||||
@ -977,39 +1003,40 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.addSubnode(self.topicTitleNode)
|
self.addSubnode(self.topicTitleNode)
|
||||||
self.view.addSubview(self.titleTopicIconView)
|
if let titleTopicIconView = self.titleTopicIconView {
|
||||||
|
self.view.addSubview(titleTopicIconView)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func asyncLayout(_ currentNode: TopicItemNode?) -> (_ constrainedWidth: CGFloat, _ context: AccountContext, _ theme: PresentationTheme, _ threadId: Int64, _ title: NSAttributedString, _ iconId: Int64?, _ iconColor: Int32) -> (CGSize, () -> TopicItemNode) {
|
static func asyncLayout(_ currentNode: TopicItemNode?) -> (_ constrainedWidth: CGFloat, _ context: AccountContext, _ theme: PresentationTheme, _ threadId: Int64, _ title: NSAttributedString, _ iconId: Int64?, _ iconColor: Int32?) -> (CGSize, () -> TopicItemNode) {
|
||||||
let makeTopicTitleLayout = TextNode.asyncLayout(currentNode?.topicTitleNode)
|
let makeTopicTitleLayout = TextNode.asyncLayout(currentNode?.topicTitleNode)
|
||||||
|
|
||||||
return { constrainedWidth, context, theme, threadId, title, iconId, iconColor in
|
return { constrainedWidth, context, theme, threadId, title, iconId, iconColor in
|
||||||
let remainingWidth = max(1.0, constrainedWidth - (18.0 + 2.0))
|
let remainingWidth = max(1.0, constrainedWidth - ((iconId == nil ? 1.0 : 18.0) + 2.0))
|
||||||
|
|
||||||
let topicTitleArguments = TextNodeLayoutArguments(attributedString: title, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: remainingWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets(top: 2.0, left: 1.0, bottom: 2.0, right: 1.0))
|
let topicTitleArguments = TextNodeLayoutArguments(attributedString: title, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: remainingWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets(top: 2.0, left: 1.0, bottom: 2.0, right: 1.0))
|
||||||
|
|
||||||
let topicTitleLayout = makeTopicTitleLayout(topicTitleArguments)
|
let topicTitleLayout = makeTopicTitleLayout(topicTitleArguments)
|
||||||
|
|
||||||
return (CGSize(width: 18.0 + 2.0 + topicTitleLayout.0.size.width, height: topicTitleLayout.0.size.height), {
|
return (CGSize(width: (iconId == nil ? 1.0 : 18.0) + 2.0 + topicTitleLayout.0.size.width, height: topicTitleLayout.0.size.height), {
|
||||||
let topicTitleNode = topicTitleLayout.1()
|
let topicTitleNode = topicTitleLayout.1()
|
||||||
|
|
||||||
let titleTopicIconView: ComponentHostView<Empty>
|
let titleTopicIconContent: EmojiStatusComponent.Content?
|
||||||
if let current = currentNode?.titleTopicIconView {
|
|
||||||
titleTopicIconView = current
|
|
||||||
} else {
|
|
||||||
titleTopicIconView = ComponentHostView<Empty>()
|
|
||||||
}
|
|
||||||
|
|
||||||
let titleTopicIconContent: EmojiStatusComponent.Content
|
|
||||||
if threadId == 1 {
|
if threadId == 1 {
|
||||||
titleTopicIconContent = .image(image: PresentationResourcesChatList.generalTopicSmallIcon(theme))
|
titleTopicIconContent = .image(image: PresentationResourcesChatList.generalTopicSmallIcon(theme))
|
||||||
} else if let fileId = iconId, fileId != 0 {
|
} else if let fileId = iconId, fileId != 0 {
|
||||||
titleTopicIconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 36.0, height: 36.0), placeholderColor: theme.list.mediaPlaceholderColor, themeColor: theme.list.itemAccentColor, loopMode: .count(0))
|
titleTopicIconContent = .animation(content: .customEmoji(fileId: fileId), size: CGSize(width: 36.0, height: 36.0), placeholderColor: theme.list.mediaPlaceholderColor, themeColor: theme.list.itemAccentColor, loopMode: .count(0))
|
||||||
} else {
|
} else if let iconColor {
|
||||||
titleTopicIconContent = .topic(title: String(title.string.prefix(1)), color: iconColor, size: CGSize(width: 18.0, height: 18.0))
|
titleTopicIconContent = .topic(title: String(title.string.prefix(1)), color: iconColor, size: CGSize(width: 18.0, height: 18.0))
|
||||||
|
} else {
|
||||||
|
titleTopicIconContent = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
let titleTopicIconComponent = EmojiStatusComponent(
|
var titleTopicIconComponent: EmojiStatusComponent?
|
||||||
|
var titleTopicIconView: ComponentHostView<Empty>?
|
||||||
|
|
||||||
|
if let titleTopicIconContent {
|
||||||
|
titleTopicIconComponent = EmojiStatusComponent(
|
||||||
context: context,
|
context: context,
|
||||||
animationCache: context.animationCache,
|
animationCache: context.animationCache,
|
||||||
animationRenderer: context.animationRenderer,
|
animationRenderer: context.animationRenderer,
|
||||||
@ -1018,10 +1045,18 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
action: nil
|
action: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if let current = currentNode?.titleTopicIconView {
|
||||||
|
titleTopicIconView = current
|
||||||
|
} else {
|
||||||
|
titleTopicIconView = ComponentHostView<Empty>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let targetNode = currentNode ?? TopicItemNode(topicTitleNode: topicTitleNode, titleTopicIconView: titleTopicIconView, titleTopicIconComponent: titleTopicIconComponent)
|
let targetNode = currentNode ?? TopicItemNode(topicTitleNode: topicTitleNode, titleTopicIconView: titleTopicIconView, titleTopicIconComponent: titleTopicIconComponent)
|
||||||
|
|
||||||
targetNode.titleTopicIconComponent = titleTopicIconComponent
|
targetNode.titleTopicIconComponent = titleTopicIconComponent
|
||||||
|
|
||||||
|
if let titleTopicIconView, let titleTopicIconComponent {
|
||||||
let iconSize = titleTopicIconView.update(
|
let iconSize = titleTopicIconView.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(titleTopicIconComponent),
|
component: AnyComponent(titleTopicIconComponent),
|
||||||
@ -1031,6 +1066,9 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
titleTopicIconView.frame = CGRect(origin: CGPoint(x: 0.0, y: 2.0), size: iconSize)
|
titleTopicIconView.frame = CGRect(origin: CGPoint(x: 0.0, y: 2.0), size: iconSize)
|
||||||
|
|
||||||
topicTitleNode.frame = CGRect(origin: CGPoint(x: 18.0 + 2.0, y: 0.0), size: topicTitleLayout.0.size)
|
topicTitleNode.frame = CGRect(origin: CGPoint(x: 18.0 + 2.0, y: 0.0), size: topicTitleLayout.0.size)
|
||||||
|
} else {
|
||||||
|
topicTitleNode.frame = CGRect(origin: CGPoint(x: 1.0, y: 0.0), size: topicTitleLayout.0.size)
|
||||||
|
}
|
||||||
|
|
||||||
return targetNode
|
return targetNode
|
||||||
})
|
})
|
||||||
@ -1090,9 +1128,9 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func asyncLayout() -> (_ context: AccountContext, _ constrainedWidth: CGFloat, _ theme: PresentationTheme, _ authorTitle: NSAttributedString?, _ topics: [(id: Int64, title: NSAttributedString, iconId: Int64?, iconColor: Int32)]) -> (CGSize, () -> CGRect?) {
|
func asyncLayout() -> (_ context: AccountContext, _ constrainedWidth: CGFloat, _ theme: PresentationTheme, _ authorTitle: NSAttributedString?, _ topics: [(id: Int64, title: NSAttributedString, iconId: Int64?, iconColor: Int32?)]) -> (CGSize, () -> CGRect?) {
|
||||||
let makeAuthorLayout = TextNode.asyncLayout(self.authorNode)
|
let makeAuthorLayout = TextNode.asyncLayout(self.authorNode)
|
||||||
var makeExistingTopicLayouts: [Int64: (_ constrainedWidth: CGFloat, _ context: AccountContext, _ theme: PresentationTheme, _ threadId: Int64, _ title: NSAttributedString, _ iconId: Int64?, _ iconColor: Int32) -> (CGSize, () -> TopicItemNode)] = [:]
|
var makeExistingTopicLayouts: [Int64: (_ constrainedWidth: CGFloat, _ context: AccountContext, _ theme: PresentationTheme, _ threadId: Int64, _ title: NSAttributedString, _ iconId: Int64?, _ iconColor: Int32?) -> (CGSize, () -> TopicItemNode)] = [:]
|
||||||
for (topicId, topicNode) in self.topicNodes {
|
for (topicId, topicNode) in self.topicNodes {
|
||||||
makeExistingTopicLayouts[topicId] = TopicItemNode.asyncLayout(topicNode)
|
makeExistingTopicLayouts[topicId] = TopicItemNode.asyncLayout(topicNode)
|
||||||
}
|
}
|
||||||
@ -1119,7 +1157,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
|
|
||||||
var topicsSizeAndApply: [(Int64, CGSize, () -> TopicItemNode)] = []
|
var topicsSizeAndApply: [(Int64, CGSize, () -> TopicItemNode)] = []
|
||||||
for topic in topics {
|
for topic in topics {
|
||||||
if remainingWidth <= 22.0 + 2.0 + 10.0 {
|
if remainingWidth <= (topic.iconId == nil ? 8.0 : 22.0) + 2.0 + 10.0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1347,7 +1385,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
case let .peer(peerData):
|
case let .peer(peerData):
|
||||||
guard let chatMainPeer = peerData.peer.chatMainPeer else {
|
guard let chatMainPeer = peerData.peer.chatOrMonoforumMainPeer else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var result = ""
|
var result = ""
|
||||||
@ -1394,7 +1432,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
var result = ""
|
var result = ""
|
||||||
var isFirst = true
|
var isFirst = true
|
||||||
for peer in peers {
|
for peer in peers {
|
||||||
if let chatMainPeer = peer.peer.chatMainPeer {
|
if let chatMainPeer = peer.peer.chatOrMonoforumMainPeer {
|
||||||
let peerTitle = chatMainPeer.compactDisplayTitle
|
let peerTitle = chatMainPeer.compactDisplayTitle
|
||||||
if !peerTitle.isEmpty {
|
if !peerTitle.isEmpty {
|
||||||
if isFirst {
|
if isFirst {
|
||||||
@ -1670,6 +1708,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
var peer: EnginePeer?
|
var peer: EnginePeer?
|
||||||
var displayAsMessage = false
|
var displayAsMessage = false
|
||||||
var enablePreview = true
|
var enablePreview = true
|
||||||
|
var peerIsMonoforum = false
|
||||||
switch item.content {
|
switch item.content {
|
||||||
case .loading:
|
case .loading:
|
||||||
displayAsMessage = true
|
displayAsMessage = true
|
||||||
@ -1679,7 +1718,10 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
if displayAsMessage, case let .user(author) = peerData.messages.last?.author {
|
if displayAsMessage, case let .user(author) = peerData.messages.last?.author {
|
||||||
peer = .user(author)
|
peer = .user(author)
|
||||||
} else {
|
} else {
|
||||||
peer = peerData.peer.chatMainPeer
|
peer = peerData.peer.chatOrMonoforumMainPeer
|
||||||
|
if case let .channel(channel) = peerData.peer.peer, channel.isMonoForum {
|
||||||
|
peerIsMonoforum = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if peerData.peer.peerId.namespace == Namespaces.Peer.SecretChat {
|
if peerData.peer.peerId.namespace == Namespaces.Peer.SecretChat {
|
||||||
enablePreview = false
|
enablePreview = false
|
||||||
@ -1726,6 +1768,9 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
overrideImage = .deletedIcon
|
overrideImage = .deletedIcon
|
||||||
}
|
}
|
||||||
var isForumAvatar = false
|
var isForumAvatar = false
|
||||||
|
if peerIsMonoforum {
|
||||||
|
isForumAvatar = true
|
||||||
|
}
|
||||||
if case let .channel(channel) = peer, channel.isForumOrMonoForum {
|
if case let .channel(channel) = peer, channel.isForumOrMonoForum {
|
||||||
isForumAvatar = true
|
isForumAvatar = true
|
||||||
}
|
}
|
||||||
@ -2055,7 +2100,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
topForumTopicItems = topForumTopicItemsValue
|
topForumTopicItems = topForumTopicItemsValue
|
||||||
|
|
||||||
if item.interaction.searchTextHighightState != nil, threadInfo == nil, topForumTopicItems.isEmpty, let message = messagesValue.first, let threadId = message.threadId, let associatedThreadInfo = message.associatedThreadInfo {
|
if item.interaction.searchTextHighightState != nil, threadInfo == nil, topForumTopicItems.isEmpty, let message = messagesValue.first, let threadId = message.threadId, let associatedThreadInfo = message.associatedThreadInfo {
|
||||||
topForumTopicItems = [EngineChatList.ForumTopicData(id: threadId, title: associatedThreadInfo.title, iconFileId: associatedThreadInfo.icon, iconColor: associatedThreadInfo.iconColor, maxOutgoingReadMessageId: message.id, isUnread: false)]
|
topForumTopicItems = [EngineChatList.ForumTopicData(id: threadId, title: associatedThreadInfo.title, iconFileId: associatedThreadInfo.icon, iconColor: associatedThreadInfo.iconColor, maxOutgoingReadMessageId: message.id, isUnread: false, threadPeer: nil)]
|
||||||
}
|
}
|
||||||
|
|
||||||
switch peerValue.peer {
|
switch peerValue.peer {
|
||||||
@ -2325,7 +2370,7 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
|
|
||||||
var contentImageSpecs: [ContentImageSpec] = []
|
var contentImageSpecs: [ContentImageSpec] = []
|
||||||
var avatarContentImageSpec: ContentImageSpec?
|
var avatarContentImageSpec: ContentImageSpec?
|
||||||
var forumThread: (id: Int64, title: String, iconId: Int64?, iconColor: Int32, isUnread: Bool)?
|
var forumThread: (id: Int64, title: String, iconId: Int64?, iconColor: Int32, threadPeer: EnginePeer?, isUnread: Bool)?
|
||||||
|
|
||||||
var displayForwardedIcon = false
|
var displayForwardedIcon = false
|
||||||
var displayStoryReplyIcon = false
|
var displayStoryReplyIcon = false
|
||||||
@ -2393,10 +2438,10 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let _ = peerText, case let .channel(channel) = itemPeer.chatMainPeer, channel.isForumOrMonoForum, threadInfo == nil {
|
if let _ = peerText, case let .channel(channel) = itemPeer.chatMainPeer, channel.isForumOrMonoForum, threadInfo == nil {
|
||||||
if let forumTopicData = forumTopicData {
|
if let forumTopicData {
|
||||||
forumThread = (forumTopicData.id, forumTopicData.title, forumTopicData.iconFileId, forumTopicData.iconColor, forumTopicData.isUnread)
|
forumThread = (forumTopicData.id, forumTopicData.title, forumTopicData.iconFileId, forumTopicData.iconColor, forumTopicData.threadPeer, forumTopicData.isUnread)
|
||||||
} else if let threadInfo = threadInfo {
|
} else if let threadInfo {
|
||||||
forumThread = (threadInfo.id, threadInfo.info.title, threadInfo.info.icon, threadInfo.info.iconColor, false)
|
forumThread = (threadInfo.id, threadInfo.info.title, threadInfo.info.icon, threadInfo.info.iconColor, nil, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2906,15 +2951,20 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
titleAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_Replies, font: titleFont, textColor: theme.titleColor)
|
titleAttributedString = NSAttributedString(string: item.presentationData.strings.DialogList_Replies, font: titleFont, textColor: theme.titleColor)
|
||||||
} else if let id = itemPeer.chatMainPeer?.id, id.isAnonymousSavedMessages {
|
} else if let id = itemPeer.chatMainPeer?.id, id.isAnonymousSavedMessages {
|
||||||
titleAttributedString = NSAttributedString(string: item.presentationData.strings.ChatList_AuthorHidden, font: titleFont, textColor: theme.titleColor)
|
titleAttributedString = NSAttributedString(string: item.presentationData.strings.ChatList_AuthorHidden, font: titleFont, textColor: theme.titleColor)
|
||||||
} else if let displayTitle = itemPeer.chatMainPeer?.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder) {
|
} else if let displayTitle = itemPeer.chatOrMonoforumMainPeer?.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder) {
|
||||||
let textColor: UIColor
|
let textColor: UIColor
|
||||||
if case let .chatList(index) = item.index, index.messageIndex.id.peerId.namespace == Namespaces.Peer.SecretChat {
|
if case let .chatList(index) = item.index, index.messageIndex.id.peerId.namespace == Namespaces.Peer.SecretChat {
|
||||||
textColor = theme.secretTitleColor
|
textColor = theme.secretTitleColor
|
||||||
} else {
|
} else {
|
||||||
textColor = theme.titleColor
|
textColor = theme.titleColor
|
||||||
}
|
}
|
||||||
|
//TODO:localize
|
||||||
|
if case let .channel(channel) = itemPeer.peer, channel.flags.contains(.isMonoforum) {
|
||||||
|
titleAttributedString = NSAttributedString(string: "\(displayTitle) Messages", font: titleFont, textColor: textColor)
|
||||||
|
} else {
|
||||||
titleAttributedString = NSAttributedString(string: displayTitle, font: titleFont, textColor: textColor)
|
titleAttributedString = NSAttributedString(string: displayTitle, font: titleFont, textColor: textColor)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case .group:
|
case .group:
|
||||||
titleAttributedString = NSAttributedString(string: item.presentationData.strings.ChatList_ArchivedChatsTitle, font: titleFont, textColor: theme.titleColor)
|
titleAttributedString = NSAttributedString(string: item.presentationData.strings.ChatList_ArchivedChatsTitle, font: titleFont, textColor: theme.titleColor)
|
||||||
}
|
}
|
||||||
@ -3271,9 +3321,30 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
|
|||||||
let isSearching = item.interaction.searchTextHighightState != nil
|
let isSearching = item.interaction.searchTextHighightState != nil
|
||||||
|
|
||||||
var isFirstForumThreadSelectable = false
|
var isFirstForumThreadSelectable = false
|
||||||
var forumThreads: [(id: Int64, title: NSAttributedString, iconId: Int64?, iconColor: Int32)] = []
|
var forumThreads: [(id: Int64, title: NSAttributedString, iconId: Int64?, iconColor: Int32?)] = []
|
||||||
if case .savedMessagesChats = item.chatListLocation {
|
if case .savedMessagesChats = item.chatListLocation {
|
||||||
} else if case let .peer(peer) = item.content, case let .channel(channel) = peer.peer.peer, channel.flags.contains(.isMonoforum) {
|
} else if case let .peer(peer) = item.content, case let .channel(channel) = peer.peer.peer, channel.flags.contains(.isMonoforum) {
|
||||||
|
if forumThread != nil || !topForumTopicItems.isEmpty {
|
||||||
|
if let forumThread {
|
||||||
|
isFirstForumThreadSelectable = forumThread.isUnread
|
||||||
|
forumThreads.append((id: forumThread.id, title: NSAttributedString(string: forumThread.threadPeer?.compactDisplayTitle ?? " ", font: textFont, textColor: forumThread.isUnread || isSearching ? theme.authorNameColor : theme.messageTextColor), iconId: nil, iconColor: nil))
|
||||||
|
}
|
||||||
|
for topicItem in topForumTopicItems {
|
||||||
|
if forumThread?.id != topicItem.id {
|
||||||
|
forumThreads.append((id: topicItem.id, title: NSAttributedString(string: topicItem.threadPeer?.compactDisplayTitle ?? " ", font: textFont, textColor: topicItem.isUnread || isSearching ? theme.authorNameColor : theme.messageTextColor), iconId: nil, iconColor: nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let effectiveAuthorTitle, let textAttributedStringValue = textAttributedString {
|
||||||
|
let mutableTextAttributedString = NSMutableAttributedString()
|
||||||
|
mutableTextAttributedString.append(NSAttributedString(string: effectiveAuthorTitle.string + ": ", font: textFont, textColor: theme.authorNameColor))
|
||||||
|
mutableTextAttributedString.append(textAttributedStringValue)
|
||||||
|
|
||||||
|
textAttributedString = mutableTextAttributedString
|
||||||
|
}
|
||||||
|
|
||||||
|
effectiveAuthorTitle = nil
|
||||||
|
}
|
||||||
} else if forumThread != nil || !topForumTopicItems.isEmpty {
|
} else if forumThread != nil || !topForumTopicItems.isEmpty {
|
||||||
if let forumThread = forumThread {
|
if let forumThread = forumThread {
|
||||||
isFirstForumThreadSelectable = forumThread.isUnread
|
isFirstForumThreadSelectable = forumThread.isUnread
|
||||||
|
@ -704,8 +704,8 @@ func chatListNodeEntriesForView(view: EngineChatList, state: ChatListNodeState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var threadInfo: ChatListItemContent.ThreadInfo?
|
var threadInfo: ChatListItemContent.ThreadInfo?
|
||||||
if let threadData = entry.threadData, let threadId = threadId {
|
if let threadData = entry.threadData, let threadId {
|
||||||
threadInfo = ChatListItemContent.ThreadInfo(id: threadId, info: threadData.info, isOwnedByMe: threadData.isOwnedByMe, isClosed: threadData.isClosed, isHidden: threadData.isHidden)
|
threadInfo = ChatListItemContent.ThreadInfo(id: threadId, info: threadData.info, isOwnedByMe: threadData.isOwnedByMe, isClosed: threadData.isClosed, isHidden: threadData.isHidden, threadPeer: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
let entry: ChatListNodeEntry = .PeerEntry(ChatListNodeEntry.PeerEntryData(
|
let entry: ChatListNodeEntry = .PeerEntry(ChatListNodeEntry.PeerEntryData(
|
||||||
@ -863,7 +863,9 @@ func chatListNodeEntriesForView(view: EngineChatList, state: ChatListNodeState,
|
|||||||
draftState: draftState,
|
draftState: draftState,
|
||||||
mediaDraftContentType: item.item.mediaDraftContentType,
|
mediaDraftContentType: item.item.mediaDraftContentType,
|
||||||
peer: item.item.renderedPeer,
|
peer: item.item.renderedPeer,
|
||||||
threadInfo: item.item.threadData.flatMap { ChatListItemContent.ThreadInfo(id: threadId, info: $0.info, isOwnedByMe: $0.isOwnedByMe, isClosed: $0.isClosed, isHidden: $0.isHidden) },
|
threadInfo: item.item.threadData.flatMap {
|
||||||
|
return ChatListItemContent.ThreadInfo(id: threadId, info: $0.info, isOwnedByMe: $0.isOwnedByMe, isClosed: $0.isClosed, isHidden: $0.isHidden, threadPeer: nil)
|
||||||
|
},
|
||||||
presence: item.item.presence,
|
presence: item.item.presence,
|
||||||
hasUnseenMentions: item.item.hasUnseenMentions,
|
hasUnseenMentions: item.item.hasUnseenMentions,
|
||||||
hasUnseenReactions: item.item.hasUnseenReactions,
|
hasUnseenReactions: item.item.hasUnseenReactions,
|
||||||
|
@ -198,13 +198,13 @@ final class ChatListIndexTable: Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let previous = previous {
|
if let previous = previous {
|
||||||
var isThreadBasedUnreadCalculation = postbox.seedConfiguration.peerSummaryIsThreadBased(updated.0)
|
var isThreadBasedUnreadCalculation = postbox.seedConfiguration.peerSummaryIsThreadBased(updated.0).value
|
||||||
if let cachedData = updatedCachedPeerData[updated.0.id]?.1, postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData) {
|
if let cachedData = updatedCachedPeerData[updated.0.id]?.1, postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData) {
|
||||||
isThreadBasedUnreadCalculation = false
|
isThreadBasedUnreadCalculation = false
|
||||||
}
|
}
|
||||||
|
|
||||||
var wasThreadBasedUnreadCalculation = false
|
var wasThreadBasedUnreadCalculation = false
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(previous.0) {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(previous.0).value {
|
||||||
if let cachedData = postbox.cachedPeerDataTable.get(previous.0.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData) {
|
if let cachedData = postbox.cachedPeerDataTable.get(previous.0.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData) {
|
||||||
} else {
|
} else {
|
||||||
wasThreadBasedUnreadCalculation = true
|
wasThreadBasedUnreadCalculation = true
|
||||||
@ -224,13 +224,13 @@ final class ChatListIndexTable: Table {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var isThreadBasedUnreadCalculation = postbox.seedConfiguration.peerSummaryIsThreadBased(peer)
|
var isThreadBasedUnreadCalculation = postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value
|
||||||
if postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedDataUpdate.1) {
|
if postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedDataUpdate.1) {
|
||||||
isThreadBasedUnreadCalculation = false
|
isThreadBasedUnreadCalculation = false
|
||||||
}
|
}
|
||||||
|
|
||||||
var wasThreadBasedUnreadCalculation = false
|
var wasThreadBasedUnreadCalculation = false
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value {
|
||||||
if let previousCachedData = cachedDataUpdate.0, postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(previousCachedData) {
|
if let previousCachedData = cachedDataUpdate.0, postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(previousCachedData) {
|
||||||
} else {
|
} else {
|
||||||
wasThreadBasedUnreadCalculation = true
|
wasThreadBasedUnreadCalculation = true
|
||||||
@ -412,7 +412,12 @@ final class ChatListIndexTable: Table {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let isContact = postbox.contactsTable.isContact(peerId: peerId)
|
let isContact = postbox.contactsTable.isContact(peerId: peerId)
|
||||||
let notificationPeerId: PeerId = peer.associatedPeerId ?? peerId
|
let notificationPeerId: PeerId
|
||||||
|
if let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
|
notificationPeerId = associatedPeerId
|
||||||
|
} else {
|
||||||
|
notificationPeerId = peerId
|
||||||
|
}
|
||||||
|
|
||||||
let initialReadState: CombinedPeerReadState?
|
let initialReadState: CombinedPeerReadState?
|
||||||
if let updated = updatedIsThreadBasedUnreadCountCalculation[peerId] {
|
if let updated = updatedIsThreadBasedUnreadCountCalculation[peerId] {
|
||||||
@ -434,7 +439,7 @@ final class ChatListIndexTable: Table {
|
|||||||
displayAsRegularChat = true
|
displayAsRegularChat = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer), !displayAsRegularChat {
|
if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value, !displayAsRegularChat {
|
||||||
let previousCount: Int32
|
let previousCount: Int32
|
||||||
if let previousSummary = alteredInitialPeerThreadsSummaries[peerId] {
|
if let previousSummary = alteredInitialPeerThreadsSummaries[peerId] {
|
||||||
previousCount = previousSummary.effectiveUnreadCount
|
previousCount = previousSummary.effectiveUnreadCount
|
||||||
@ -453,7 +458,7 @@ final class ChatListIndexTable: Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let currentReadState: CombinedPeerReadState?
|
let currentReadState: CombinedPeerReadState?
|
||||||
if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer), !displayAsRegularChat {
|
if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value, !displayAsRegularChat {
|
||||||
let count = postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0
|
let count = postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0
|
||||||
currentReadState = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 1, maxKnownId: 0, count: count, markedUnread: false))])
|
currentReadState = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 1, maxKnownId: 0, count: count, markedUnread: false))])
|
||||||
} else {
|
} else {
|
||||||
@ -686,7 +691,7 @@ final class ChatListIndexTable: Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let combinedState: CombinedPeerReadState?
|
let combinedState: CombinedPeerReadState?
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value {
|
||||||
let count: Int32 = postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0
|
let count: Int32 = postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0
|
||||||
combinedState = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 1, maxKnownId: 0, count: count, markedUnread: false))])
|
combinedState = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 1, maxKnownId: 0, count: count, markedUnread: false))])
|
||||||
} else {
|
} else {
|
||||||
@ -698,7 +703,12 @@ final class ChatListIndexTable: Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let isContact = postbox.contactsTable.isContact(peerId: peerId)
|
let isContact = postbox.contactsTable.isContact(peerId: peerId)
|
||||||
let notificationPeerId: PeerId = peer.associatedPeerId ?? peerId
|
let notificationPeerId: PeerId
|
||||||
|
if let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
|
notificationPeerId = associatedPeerId
|
||||||
|
} else {
|
||||||
|
notificationPeerId = peerId
|
||||||
|
}
|
||||||
let inclusion = self.get(peerId: peerId)
|
let inclusion = self.get(peerId: peerId)
|
||||||
if let (groupId, _) = inclusion.includedIndex(peerId: peerId) {
|
if let (groupId, _) = inclusion.includedIndex(peerId: peerId) {
|
||||||
if totalStates[groupId] == nil {
|
if totalStates[groupId] == nil {
|
||||||
@ -778,7 +788,7 @@ final class ChatListIndexTable: Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let combinedState: CombinedPeerReadState?
|
let combinedState: CombinedPeerReadState?
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value {
|
||||||
let count: Int32 = postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0
|
let count: Int32 = postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0
|
||||||
combinedState = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 1, maxKnownId: 0, count: count, markedUnread: false))])
|
combinedState = CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 0, maxOutgoingReadId: 1, maxKnownId: 0, count: count, markedUnread: false))])
|
||||||
} else {
|
} else {
|
||||||
|
@ -100,13 +100,28 @@ public struct ChatListGroupReferenceEntry: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ChatListForumTopicData: Equatable {
|
public final class ChatListForumTopicData: Equatable {
|
||||||
public var id: Int64
|
public let id: Int64
|
||||||
public var info: StoredMessageHistoryThreadInfo
|
public let info: StoredMessageHistoryThreadInfo
|
||||||
|
public let threadPeer: Peer?
|
||||||
|
|
||||||
public init(id: Int64, info: StoredMessageHistoryThreadInfo) {
|
public init(id: Int64, info: StoredMessageHistoryThreadInfo, threadPeer: Peer?) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.info = info
|
self.info = info
|
||||||
|
self.threadPeer = threadPeer
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: ChatListForumTopicData, rhs: ChatListForumTopicData) -> Bool {
|
||||||
|
if lhs.id != rhs.id {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.info != rhs.info {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !arePeersEqual(lhs.threadPeer, rhs.threadPeer) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,7 +462,12 @@ public struct ChatListFilterPredicate {
|
|||||||
if self.pinnedPeerIds.contains(peer.id) {
|
if self.pinnedPeerIds.contains(peer.id) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
let includePeerId = peer.associatedPeerId ?? peer.id
|
let includePeerId: PeerId
|
||||||
|
if let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
|
includePeerId = associatedPeerId
|
||||||
|
} else {
|
||||||
|
includePeerId = peer.id
|
||||||
|
}
|
||||||
if self.excludePeerIds.contains(includePeerId) {
|
if self.excludePeerIds.contains(includePeerId) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -694,7 +714,7 @@ final class MutableChatListView {
|
|||||||
let renderedPeer = RenderedPeer(peerId: peer.id, peers: peers, associatedMedia: renderAssociatedMediaForPeers(postbox: postbox, peers: peers))
|
let renderedPeer = RenderedPeer(peerId: peer.id, peers: peers, associatedMedia: renderAssociatedMediaForPeers(postbox: postbox, peers: peers))
|
||||||
|
|
||||||
let isUnread: Bool
|
let isUnread: Bool
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value {
|
||||||
let hasUnmutedUnread = postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.hasUnmutedUnread ?? false
|
let hasUnmutedUnread = postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.hasUnmutedUnread ?? false
|
||||||
isUnread = hasUnmutedUnread
|
isUnread = hasUnmutedUnread
|
||||||
} else {
|
} else {
|
||||||
@ -826,7 +846,7 @@ final class MutableChatListView {
|
|||||||
displayAsRegularChat = postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData)
|
displayAsRegularChat = postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let peer = groupEntries[i].renderedPeers[j].peer.peer, postbox.seedConfiguration.peerSummaryIsThreadBased(peer), !displayAsRegularChat {
|
if let peer = groupEntries[i].renderedPeers[j].peer.peer, postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value, !displayAsRegularChat {
|
||||||
isUnread = postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.hasUnmutedUnread ?? false
|
isUnread = postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.hasUnmutedUnread ?? false
|
||||||
} else {
|
} else {
|
||||||
isUnread = postbox.readStateTable.getCombinedState(groupEntries[i].renderedPeers[j].peer.peerId)?.isUnread ?? false
|
isUnread = postbox.readStateTable.getCombinedState(groupEntries[i].renderedPeers[j].peer.peerId)?.isUnread ?? false
|
||||||
@ -904,6 +924,9 @@ final class MutableChatListView {
|
|||||||
if let associatedPeer = postbox.peerTable.get(associatedPeerId) {
|
if let associatedPeer = postbox.peerTable.get(associatedPeerId) {
|
||||||
peers[associatedPeer.id] = associatedPeer
|
peers[associatedPeer.id] = associatedPeer
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
notificationSettings = postbox.peerNotificationSettingsTable.getEffective(associatedPeerId)
|
notificationSettings = postbox.peerNotificationSettingsTable.getEffective(associatedPeerId)
|
||||||
presence = postbox.peerPresenceTable.get(associatedPeerId)
|
presence = postbox.peerPresenceTable.get(associatedPeerId)
|
||||||
isContact = postbox.contactsTable.isContact(peerId: associatedPeerId)
|
isContact = postbox.contactsTable.isContact(peerId: associatedPeerId)
|
||||||
@ -916,17 +939,25 @@ final class MutableChatListView {
|
|||||||
|
|
||||||
let renderedPeer = RenderedPeer(peerId: index.messageIndex.id.peerId, peers: peers, associatedMedia: renderAssociatedMediaForPeers(postbox: postbox, peers: peers))
|
let renderedPeer = RenderedPeer(peerId: index.messageIndex.id.peerId, peers: peers, associatedMedia: renderAssociatedMediaForPeers(postbox: postbox, peers: peers))
|
||||||
|
|
||||||
|
var isThreadBased = false
|
||||||
|
var threadsArePeers = false
|
||||||
|
if let peer = renderedPeer.peer {
|
||||||
|
let value = postbox.seedConfiguration.peerSummaryIsThreadBased(peer)
|
||||||
|
isThreadBased = value.value
|
||||||
|
threadsArePeers = value.threadsArePeers
|
||||||
|
}
|
||||||
|
|
||||||
var forumTopicData: ChatListForumTopicData?
|
var forumTopicData: ChatListForumTopicData?
|
||||||
if let message = renderedMessages.first, let threadId = message.threadId {
|
if let message = renderedMessages.first, let threadId = message.threadId {
|
||||||
if let info = postbox.messageHistoryThreadIndexTable.get(peerId: message.id.peerId, threadId: threadId) {
|
if let info = postbox.messageHistoryThreadIndexTable.get(peerId: message.id.peerId, threadId: threadId) {
|
||||||
forumTopicData = ChatListForumTopicData(id: threadId, info: info)
|
forumTopicData = ChatListForumTopicData(id: threadId, info: info, threadPeer: threadsArePeers ? postbox.peerTable.get(PeerId(threadId)) : nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var topForumTopics: [ChatListForumTopicData] = []
|
var topForumTopics: [ChatListForumTopicData] = []
|
||||||
if let peer = renderedPeer.peer, postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if let peer = renderedPeer.peer, isThreadBased {
|
||||||
for item in postbox.messageHistoryThreadIndexTable.fetch(peerId: peer.id, namespace: 0, start: .upperBound, end: .lowerBound, limit: 5) {
|
for item in postbox.messageHistoryThreadIndexTable.fetch(peerId: peer.id, namespace: 0, start: .upperBound, end: .lowerBound, limit: 5) {
|
||||||
topForumTopics.append(ChatListForumTopicData(id: item.threadId, info: item.info))
|
topForumTopics.append(ChatListForumTopicData(id: item.threadId, info: item.info, threadPeer: threadsArePeers ? postbox.peerTable.get(PeerId(item.threadId)) : nil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -938,7 +969,7 @@ final class MutableChatListView {
|
|||||||
displayAsRegularChat = postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData)
|
displayAsRegularChat = postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedData)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let peer = postbox.peerTable.get(index.messageIndex.id.peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer), !displayAsRegularChat {
|
if isThreadBased, !displayAsRegularChat {
|
||||||
let summary = postbox.peerThreadsSummaryTable.get(peerId: index.messageIndex.id.peerId)
|
let summary = postbox.peerThreadsSummaryTable.get(peerId: index.messageIndex.id.peerId)
|
||||||
var count: Int32 = 0
|
var count: Int32 = 0
|
||||||
var isMuted: Bool = false
|
var isMuted: Bool = false
|
||||||
|
@ -65,7 +65,7 @@ private func mappedChatListFilterPredicate(postbox: PostboxImpl, currentTransact
|
|||||||
if let cachedPeerData = postbox.cachedPeerDataTable.get(peer.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedPeerData) {
|
if let cachedPeerData = postbox.cachedPeerDataTable.get(peer.id), postbox.seedConfiguration.decodeDisplayPeerAsRegularChat(cachedPeerData) {
|
||||||
displayAsRegularChat = true
|
displayAsRegularChat = true
|
||||||
}
|
}
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer) && !displayAsRegularChat {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value && !displayAsRegularChat {
|
||||||
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.effectiveUnreadCount ?? 0) > 0
|
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.effectiveUnreadCount ?? 0) > 0
|
||||||
} else {
|
} else {
|
||||||
isUnread = postbox.readStateTable.getCombinedState(index.messageIndex.id.peerId)?.isUnread ?? false
|
isUnread = postbox.readStateTable.getCombinedState(index.messageIndex.id.peerId)?.isUnread ?? false
|
||||||
@ -441,7 +441,7 @@ private final class ChatListViewSpaceState {
|
|||||||
let messageTagSummaryResult = resolveChatListMessageTagSummaryResultCalculation(postbox: postbox, peerId: peer.id, threadId: nil, calculation: filterPredicate.messageTagSummary)
|
let messageTagSummaryResult = resolveChatListMessageTagSummaryResultCalculation(postbox: postbox, peerId: peer.id, threadId: nil, calculation: filterPredicate.messageTagSummary)
|
||||||
|
|
||||||
var isUnread: Bool
|
var isUnread: Bool
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer) && !displayAsRegularChat {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value && !displayAsRegularChat {
|
||||||
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.effectiveUnreadCount ?? 0) > 0
|
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: peer.id)?.effectiveUnreadCount ?? 0) > 0
|
||||||
} else {
|
} else {
|
||||||
isUnread = postbox.readStateTable.getCombinedState(index.messageIndex.id.peerId)?.isUnread ?? false
|
isUnread = postbox.readStateTable.getCombinedState(index.messageIndex.id.peerId)?.isUnread ?? false
|
||||||
@ -571,7 +571,7 @@ private final class ChatListViewSpaceState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var isUnread: Bool
|
var isUnread: Bool
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(entryPeer) && !displayAsRegularChat {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(entryPeer).value && !displayAsRegularChat {
|
||||||
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: entryPeer.id)?.effectiveUnreadCount ?? 0) > 0
|
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: entryPeer.id)?.effectiveUnreadCount ?? 0) > 0
|
||||||
} else {
|
} else {
|
||||||
isUnread = postbox.readStateTable.getCombinedState(entryPeer.id)?.isUnread ?? false
|
isUnread = postbox.readStateTable.getCombinedState(entryPeer.id)?.isUnread ?? false
|
||||||
@ -620,7 +620,7 @@ private final class ChatListViewSpaceState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var isUnread: Bool
|
var isUnread: Bool
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(mainPeer) && !displayAsRegularChat {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(mainPeer).value && !displayAsRegularChat {
|
||||||
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0) > 0
|
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0) > 0
|
||||||
} else {
|
} else {
|
||||||
isUnread = postbox.readStateTable.getCombinedState(peerId)?.isUnread ?? false
|
isUnread = postbox.readStateTable.getCombinedState(peerId)?.isUnread ?? false
|
||||||
@ -750,7 +750,7 @@ private final class ChatListViewSpaceState {
|
|||||||
switch entry {
|
switch entry {
|
||||||
case let .MessageEntry(entryData):
|
case let .MessageEntry(entryData):
|
||||||
var presencePeerId = entryData.renderedPeer.peerId
|
var presencePeerId = entryData.renderedPeer.peerId
|
||||||
if let peer = entryData.renderedPeer.peers[entryData.renderedPeer.peerId], let associatedPeerId = peer.associatedPeerId {
|
if let peer = entryData.renderedPeer.peers[entryData.renderedPeer.peerId], let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
presencePeerId = associatedPeerId
|
presencePeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
if let presence = transaction.currentUpdatedPeerPresences[presencePeerId] {
|
if let presence = transaction.currentUpdatedPeerPresences[presencePeerId] {
|
||||||
@ -802,7 +802,7 @@ private final class ChatListViewSpaceState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var isUnread: Bool
|
var isUnread: Bool
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(entryPeer) && !displayAsRegularChat {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(entryPeer).value && !displayAsRegularChat {
|
||||||
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: entryPeer.id)?.effectiveUnreadCount ?? 0) > 0
|
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: entryPeer.id)?.effectiveUnreadCount ?? 0) > 0
|
||||||
} else {
|
} else {
|
||||||
isUnread = postbox.readStateTable.getCombinedState(entryPeer.id)?.isUnread ?? false
|
isUnread = postbox.readStateTable.getCombinedState(entryPeer.id)?.isUnread ?? false
|
||||||
@ -860,7 +860,7 @@ private final class ChatListViewSpaceState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var isUnread: Bool
|
var isUnread: Bool
|
||||||
if postbox.seedConfiguration.peerSummaryIsThreadBased(mainPeer) && !displayAsRegularChat {
|
if postbox.seedConfiguration.peerSummaryIsThreadBased(mainPeer).value && !displayAsRegularChat {
|
||||||
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0) > 0
|
isUnread = (postbox.peerThreadsSummaryTable.get(peerId: peerId)?.effectiveUnreadCount ?? 0) > 0
|
||||||
} else {
|
} else {
|
||||||
isUnread = postbox.readStateTable.getCombinedState(peerId)?.isUnread ?? false
|
isUnread = postbox.readStateTable.getCombinedState(peerId)?.isUnread ?? false
|
||||||
@ -954,7 +954,7 @@ private final class ChatListViewSpaceState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var updatedReadState = entryData.readState
|
var updatedReadState = entryData.readState
|
||||||
if let peer = postbox.peerTable.get(entryData.index.messageIndex.id.peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer), !displayAsRegularChat {
|
if let peer = postbox.peerTable.get(entryData.index.messageIndex.id.peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value, !displayAsRegularChat {
|
||||||
let summary = postbox.peerThreadsSummaryTable.get(peerId: peer.id)
|
let summary = postbox.peerThreadsSummaryTable.get(peerId: peer.id)
|
||||||
|
|
||||||
var count: Int32 = 0
|
var count: Int32 = 0
|
||||||
@ -1534,10 +1534,14 @@ struct ChatListViewState {
|
|||||||
if let associatedPeer = postbox.peerTable.get(associatedPeerId) {
|
if let associatedPeer = postbox.peerTable.get(associatedPeerId) {
|
||||||
peers[associatedPeer.id] = associatedPeer
|
peers[associatedPeer.id] = associatedPeer
|
||||||
}
|
}
|
||||||
|
if peer.associatedPeerOverridesIdentity {
|
||||||
presence = postbox.peerPresenceTable.get(associatedPeerId)
|
presence = postbox.peerPresenceTable.get(associatedPeerId)
|
||||||
} else {
|
} else {
|
||||||
presence = postbox.peerPresenceTable.get(index.messageIndex.id.peerId)
|
presence = postbox.peerPresenceTable.get(index.messageIndex.id.peerId)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
presence = postbox.peerPresenceTable.get(index.messageIndex.id.peerId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let renderedPeer = RenderedPeer(peerId: index.messageIndex.id.peerId, peers: peers, associatedMedia: renderAssociatedMediaForPeers(postbox: postbox, peers: peers))
|
let renderedPeer = RenderedPeer(peerId: index.messageIndex.id.peerId, peers: peers, associatedMedia: renderAssociatedMediaForPeers(postbox: postbox, peers: peers))
|
||||||
|
|
||||||
@ -1580,10 +1584,18 @@ struct ChatListViewState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isThreadBased = false
|
||||||
|
var threadsArePeers = false
|
||||||
|
if let peer = postbox.peerTable.get(index.messageIndex.id.peerId) {
|
||||||
|
let value = postbox.seedConfiguration.peerSummaryIsThreadBased(peer)
|
||||||
|
isThreadBased = value.value
|
||||||
|
threadsArePeers = value.threadsArePeers
|
||||||
|
}
|
||||||
|
|
||||||
var forumTopicData: ChatListForumTopicData?
|
var forumTopicData: ChatListForumTopicData?
|
||||||
if let message = renderedMessages.first, let threadId = message.threadId {
|
if let message = renderedMessages.first, let threadId = message.threadId {
|
||||||
if let info = postbox.messageHistoryThreadIndexTable.get(peerId: message.id.peerId, threadId: threadId) {
|
if let info = postbox.messageHistoryThreadIndexTable.get(peerId: message.id.peerId, threadId: threadId) {
|
||||||
forumTopicData = ChatListForumTopicData(id: threadId, info: info)
|
forumTopicData = ChatListForumTopicData(id: threadId, info: info, threadPeer: threadsArePeers ? postbox.peerTable.get(PeerId(threadId)) : nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1597,12 +1609,12 @@ struct ChatListViewState {
|
|||||||
var topForumTopics: [ChatListForumTopicData] = []
|
var topForumTopics: [ChatListForumTopicData] = []
|
||||||
let readState: ChatListViewReadState?
|
let readState: ChatListViewReadState?
|
||||||
|
|
||||||
if let peer = postbox.peerTable.get(index.messageIndex.id.peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer), !displayAsRegularChat {
|
if isThreadBased, !displayAsRegularChat {
|
||||||
for item in postbox.messageHistoryThreadIndexTable.fetch(peerId: peer.id, namespace: 0, start: .upperBound, end: .lowerBound, limit: 5) {
|
for item in postbox.messageHistoryThreadIndexTable.fetch(peerId: index.messageIndex.id.peerId, namespace: 0, start: .upperBound, end: .lowerBound, limit: 5) {
|
||||||
topForumTopics.append(ChatListForumTopicData(id: item.threadId, info: item.info))
|
topForumTopics.append(ChatListForumTopicData(id: item.threadId, info: item.info, threadPeer: threadsArePeers ? postbox.peerTable.get(PeerId(item.threadId)) : nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
let summary = postbox.peerThreadsSummaryTable.get(peerId: peer.id)
|
let summary = postbox.peerThreadsSummaryTable.get(peerId: index.messageIndex.id.peerId)
|
||||||
|
|
||||||
var count: Int32 = 0
|
var count: Int32 = 0
|
||||||
var isMuted: Bool = false
|
var isMuted: Bool = false
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
// Incuding at least one Objective-C class in a swift file ensures that it doesn't get stripped by the linker
|
||||||
|
private final class LinkHelperClass: NSObject {
|
||||||
|
}
|
||||||
|
|
||||||
public func fileSize(_ path: String, useTotalFileAllocatedSize: Bool = false) -> Int64? {
|
public func fileSize(_ path: String, useTotalFileAllocatedSize: Bool = false) -> Int64? {
|
||||||
/*if useTotalFileAllocatedSize {
|
/*if useTotalFileAllocatedSize {
|
||||||
let url = URL(fileURLWithPath: path)
|
let url = URL(fileURLWithPath: path)
|
||||||
|
@ -900,7 +900,7 @@ final class MutableMessageHistoryView: MutablePostboxView {
|
|||||||
case let .peerIsContact(peerId, value):
|
case let .peerIsContact(peerId, value):
|
||||||
if let replacedPeerIds = transaction.replaceContactPeerIds {
|
if let replacedPeerIds = transaction.replaceContactPeerIds {
|
||||||
let updatedValue: Bool
|
let updatedValue: Bool
|
||||||
if let contactPeer = postbox.peerTable.get(peerId), let associatedPeerId = contactPeer.associatedPeerId {
|
if let contactPeer = postbox.peerTable.get(peerId), let associatedPeerId = contactPeer.associatedPeerId, contactPeer.associatedPeerOverridesIdentity {
|
||||||
updatedValue = replacedPeerIds.contains(associatedPeerId)
|
updatedValue = replacedPeerIds.contains(associatedPeerId)
|
||||||
} else {
|
} else {
|
||||||
updatedValue = replacedPeerIds.contains(peerId)
|
updatedValue = replacedPeerIds.contains(peerId)
|
||||||
|
@ -298,6 +298,7 @@ public protocol Peer: AnyObject, PostboxCoding {
|
|||||||
var id: PeerId { get }
|
var id: PeerId { get }
|
||||||
var indexName: PeerIndexNameRepresentation { get }
|
var indexName: PeerIndexNameRepresentation { get }
|
||||||
var associatedPeerId: PeerId? { get }
|
var associatedPeerId: PeerId? { get }
|
||||||
|
var associatedPeerOverridesIdentity: Bool { get }
|
||||||
var notificationSettingsPeerId: PeerId? { get }
|
var notificationSettingsPeerId: PeerId? { get }
|
||||||
var associatedMediaIds: [MediaId]? { get }
|
var associatedMediaIds: [MediaId]? { get }
|
||||||
var timeoutAttribute: UInt32? { get }
|
var timeoutAttribute: UInt32? { get }
|
||||||
@ -305,6 +306,10 @@ public protocol Peer: AnyObject, PostboxCoding {
|
|||||||
func isEqual(_ other: Peer) -> Bool
|
func isEqual(_ other: Peer) -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension Peer {
|
||||||
|
var associatedPeerOverridesIdentity: Bool { return false }
|
||||||
|
}
|
||||||
|
|
||||||
public func arePeersEqual(_ lhs: Peer?, _ rhs: Peer?) -> Bool {
|
public func arePeersEqual(_ lhs: Peer?, _ rhs: Peer?) -> Bool {
|
||||||
if let lhs = lhs, let rhs = rhs {
|
if let lhs = lhs, let rhs = rhs {
|
||||||
return lhs.isEqual(rhs)
|
return lhs.isEqual(rhs)
|
||||||
|
@ -9,7 +9,7 @@ final class MutablePeerNotificationSettingsView: MutablePostboxView {
|
|||||||
self.notificationSettings = [:]
|
self.notificationSettings = [:]
|
||||||
for peerId in peerIds {
|
for peerId in peerIds {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let peer = postbox.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId {
|
if let peer = postbox.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
if let settings = postbox.peerNotificationSettingsTable.getEffective(notificationPeerId) {
|
if let settings = postbox.peerNotificationSettingsTable.getEffective(notificationPeerId) {
|
||||||
@ -23,7 +23,7 @@ final class MutablePeerNotificationSettingsView: MutablePostboxView {
|
|||||||
var updated = false
|
var updated = false
|
||||||
for peerId in self.peerIds {
|
for peerId in self.peerIds {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let peer = postbox.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId {
|
if let peer = postbox.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
if let (_, settings) = transaction.currentUpdatedPeerNotificationSettings[notificationPeerId] {
|
if let (_, settings) = transaction.currentUpdatedPeerNotificationSettings[notificationPeerId] {
|
||||||
@ -41,7 +41,7 @@ final class MutablePeerNotificationSettingsView: MutablePostboxView {
|
|||||||
/*var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
/*var notificationSettings: [PeerId: PeerNotificationSettings] = [:]
|
||||||
for peerId in self.peerIds {
|
for peerId in self.peerIds {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let peer = postbox.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId {
|
if let peer = postbox.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
if let settings = postbox.peerNotificationSettingsTable.getEffective(notificationPeerId) {
|
if let settings = postbox.peerNotificationSettingsTable.getEffective(notificationPeerId) {
|
||||||
|
@ -48,7 +48,7 @@ final class MutablePeerView: MutablePostboxView {
|
|||||||
var messageIds = Set<MessageId>()
|
var messageIds = Set<MessageId>()
|
||||||
peerIds.insert(peerId)
|
peerIds.insert(peerId)
|
||||||
|
|
||||||
if let peer = getPeer(peerId), let associatedPeerId = peer.associatedPeerId {
|
if let peer = getPeer(peerId), let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
peerIds.insert(associatedPeerId)
|
peerIds.insert(associatedPeerId)
|
||||||
self.contactPeerId = associatedPeerId
|
self.contactPeerId = associatedPeerId
|
||||||
self.peerIsContact = postbox.contactsTable.isContact(peerId: associatedPeerId)
|
self.peerIsContact = postbox.contactsTable.isContact(peerId: associatedPeerId)
|
||||||
@ -76,7 +76,7 @@ final class MutablePeerView: MutablePostboxView {
|
|||||||
self.memberStoryStats[id] = value
|
self.memberStoryStats[id] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let peer = self.peers[peerId], let associatedPeerId = peer.associatedPeerId {
|
if let peer = self.peers[peerId], let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
if let peer = getPeer(associatedPeerId) {
|
if let peer = getPeer(associatedPeerId) {
|
||||||
self.peers[associatedPeerId] = peer
|
self.peers[associatedPeerId] = peer
|
||||||
}
|
}
|
||||||
@ -236,7 +236,7 @@ final class MutablePeerView: MutablePostboxView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let peer = self.peers[self.peerId] {
|
if let peer = self.peers[self.peerId] {
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
if let (_, notificationSettings) = updatedNotificationSettings[associatedPeerId] {
|
if let (_, notificationSettings) = updatedNotificationSettings[associatedPeerId] {
|
||||||
self.notificationSettings = notificationSettings
|
self.notificationSettings = notificationSettings
|
||||||
updated = true
|
updated = true
|
||||||
|
@ -3309,7 +3309,7 @@ final class PostboxImpl {
|
|||||||
additionalDataEntries.append(.totalUnreadState(self.messageHistoryMetadataTable.getTotalUnreadState(groupId: .root)))
|
additionalDataEntries.append(.totalUnreadState(self.messageHistoryMetadataTable.getTotalUnreadState(groupId: .root)))
|
||||||
case let .peerNotificationSettings(peerId):
|
case let .peerNotificationSettings(peerId):
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let peer = self.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId {
|
if let peer = self.peerTable.get(peerId), let associatedPeerId = peer.associatedPeerId, peer.associatedPeerOverridesIdentity {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
additionalDataEntries.append(.peerNotificationSettings(self.peerNotificationSettingsTable.getEffective(notificationPeerId)))
|
additionalDataEntries.append(.peerNotificationSettings(self.peerNotificationSettingsTable.getEffective(notificationPeerId)))
|
||||||
@ -3319,7 +3319,7 @@ final class PostboxImpl {
|
|||||||
additionalDataEntries.append(.preferencesEntry(key, self.preferencesTable.get(key: key)))
|
additionalDataEntries.append(.preferencesEntry(key, self.preferencesTable.get(key: key)))
|
||||||
case let .peerIsContact(peerId):
|
case let .peerIsContact(peerId):
|
||||||
let value: Bool
|
let value: Bool
|
||||||
if let contactPeer = self.peerTable.get(peerId), let associatedPeerId = contactPeer.associatedPeerId {
|
if let contactPeer = self.peerTable.get(peerId), contactPeer.associatedPeerOverridesIdentity, let associatedPeerId = contactPeer.associatedPeerId {
|
||||||
value = self.contactsTable.isContact(peerId: associatedPeerId)
|
value = self.contactsTable.isContact(peerId: associatedPeerId)
|
||||||
} else {
|
} else {
|
||||||
value = self.contactsTable.isContact(peerId: peerId)
|
value = self.contactsTable.isContact(peerId: peerId)
|
||||||
|
@ -66,7 +66,7 @@ public final class SeedConfiguration {
|
|||||||
public let existingGlobalMessageTags: GlobalMessageTags
|
public let existingGlobalMessageTags: GlobalMessageTags
|
||||||
public let peerNamespacesRequiringMessageTextIndex: [PeerId.Namespace]
|
public let peerNamespacesRequiringMessageTextIndex: [PeerId.Namespace]
|
||||||
public let peerSummaryCounterTags: (Peer, Bool) -> PeerSummaryCounterTags
|
public let peerSummaryCounterTags: (Peer, Bool) -> PeerSummaryCounterTags
|
||||||
public let peerSummaryIsThreadBased: (Peer) -> Bool
|
public let peerSummaryIsThreadBased: (Peer) -> (value: Bool, threadsArePeers: Bool)
|
||||||
public let additionalChatListIndexNamespace: MessageId.Namespace?
|
public let additionalChatListIndexNamespace: MessageId.Namespace?
|
||||||
public let messageNamespacesRequiringGroupStatsValidation: Set<MessageId.Namespace>
|
public let messageNamespacesRequiringGroupStatsValidation: Set<MessageId.Namespace>
|
||||||
public let defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState]
|
public let defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState]
|
||||||
@ -97,7 +97,7 @@ public final class SeedConfiguration {
|
|||||||
existingGlobalMessageTags: GlobalMessageTags,
|
existingGlobalMessageTags: GlobalMessageTags,
|
||||||
peerNamespacesRequiringMessageTextIndex: [PeerId.Namespace],
|
peerNamespacesRequiringMessageTextIndex: [PeerId.Namespace],
|
||||||
peerSummaryCounterTags: @escaping (Peer, Bool) -> PeerSummaryCounterTags,
|
peerSummaryCounterTags: @escaping (Peer, Bool) -> PeerSummaryCounterTags,
|
||||||
peerSummaryIsThreadBased: @escaping (Peer) -> Bool,
|
peerSummaryIsThreadBased: @escaping (Peer) -> (value: Bool, threadsArePeers: Bool),
|
||||||
additionalChatListIndexNamespace: MessageId.Namespace?,
|
additionalChatListIndexNamespace: MessageId.Namespace?,
|
||||||
messageNamespacesRequiringGroupStatsValidation: Set<MessageId.Namespace>,
|
messageNamespacesRequiringGroupStatsValidation: Set<MessageId.Namespace>,
|
||||||
defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState],
|
defaultMessageNamespaceReadStates: [MessageId.Namespace: PeerReadState],
|
||||||
|
@ -64,7 +64,7 @@ final class MutableUnreadMessageCountsView: MutablePostboxView {
|
|||||||
case let .totalInGroup(groupId):
|
case let .totalInGroup(groupId):
|
||||||
return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId))
|
return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId))
|
||||||
case let .peer(peerId, handleThreads):
|
case let .peer(peerId, handleThreads):
|
||||||
if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value {
|
||||||
var count: Int32 = 0
|
var count: Int32 = 0
|
||||||
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
||||||
count = summary.totalUnreadCount
|
count = summary.totalUnreadCount
|
||||||
@ -113,7 +113,7 @@ final class MutableUnreadMessageCountsView: MutablePostboxView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .peer(peerId, handleThreads, _):
|
case let .peer(peerId, handleThreads, _):
|
||||||
if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value {
|
||||||
if transaction.updatedPeerThreadsSummaries.contains(peerId) {
|
if transaction.updatedPeerThreadsSummaries.contains(peerId) {
|
||||||
var count: Int32 = 0
|
var count: Int32 = 0
|
||||||
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
||||||
@ -143,7 +143,7 @@ final class MutableUnreadMessageCountsView: MutablePostboxView {
|
|||||||
case let .totalInGroup(groupId):
|
case let .totalInGroup(groupId):
|
||||||
return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId))
|
return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId))
|
||||||
case let .peer(peerId, handleThreads):
|
case let .peer(peerId, handleThreads):
|
||||||
if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value {
|
||||||
var count: Int32 = 0
|
var count: Int32 = 0
|
||||||
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
||||||
count = summary.totalUnreadCount
|
count = summary.totalUnreadCount
|
||||||
@ -240,7 +240,7 @@ final class MutableCombinedReadStateView: MutablePostboxView {
|
|||||||
var updated = false
|
var updated = false
|
||||||
|
|
||||||
if transaction.alteredInitialPeerCombinedReadStates[self.peerId] != nil || transaction.updatedPeerThreadCombinedStates.contains(self.peerId) {
|
if transaction.alteredInitialPeerCombinedReadStates[self.peerId] != nil || transaction.updatedPeerThreadCombinedStates.contains(self.peerId) {
|
||||||
if self.handleThreads, let peer = postbox.peerTable.get(self.peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if self.handleThreads, let peer = postbox.peerTable.get(self.peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value {
|
||||||
var count: Int32 = 0
|
var count: Int32 = 0
|
||||||
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
||||||
count = summary.totalUnreadCount
|
count = summary.totalUnreadCount
|
||||||
@ -260,7 +260,7 @@ final class MutableCombinedReadStateView: MutablePostboxView {
|
|||||||
|
|
||||||
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
|
func refreshDueToExternalTransaction(postbox: PostboxImpl) -> Bool {
|
||||||
let state: CombinedPeerReadState?
|
let state: CombinedPeerReadState?
|
||||||
if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) {
|
if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer).value {
|
||||||
var count: Int32 = 0
|
var count: Int32 = 0
|
||||||
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) {
|
||||||
count = summary.totalUnreadCount
|
count = summary.totalUnreadCount
|
||||||
|
@ -539,6 +539,7 @@ struct LoadMessageHistoryThreadsResult {
|
|||||||
var unreadMentionsCount: Int32
|
var unreadMentionsCount: Int32
|
||||||
var unreadReactionsCount: Int32
|
var unreadReactionsCount: Int32
|
||||||
var index: StoredPeerThreadCombinedState.Index?
|
var index: StoredPeerThreadCombinedState.Index?
|
||||||
|
var threadPeer: Peer?
|
||||||
|
|
||||||
init(
|
init(
|
||||||
threadId: Int64,
|
threadId: Int64,
|
||||||
@ -546,7 +547,8 @@ struct LoadMessageHistoryThreadsResult {
|
|||||||
topMessage: Int32,
|
topMessage: Int32,
|
||||||
unreadMentionsCount: Int32,
|
unreadMentionsCount: Int32,
|
||||||
unreadReactionsCount: Int32,
|
unreadReactionsCount: Int32,
|
||||||
index: StoredPeerThreadCombinedState.Index
|
index: StoredPeerThreadCombinedState.Index,
|
||||||
|
threadPeer: Peer?
|
||||||
) {
|
) {
|
||||||
self.threadId = threadId
|
self.threadId = threadId
|
||||||
self.data = data
|
self.data = data
|
||||||
@ -554,6 +556,7 @@ struct LoadMessageHistoryThreadsResult {
|
|||||||
self.unreadMentionsCount = unreadMentionsCount
|
self.unreadMentionsCount = unreadMentionsCount
|
||||||
self.unreadReactionsCount = unreadReactionsCount
|
self.unreadReactionsCount = unreadReactionsCount
|
||||||
self.index = index
|
self.index = index
|
||||||
|
self.threadPeer = threadPeer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,7 +664,8 @@ public func _internal_fillSavedMessageHistory(accountPeerId: PeerId, postbox: Po
|
|||||||
topMessage: message.id.id,
|
topMessage: message.id.id,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
unreadReactionsCount: 0,
|
unreadReactionsCount: 0,
|
||||||
index: StoredPeerThreadCombinedState.Index(timestamp: message.timestamp, threadId: threadId, messageId: message.id.id)
|
index: StoredPeerThreadCombinedState.Index(timestamp: message.timestamp, threadId: threadId, messageId: message.id.id),
|
||||||
|
threadPeer: nil
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -791,13 +795,22 @@ func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Post
|
|||||||
minIndex = topicIndex
|
minIndex = topicIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var threadPeer: Peer?
|
||||||
|
for user in users {
|
||||||
|
if user.peerId == peer.peerId {
|
||||||
|
threadPeer = TelegramUser(user: user)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
items.append(LoadMessageHistoryThreadsResult.Item(
|
items.append(LoadMessageHistoryThreadsResult.Item(
|
||||||
threadId: peer.peerId.toInt64(),
|
threadId: peer.peerId.toInt64(),
|
||||||
data: data,
|
data: data,
|
||||||
topMessage: topMessage,
|
topMessage: topMessage,
|
||||||
unreadMentionsCount: 0,
|
unreadMentionsCount: 0,
|
||||||
unreadReactionsCount: 0,
|
unreadReactionsCount: 0,
|
||||||
index: topicIndex
|
index: topicIndex,
|
||||||
|
threadPeer: threadPeer
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -936,7 +949,8 @@ func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Post
|
|||||||
topMessage: topMessage,
|
topMessage: topMessage,
|
||||||
unreadMentionsCount: unreadMentionsCount,
|
unreadMentionsCount: unreadMentionsCount,
|
||||||
unreadReactionsCount: unreadReactionsCount,
|
unreadReactionsCount: unreadReactionsCount,
|
||||||
index: topicIndex
|
index: topicIndex,
|
||||||
|
threadPeer: nil
|
||||||
))
|
))
|
||||||
case .forumTopicDeleted:
|
case .forumTopicDeleted:
|
||||||
break
|
break
|
||||||
@ -1157,7 +1171,8 @@ public func _internal_searchForumTopics(account: Account, peerId: EnginePeer.Id,
|
|||||||
iconFileId: itemData.info.icon,
|
iconFileId: itemData.info.icon,
|
||||||
iconColor: itemData.info.iconColor,
|
iconColor: itemData.info.iconColor,
|
||||||
maxOutgoingReadMessageId: EngineMessage.Id(peerId: peerId, namespace: Namespaces.Message.Cloud, id: itemData.maxOutgoingReadId),
|
maxOutgoingReadMessageId: EngineMessage.Id(peerId: peerId, namespace: Namespaces.Message.Cloud, id: itemData.maxOutgoingReadId),
|
||||||
isUnread: false
|
isUnread: false,
|
||||||
|
threadPeer: item.threadPeer.flatMap(EnginePeer.init)
|
||||||
),
|
),
|
||||||
topForumTopicItems: [],
|
topForumTopicItems: [],
|
||||||
hasFailed: false,
|
hasFailed: false,
|
||||||
|
@ -2336,7 +2336,7 @@ public func messagesForNotification(transaction: Transaction, id: MessageId, alw
|
|||||||
|
|
||||||
var notificationPeerId = id.peerId
|
var notificationPeerId = id.peerId
|
||||||
let peer = transaction.getPeer(id.peerId)
|
let peer = transaction.getPeer(id.peerId)
|
||||||
if let peer = peer, let associatedPeerId = peer.associatedPeerId {
|
if let peer, peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
if message.personal, let author = message.author {
|
if message.personal, let author = message.author {
|
||||||
|
@ -93,7 +93,7 @@ func pushPeerNotificationSettings(postbox: Postbox, network: Network, peerId: Pe
|
|||||||
return postbox.transaction { transaction -> Signal<Void, NoError> in
|
return postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||||
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
|
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,10 +946,15 @@ public final class PendingMessageManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var topMsgId: Int32?
|
var topMsgId: Int32?
|
||||||
|
var monoforumPeerId: Api.InputPeer?
|
||||||
if let threadId = messages[0].0.threadId {
|
if let threadId = messages[0].0.threadId {
|
||||||
|
if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) {
|
||||||
|
monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer)
|
||||||
|
} else {
|
||||||
flags |= Int32(1 << 9)
|
flags |= Int32(1 << 9)
|
||||||
topMsgId = Int32(clamping: threadId)
|
topMsgId = Int32(clamping: threadId)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var quickReplyShortcut: Api.InputQuickReplyShortcut?
|
var quickReplyShortcut: Api.InputQuickReplyShortcut?
|
||||||
if let quickReply {
|
if let quickReply {
|
||||||
@ -965,6 +970,12 @@ public final class PendingMessageManager {
|
|||||||
flags |= 1 << 21
|
flags |= 1 << 21
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var replyTo: Api.InputReplyTo?
|
||||||
|
if let monoforumPeerId {
|
||||||
|
replyTo = .inputReplyToMonoForum(monoforumPeerId: monoforumPeerId)
|
||||||
|
flags |= 1 << 22
|
||||||
|
}
|
||||||
|
|
||||||
let forwardPeerIds = Set(forwardIds.map { $0.0.peerId })
|
let forwardPeerIds = Set(forwardIds.map { $0.0.peerId })
|
||||||
if forwardPeerIds.count != 1 {
|
if forwardPeerIds.count != 1 {
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
@ -972,7 +983,7 @@ public final class PendingMessageManager {
|
|||||||
} else if let inputSourcePeerId = forwardPeerIds.first, let inputSourcePeer = transaction.getPeer(inputSourcePeerId).flatMap(apiInputPeer) {
|
} else if let inputSourcePeerId = forwardPeerIds.first, let inputSourcePeer = transaction.getPeer(inputSourcePeerId).flatMap(apiInputPeer) {
|
||||||
let dependencyTag = PendingMessageRequestDependencyTag(messageId: messages[0].0.id)
|
let dependencyTag = PendingMessageRequestDependencyTag(messageId: messages[0].0.id)
|
||||||
|
|
||||||
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: inputSourcePeer, id: forwardIds.map { $0.0.id }, randomId: forwardIds.map { $0.1 }, toPeer: inputPeer, topMsgId: topMsgId, replyTo: nil, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), tag: dependencyTag)
|
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: inputSourcePeer, id: forwardIds.map { $0.0.id }, randomId: forwardIds.map { $0.1 }, toPeer: inputPeer, topMsgId: topMsgId, replyTo: replyTo, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), tag: dependencyTag)
|
||||||
} else {
|
} else {
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "Invalid forward source"))
|
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "Invalid forward source"))
|
||||||
@ -1601,10 +1612,15 @@ public final class PendingMessageManager {
|
|||||||
|> map(NetworkRequestResult.result)
|
|> map(NetworkRequestResult.result)
|
||||||
case let .forward(sourceInfo):
|
case let .forward(sourceInfo):
|
||||||
var topMsgId: Int32?
|
var topMsgId: Int32?
|
||||||
|
var monoforumPeerId: Api.InputPeer?
|
||||||
if let threadId = message.threadId {
|
if let threadId = message.threadId {
|
||||||
|
if let channel = peer as? TelegramChannel, channel.flags.contains(.isMonoforum) {
|
||||||
|
monoforumPeerId = transaction.getPeer(PeerId(threadId)).flatMap(apiInputPeer)
|
||||||
|
} else {
|
||||||
flags |= Int32(1 << 9)
|
flags |= Int32(1 << 9)
|
||||||
topMsgId = Int32(clamping: threadId)
|
topMsgId = Int32(clamping: threadId)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var quickReplyShortcut: Api.InputQuickReplyShortcut?
|
var quickReplyShortcut: Api.InputQuickReplyShortcut?
|
||||||
if let quickReply {
|
if let quickReply {
|
||||||
@ -1624,8 +1640,14 @@ public final class PendingMessageManager {
|
|||||||
flags |= 1 << 21
|
flags |= 1 << 21
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var replyTo: Api.InputReplyTo?
|
||||||
|
if let monoforumPeerId {
|
||||||
|
replyTo = .inputReplyToMonoForum(monoforumPeerId: monoforumPeerId)
|
||||||
|
flags |= 1 << 22
|
||||||
|
}
|
||||||
|
|
||||||
if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = transaction.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
|
if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = transaction.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
|
||||||
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, replyTo: nil, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), tag: dependencyTag)
|
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer, topMsgId: topMsgId, replyTo: replyTo, scheduleDate: scheduleTime, sendAs: sendAsInputPeer, quickReplyShortcut: quickReplyShortcut, videoTimestamp: videoTimestamp, allowPaidStars: allowPaidStars), tag: dependencyTag)
|
||||||
|> map(NetworkRequestResult.result)
|
|> map(NetworkRequestResult.result)
|
||||||
} else {
|
} else {
|
||||||
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal"))
|
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal"))
|
||||||
|
@ -76,12 +76,14 @@ public let telegramPostboxSeedConfiguration: SeedConfiguration = {
|
|||||||
peerSummaryIsThreadBased: { peer in
|
peerSummaryIsThreadBased: { peer in
|
||||||
if let channel = peer as? TelegramChannel {
|
if let channel = peer as? TelegramChannel {
|
||||||
if channel.flags.contains(.isForum) {
|
if channel.flags.contains(.isForum) {
|
||||||
return true
|
return (true, false)
|
||||||
|
} else if channel.flags.contains(.isMonoforum) {
|
||||||
|
return (true, true)
|
||||||
} else {
|
} else {
|
||||||
return false
|
return (false, false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false
|
return (false, false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
additionalChatListIndexNamespace: Namespaces.Message.Cloud,
|
additionalChatListIndexNamespace: Namespaces.Message.Cloud,
|
||||||
|
@ -214,6 +214,14 @@ public final class TelegramChannel: Peer, Equatable {
|
|||||||
public let sendPaidMessageStars: StarsAmount?
|
public let sendPaidMessageStars: StarsAmount?
|
||||||
public let linkedMonoforumId: PeerId?
|
public let linkedMonoforumId: PeerId?
|
||||||
|
|
||||||
|
public var associatedPeerId: PeerId? {
|
||||||
|
if self.flags.contains(.isMonoforum) {
|
||||||
|
return self.linkedMonoforumId
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public var indexName: PeerIndexNameRepresentation {
|
public var indexName: PeerIndexNameRepresentation {
|
||||||
var addressNames = self.usernames.map { $0.username }
|
var addressNames = self.usernames.map { $0.username }
|
||||||
if addressNames.isEmpty, let username = self.username, !username.isEmpty {
|
if addressNames.isEmpty, let username = self.username, !username.isEmpty {
|
||||||
@ -245,7 +253,6 @@ public final class TelegramChannel: Peer, Equatable {
|
|||||||
return mediaIds
|
return mediaIds
|
||||||
}
|
}
|
||||||
|
|
||||||
public let associatedPeerId: PeerId? = nil
|
|
||||||
public let notificationSettingsPeerId: PeerId? = nil
|
public let notificationSettingsPeerId: PeerId? = nil
|
||||||
|
|
||||||
public var timeoutAttribute: UInt32? {
|
public var timeoutAttribute: UInt32? {
|
||||||
|
@ -17,6 +17,10 @@ public final class TelegramSecretChat: Peer, Equatable {
|
|||||||
public var associatedMediaIds: [MediaId]? { return nil }
|
public var associatedMediaIds: [MediaId]? { return nil }
|
||||||
|
|
||||||
public let associatedPeerId: PeerId?
|
public let associatedPeerId: PeerId?
|
||||||
|
public var associatedPeerControlsNotifications: Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
public let notificationSettingsPeerId: PeerId?
|
public let notificationSettingsPeerId: PeerId?
|
||||||
|
|
||||||
public var timeoutAttribute: UInt32? { return nil }
|
public var timeoutAttribute: UInt32? { return nil }
|
||||||
|
@ -28,21 +28,48 @@ public final class EngineChatList: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ForumTopicData: Equatable {
|
public final class ForumTopicData: Equatable {
|
||||||
public var id: Int64
|
public let id: Int64
|
||||||
public var title: String
|
public let title: String
|
||||||
public var iconFileId: Int64?
|
public let iconFileId: Int64?
|
||||||
public var iconColor: Int32
|
public let iconColor: Int32
|
||||||
public var maxOutgoingReadMessageId: EngineMessage.Id
|
public let maxOutgoingReadMessageId: EngineMessage.Id
|
||||||
public var isUnread: Bool
|
public let isUnread: Bool
|
||||||
|
public let threadPeer: EnginePeer?
|
||||||
|
|
||||||
public init(id: Int64, title: String, iconFileId: Int64?, iconColor: Int32, maxOutgoingReadMessageId: EngineMessage.Id, isUnread: Bool) {
|
public init(id: Int64, title: String, iconFileId: Int64?, iconColor: Int32, maxOutgoingReadMessageId: EngineMessage.Id, isUnread: Bool, threadPeer: EnginePeer?) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.title = title
|
self.title = title
|
||||||
self.iconFileId = iconFileId
|
self.iconFileId = iconFileId
|
||||||
self.iconColor = iconColor
|
self.iconColor = iconColor
|
||||||
self.maxOutgoingReadMessageId = maxOutgoingReadMessageId
|
self.maxOutgoingReadMessageId = maxOutgoingReadMessageId
|
||||||
self.isUnread = isUnread
|
self.isUnread = isUnread
|
||||||
|
self.threadPeer = threadPeer
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: ForumTopicData, rhs: ForumTopicData) -> Bool {
|
||||||
|
if lhs.id != rhs.id {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.title != rhs.title {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.iconFileId != rhs.iconFileId {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.iconColor != rhs.iconColor {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.maxOutgoingReadMessageId != rhs.maxOutgoingReadMessageId {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.isUnread != rhs.isUnread {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if lhs.threadPeer != rhs.threadPeer {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,15 +534,15 @@ extension EngineChatList.Item {
|
|||||||
var forumTopicDataValue: EngineChatList.ForumTopicData?
|
var forumTopicDataValue: EngineChatList.ForumTopicData?
|
||||||
if let forumTopicData = forumTopicData {
|
if let forumTopicData = forumTopicData {
|
||||||
let id = forumTopicData.id
|
let id = forumTopicData.id
|
||||||
if let forumTopicData = forumTopicData.info.data.get(MessageHistoryThreadData.self) {
|
if let forumTopicInfo = forumTopicData.info.data.get(MessageHistoryThreadData.self) {
|
||||||
forumTopicDataValue = EngineChatList.ForumTopicData(id: id, title: forumTopicData.info.title, iconFileId: forumTopicData.info.icon, iconColor: forumTopicData.info.iconColor, maxOutgoingReadMessageId: MessageId(peerId: index.messageIndex.id.peerId, namespace: Namespaces.Message.Cloud, id: forumTopicData.maxOutgoingReadId), isUnread: forumTopicData.incomingUnreadCount > 0)
|
forumTopicDataValue = EngineChatList.ForumTopicData(id: id, title: forumTopicInfo.info.title, iconFileId: forumTopicInfo.info.icon, iconColor: forumTopicInfo.info.iconColor, maxOutgoingReadMessageId: MessageId(peerId: index.messageIndex.id.peerId, namespace: Namespaces.Message.Cloud, id: forumTopicInfo.maxOutgoingReadId), isUnread: forumTopicInfo.incomingUnreadCount > 0, threadPeer: forumTopicData.threadPeer.flatMap(EnginePeer.init))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var topForumTopicItems: [EngineChatList.ForumTopicData] = []
|
var topForumTopicItems: [EngineChatList.ForumTopicData] = []
|
||||||
for item in topForumTopics {
|
for item in topForumTopics {
|
||||||
if let forumTopicData = item.info.data.get(MessageHistoryThreadData.self) {
|
if let forumTopicInfo = item.info.data.get(MessageHistoryThreadData.self) {
|
||||||
topForumTopicItems.append(EngineChatList.ForumTopicData(id: item.id, title: forumTopicData.info.title, iconFileId: forumTopicData.info.icon, iconColor: forumTopicData.info.iconColor, maxOutgoingReadMessageId: MessageId(peerId: index.messageIndex.id.peerId, namespace: Namespaces.Message.Cloud, id: forumTopicData.maxOutgoingReadId), isUnread: forumTopicData.incomingUnreadCount > 0))
|
topForumTopicItems.append(EngineChatList.ForumTopicData(id: item.id, title: forumTopicInfo.info.title, iconFileId: forumTopicInfo.info.icon, iconColor: forumTopicInfo.info.iconColor, maxOutgoingReadMessageId: MessageId(peerId: index.messageIndex.id.peerId, namespace: Namespaces.Message.Cloud, id: forumTopicInfo.maxOutgoingReadId), isUnread: forumTopicInfo.incomingUnreadCount > 0, threadPeer: item.threadPeer.flatMap(EnginePeer.init)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ func _internal_togglePeerMuted(account: Account, peerId: PeerId, threadId: Int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ func _internal_togglePeerStoriesMuted(account: Account, peerId: PeerId) -> Signa
|
|||||||
}
|
}
|
||||||
|
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ func _internal_updatePeerMuteSetting(account: Account, transaction: Transaction,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ func _internal_updatePeerDisplayPreviewsSetting(account: Account, transaction: T
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ func _internal_updatePeerStoriesMutedSetting(account: Account, peerId: PeerId, m
|
|||||||
func _internal_updatePeerStoriesMutedSetting(account: Account, transaction: Transaction, peerId: PeerId, mute: PeerStoryNotificationSettings.Mute) {
|
func _internal_updatePeerStoriesMutedSetting(account: Account, transaction: Transaction, peerId: PeerId, mute: PeerStoryNotificationSettings.Mute) {
|
||||||
if let peer = transaction.getPeer(peerId) {
|
if let peer = transaction.getPeer(peerId) {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ func _internal_updatePeerStoriesMutedSetting(account: Account, transaction: Tran
|
|||||||
func _internal_updatePeerStoriesHideSenderSetting(account: Account, transaction: Transaction, peerId: PeerId, hideSender: PeerStoryNotificationSettings.HideSender) {
|
func _internal_updatePeerStoriesHideSenderSetting(account: Account, transaction: Transaction, peerId: PeerId, hideSender: PeerStoryNotificationSettings.HideSender) {
|
||||||
if let peer = transaction.getPeer(peerId) {
|
if let peer = transaction.getPeer(peerId) {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ func _internal_updatePeerNotificationSoundInteractive(account: Account, transact
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ func _internal_updatePeerNotificationSoundInteractive(account: Account, transact
|
|||||||
func _internal_updatePeerStoryNotificationSoundInteractive(account: Account, transaction: Transaction, peerId: PeerId, sound: PeerMessageSound) {
|
func _internal_updatePeerStoryNotificationSoundInteractive(account: Account, transaction: Transaction, peerId: PeerId, sound: PeerMessageSound) {
|
||||||
if let peer = transaction.getPeer(peerId) {
|
if let peer = transaction.getPeer(peerId) {
|
||||||
var notificationPeerId = peerId
|
var notificationPeerId = peerId
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
notificationPeerId = associatedPeerId
|
notificationPeerId = associatedPeerId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,6 +632,14 @@ public final class EngineRenderedPeer: Equatable {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var chatOrMonoforumMainPeer: EnginePeer? {
|
||||||
|
if case let .channel(channel) = self.peer, channel.flags.contains(.isMonoforum), let linkedMonoforumId = channel.linkedMonoforumId {
|
||||||
|
return self.peers[linkedMonoforumId]
|
||||||
|
} else {
|
||||||
|
return self.chatMainPeer
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension EngineRenderedPeer {
|
public extension EngineRenderedPeer {
|
||||||
|
@ -80,7 +80,7 @@ public func _internal_recentlySearchedPeers(postbox: Postbox) -> Signal<[Recentl
|
|||||||
var presence: TelegramUserPresence?
|
var presence: TelegramUserPresence?
|
||||||
var unreadCount = unreadCounts[peerId] ?? 0
|
var unreadCount = unreadCounts[peerId] ?? 0
|
||||||
if let peer = peerView.peers[peerId] {
|
if let peer = peerView.peers[peerId] {
|
||||||
if let associatedPeerId = peer.associatedPeerId {
|
if peer is TelegramSecretChat, let associatedPeerId = peer.associatedPeerId {
|
||||||
presence = peerView.peerPresences[associatedPeerId] as? TelegramUserPresence
|
presence = peerView.peerPresences[associatedPeerId] as? TelegramUserPresence
|
||||||
} else {
|
} else {
|
||||||
presence = peerView.peerPresences[peerId] as? TelegramUserPresence
|
presence = peerView.peerPresences[peerId] as? TelegramUserPresence
|
||||||
|
@ -895,243 +895,6 @@ func _internal_collectCacheUsageStats(account: Account, peerId: PeerId? = nil, a
|
|||||||
}
|
}
|
||||||
|> runOn(queue)
|
|> runOn(queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*let initialState = CacheUsageStatsState()
|
|
||||||
if let peerId = peerId {
|
|
||||||
initialState.lowerBound = MessageIndex.lowerBound(peerId: peerId)
|
|
||||||
initialState.upperBound = MessageIndex.upperBound(peerId: peerId)
|
|
||||||
}
|
|
||||||
|
|
||||||
let state = Atomic<CacheUsageStatsState>(value: initialState)
|
|
||||||
|
|
||||||
let excludeResourceIds = account.postbox.transaction { transaction -> Set<MediaResourceId> in
|
|
||||||
var result = Set<MediaResourceId>()
|
|
||||||
transaction.enumeratePreferencesEntries({ entry in
|
|
||||||
result.formUnion(entry.relatedResources)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
return excludeResourceIds
|
|
||||||
|> mapToSignal { excludeResourceIds -> Signal<CacheUsageStatsResult, NoError> in
|
|
||||||
let fetch = account.postbox.transaction { transaction -> ([PeerId : Set<MediaId>], [MediaId : Media], MessageIndex?) in
|
|
||||||
return transaction.enumerateMedia(lowerBound: state.with { $0.lowerBound }, upperBound: state.with { $0.upperBound }, limit: 1000)
|
|
||||||
}
|
|
||||||
|> mapError { _ -> CollectCacheUsageStatsError in }
|
|
||||||
|
|
||||||
let process: ([PeerId : Set<MediaId>], [MediaId : Media], MessageIndex?) -> Signal<CacheUsageStatsResult, CollectCacheUsageStatsError> = { mediaByPeer, mediaRefs, updatedLowerBound in
|
|
||||||
var mediaIdToPeerId: [MediaId: PeerId] = [:]
|
|
||||||
for (peerId, mediaIds) in mediaByPeer {
|
|
||||||
for id in mediaIds {
|
|
||||||
mediaIdToPeerId[id] = peerId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var resourceIdToMediaId: [MediaResourceId: (MediaId, PeerCacheUsageCategory)] = [:]
|
|
||||||
var mediaResourceIds: [MediaId: [MediaResourceId]] = [:]
|
|
||||||
var resourceIds: [MediaResourceId] = []
|
|
||||||
for (id, media) in mediaRefs {
|
|
||||||
mediaResourceIds[id] = []
|
|
||||||
var parsedMedia: [Media] = []
|
|
||||||
switch media {
|
|
||||||
case let image as TelegramMediaImage:
|
|
||||||
parsedMedia.append(image)
|
|
||||||
case let file as TelegramMediaFile:
|
|
||||||
parsedMedia.append(file)
|
|
||||||
case let webpage as TelegramMediaWebpage:
|
|
||||||
if case let .Loaded(content) = webpage.content {
|
|
||||||
if let image = content.image {
|
|
||||||
parsedMedia.append(image)
|
|
||||||
}
|
|
||||||
if let file = content.file {
|
|
||||||
parsedMedia.append(file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
for media in parsedMedia {
|
|
||||||
if let image = media as? TelegramMediaImage {
|
|
||||||
for representation in image.representations {
|
|
||||||
resourceIds.append(representation.resource.id)
|
|
||||||
resourceIdToMediaId[representation.resource.id] = (id, .image)
|
|
||||||
mediaResourceIds[id]!.append(representation.resource.id)
|
|
||||||
}
|
|
||||||
} else if let file = media as? TelegramMediaFile {
|
|
||||||
var category: PeerCacheUsageCategory = .file
|
|
||||||
loop: for attribute in file.attributes {
|
|
||||||
switch attribute {
|
|
||||||
case .Video:
|
|
||||||
category = .video
|
|
||||||
break loop
|
|
||||||
case .Audio:
|
|
||||||
category = .audio
|
|
||||||
break loop
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for representation in file.previewRepresentations {
|
|
||||||
resourceIds.append(representation.resource.id)
|
|
||||||
resourceIdToMediaId[representation.resource.id] = (id, category)
|
|
||||||
mediaResourceIds[id]!.append(representation.resource.id)
|
|
||||||
}
|
|
||||||
resourceIds.append(file.resource.id)
|
|
||||||
resourceIdToMediaId[file.resource.id] = (id, category)
|
|
||||||
mediaResourceIds[id]!.append(file.resource.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return account.postbox.mediaBox.collectResourceCacheUsage(resourceIds)
|
|
||||||
|> mapError { _ -> CollectCacheUsageStatsError in }
|
|
||||||
|> mapToSignal { result -> Signal<CacheUsageStatsResult, CollectCacheUsageStatsError> in
|
|
||||||
state.with { state -> Void in
|
|
||||||
state.lowerBound = updatedLowerBound
|
|
||||||
for (wrappedId, size) in result {
|
|
||||||
if let (id, category) = resourceIdToMediaId[wrappedId] {
|
|
||||||
if let peerId = mediaIdToPeerId[id] {
|
|
||||||
if state.media[peerId] == nil {
|
|
||||||
state.media[peerId] = [:]
|
|
||||||
}
|
|
||||||
if state.media[peerId]![category] == nil {
|
|
||||||
state.media[peerId]![category] = [:]
|
|
||||||
}
|
|
||||||
var currentSize: Int64 = 0
|
|
||||||
if let current = state.media[peerId]![category]![id] {
|
|
||||||
currentSize = current
|
|
||||||
}
|
|
||||||
state.media[peerId]![category]![id] = currentSize + size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (id, ids) in mediaResourceIds {
|
|
||||||
state.mediaResourceIds[id] = ids
|
|
||||||
for resourceId in ids {
|
|
||||||
state.allResourceIds.insert(resourceId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if updatedLowerBound == nil {
|
|
||||||
if peerId != nil {
|
|
||||||
let (finalMedia, finalMediaResourceIds, _) = state.with { state -> ([PeerId: [PeerCacheUsageCategory: [MediaId: Int64]]], [MediaId: [MediaResourceId]], Set<MediaResourceId>) in
|
|
||||||
return (state.media, state.mediaResourceIds, state.allResourceIds)
|
|
||||||
}
|
|
||||||
return account.postbox.transaction { transaction -> CacheUsageStats in
|
|
||||||
var peers: [PeerId: Peer] = [:]
|
|
||||||
for peerId in finalMedia.keys {
|
|
||||||
if let peer = transaction.getPeer(peerId) {
|
|
||||||
peers[peer.id] = peer
|
|
||||||
if let associatedPeerId = peer.associatedPeerId, let associatedPeer = transaction.getPeer(associatedPeerId) {
|
|
||||||
peers[associatedPeer.id] = associatedPeer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CacheUsageStats(media: finalMedia, mediaResourceIds: finalMediaResourceIds, peers: peers, otherSize: 0, otherPaths: [], cacheSize: 0, tempPaths: [], tempSize: 0, immutableSize: 0)
|
|
||||||
} |> mapError { _ -> CollectCacheUsageStatsError in }
|
|
||||||
|> mapToSignal { stats -> Signal<CacheUsageStatsResult, CollectCacheUsageStatsError> in
|
|
||||||
return .fail(.done(stats))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let (finalMedia, finalMediaResourceIds, allResourceIds) = state.with { state -> ([PeerId: [PeerCacheUsageCategory: [MediaId: Int64]]], [MediaId: [MediaResourceId]], Set<MediaResourceId>) in
|
|
||||||
return (state.media, state.mediaResourceIds, state.allResourceIds)
|
|
||||||
}
|
|
||||||
|
|
||||||
return account.postbox.mediaBox.collectOtherResourceUsage(excludeIds: excludeResourceIds, combinedExcludeIds: allResourceIds.union(excludeResourceIds))
|
|
||||||
|> mapError { _ -> CollectCacheUsageStatsError in }
|
|
||||||
|> mapToSignal { otherSize, otherPaths, cacheSize in
|
|
||||||
var tempPaths: [String] = []
|
|
||||||
var tempSize: Int64 = 0
|
|
||||||
#if os(iOS)
|
|
||||||
if let enumerator = FileManager.default.enumerator(at: URL(fileURLWithPath: NSTemporaryDirectory()), includingPropertiesForKeys: [.isDirectoryKey, .fileAllocatedSizeKey, .isSymbolicLinkKey]) {
|
|
||||||
for url in enumerator {
|
|
||||||
if let url = url as? URL {
|
|
||||||
if let isDirectoryValue = (try? url.resourceValues(forKeys: Set([.isDirectoryKey])))?.isDirectory, isDirectoryValue {
|
|
||||||
tempPaths.append(url.path)
|
|
||||||
} else if let fileSizeValue = (try? url.resourceValues(forKeys: Set([.fileAllocatedSizeKey])))?.fileAllocatedSize {
|
|
||||||
tempPaths.append(url.path)
|
|
||||||
|
|
||||||
if let isSymbolicLinkValue = (try? url.resourceValues(forKeys: Set([.isSymbolicLinkKey])))?.isSymbolicLink, isSymbolicLinkValue {
|
|
||||||
} else {
|
|
||||||
tempSize += Int64(fileSizeValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
var immutableSize: Int64 = 0
|
|
||||||
if let files = try? FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: account.basePath + "/postbox/db"), includingPropertiesForKeys: [URLResourceKey.fileSizeKey], options: []) {
|
|
||||||
for url in files {
|
|
||||||
if let fileSize = (try? url.resourceValues(forKeys: Set([.fileSizeKey])))?.fileSize {
|
|
||||||
immutableSize += Int64(fileSize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let logFilesPath = logFilesPath, let files = try? FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: logFilesPath), includingPropertiesForKeys: [URLResourceKey.fileSizeKey], options: []) {
|
|
||||||
for url in files {
|
|
||||||
if let fileSize = (try? url.resourceValues(forKeys: Set([.fileSizeKey])))?.fileSize {
|
|
||||||
immutableSize += Int64(fileSize)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for additionalPath in additionalCachePaths {
|
|
||||||
if let enumerator = FileManager.default.enumerator(at: URL(fileURLWithPath: additionalPath), includingPropertiesForKeys: [.isDirectoryKey, .fileAllocatedSizeKey, .isSymbolicLinkKey]) {
|
|
||||||
for url in enumerator {
|
|
||||||
if let url = url as? URL {
|
|
||||||
if let isDirectoryValue = (try? url.resourceValues(forKeys: Set([.isDirectoryKey])))?.isDirectory, isDirectoryValue {
|
|
||||||
} else if let fileSizeValue = (try? url.resourceValues(forKeys: Set([.fileAllocatedSizeKey])))?.fileAllocatedSize {
|
|
||||||
tempPaths.append(url.path)
|
|
||||||
|
|
||||||
if let isSymbolicLinkValue = (try? url.resourceValues(forKeys: Set([.isSymbolicLinkKey])))?.isSymbolicLink, isSymbolicLinkValue {
|
|
||||||
} else {
|
|
||||||
tempSize += Int64(fileSizeValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return account.postbox.transaction { transaction -> CacheUsageStats in
|
|
||||||
var peers: [PeerId: Peer] = [:]
|
|
||||||
for peerId in finalMedia.keys {
|
|
||||||
if let peer = transaction.getPeer(peerId) {
|
|
||||||
peers[peer.id] = peer
|
|
||||||
if let associatedPeerId = peer.associatedPeerId, let associatedPeer = transaction.getPeer(associatedPeerId) {
|
|
||||||
peers[associatedPeer.id] = associatedPeer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CacheUsageStats(media: finalMedia, mediaResourceIds: finalMediaResourceIds, peers: peers, otherSize: otherSize, otherPaths: otherPaths, cacheSize: cacheSize, tempPaths: tempPaths, tempSize: tempSize, immutableSize: immutableSize)
|
|
||||||
} |> mapError { _ -> CollectCacheUsageStatsError in }
|
|
||||||
|> mapToSignal { stats -> Signal<CacheUsageStatsResult, CollectCacheUsageStatsError> in
|
|
||||||
return .fail(.done(stats))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let signal = (fetch |> mapToSignal { mediaByPeer, mediaRefs, updatedLowerBound -> Signal<CacheUsageStatsResult, CollectCacheUsageStatsError> in
|
|
||||||
return process(mediaByPeer, mediaRefs, updatedLowerBound)
|
|
||||||
})
|
|
||||||
|> restart
|
|
||||||
|
|
||||||
return signal |> `catch` { error in
|
|
||||||
switch error {
|
|
||||||
case let .done(result):
|
|
||||||
return .single(.result(result))
|
|
||||||
case .generic:
|
|
||||||
return .complete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func _internal_clearCachedMediaResources(account: Account, mediaResourceIds: Set<MediaResourceId>) -> Signal<Float, NoError> {
|
func _internal_clearCachedMediaResources(account: Account, mediaResourceIds: Set<MediaResourceId>) -> Signal<Float, NoError> {
|
||||||
|
@ -481,6 +481,14 @@ public extension RenderedPeer {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var chatOrMonoforumMainPeer: Peer? {
|
||||||
|
if let channel = self.peer as? TelegramChannel, channel.flags.contains(.isMonoforum), let linkedMonoforumId = channel.linkedMonoforumId {
|
||||||
|
return self.peers[linkedMonoforumId]
|
||||||
|
} else {
|
||||||
|
return self.chatMainPeer
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isServicePeer(_ peer: Peer) -> Bool {
|
public func isServicePeer(_ peer: Peer) -> Bool {
|
||||||
|
@ -403,6 +403,36 @@ public func navigateToForumThreadImpl(context: AccountContext, peerId: EnginePee
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func chatControllerForForumThreadImpl(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64) -> Signal<ChatController, NoError> {
|
public func chatControllerForForumThreadImpl(context: AccountContext, peerId: EnginePeer.Id, threadId: Int64) -> Signal<ChatController, NoError> {
|
||||||
|
return context.engine.data.get(
|
||||||
|
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||||
|
)
|
||||||
|
|> deliverOnMainQueue
|
||||||
|
|> mapToSignal { peer -> Signal<ChatController, NoError> in
|
||||||
|
guard let peer else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
|
||||||
|
if case let .channel(channel) = peer, channel.flags.contains(.isMonoforum) {
|
||||||
|
return .single(ChatControllerImpl(
|
||||||
|
context: context,
|
||||||
|
chatLocation: .replyThread(message: ChatReplyThreadMessage(
|
||||||
|
peerId: peer.id,
|
||||||
|
threadId: threadId,
|
||||||
|
channelMessageId: nil,
|
||||||
|
isChannelPost: false,
|
||||||
|
isForumPost: true,
|
||||||
|
isMonoforumPost: channel.flags.contains(.isMonoforum),
|
||||||
|
maxMessage: nil,
|
||||||
|
maxReadIncomingMessageId: nil,
|
||||||
|
maxReadOutgoingMessageId: nil,
|
||||||
|
unreadCount: 0,
|
||||||
|
initialFilledHoles: IndexSet(),
|
||||||
|
initialAnchor: .automatic,
|
||||||
|
isNotAvailable: false
|
||||||
|
)),
|
||||||
|
chatLocationContextHolder: Atomic(value: nil)
|
||||||
|
))
|
||||||
|
} else {
|
||||||
return fetchAndPreloadReplyThreadInfo(context: context, subject: .groupMessage(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId))), atMessageId: nil, preload: false)
|
return fetchAndPreloadReplyThreadInfo(context: context, subject: .groupMessage(MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId))), atMessageId: nil, preload: false)
|
||||||
|> deliverOnMainQueue
|
|> deliverOnMainQueue
|
||||||
|> `catch` { _ -> Signal<ReplyThreadInfo, NoError> in
|
|> `catch` { _ -> Signal<ReplyThreadInfo, NoError> in
|
||||||
@ -416,6 +446,8 @@ public func chatControllerForForumThreadImpl(context: AccountContext, peerId: En
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func navigateToForumChannelImpl(context: AccountContext, peerId: EnginePeer.Id, navigationController: NavigationController) {
|
public func navigateToForumChannelImpl(context: AccountContext, peerId: EnginePeer.Id, navigationController: NavigationController) {
|
||||||
let controller = ChatListControllerImpl(context: context, location: .forum(peerId: peerId), controlsHistoryPreload: false, enableDebugActions: false)
|
let controller = ChatListControllerImpl(context: context, location: .forum(peerId: peerId), controlsHistoryPreload: false, enableDebugActions: false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user