mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
[WIP] Pinned messages
This commit is contained in:
parent
258006cbe8
commit
9fa15d5765
@ -22,15 +22,20 @@ public enum PeerMessagesMediaPlaylistId: Equatable, SharedMediaPlaylistId {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum PeerMessagesPlaylistLocation: Equatable, SharedMediaPlaylistLocation {
|
public enum PeerMessagesPlaylistLocation: Equatable, SharedMediaPlaylistLocation {
|
||||||
case messages(peerId: PeerId, tagMask: MessageTags, at: MessageId)
|
case messages(chatLocation: ChatLocation, tagMask: MessageTags, at: MessageId)
|
||||||
case singleMessage(MessageId)
|
case singleMessage(MessageId)
|
||||||
case recentActions(Message)
|
case recentActions(Message)
|
||||||
case custom(messages: Signal<([Message], Int32, Bool), NoError>, at: MessageId, loadMore: (() -> Void)?)
|
case custom(messages: Signal<([Message], Int32, Bool), NoError>, at: MessageId, loadMore: (() -> Void)?)
|
||||||
|
|
||||||
public var playlistId: PeerMessagesMediaPlaylistId {
|
public var playlistId: PeerMessagesMediaPlaylistId {
|
||||||
switch self {
|
switch self {
|
||||||
case let .messages(peerId, _, _):
|
case let .messages(chatLocation, _, _):
|
||||||
|
switch chatLocation {
|
||||||
|
case let .peer(peerId):
|
||||||
return .peer(peerId)
|
return .peer(peerId)
|
||||||
|
case let .replyThread(replyThreaMessage):
|
||||||
|
return .peer(replyThreaMessage.messageId.peerId)
|
||||||
|
}
|
||||||
case let .singleMessage(id):
|
case let .singleMessage(id):
|
||||||
return .peer(id.peerId)
|
return .peer(id.peerId)
|
||||||
case let .recentActions(message):
|
case let .recentActions(message):
|
||||||
@ -59,8 +64,8 @@ public enum PeerMessagesPlaylistLocation: Equatable, SharedMediaPlaylistLocation
|
|||||||
|
|
||||||
public static func ==(lhs: PeerMessagesPlaylistLocation, rhs: PeerMessagesPlaylistLocation) -> Bool {
|
public static func ==(lhs: PeerMessagesPlaylistLocation, rhs: PeerMessagesPlaylistLocation) -> Bool {
|
||||||
switch lhs {
|
switch lhs {
|
||||||
case let .messages(peerId, tagMask, at):
|
case let .messages(chatLocation, tagMask, at):
|
||||||
if case .messages(peerId, tagMask, at) = rhs {
|
if case .messages(chatLocation, tagMask, at) = rhs {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
|
@ -541,8 +541,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1963717851] = { return Api.WallPaper.parse_wallPaperNoFile($0) }
|
dict[-1963717851] = { return Api.WallPaper.parse_wallPaperNoFile($0) }
|
||||||
dict[-1938715001] = { return Api.messages.Messages.parse_messages($0) }
|
dict[-1938715001] = { return Api.messages.Messages.parse_messages($0) }
|
||||||
dict[1951620897] = { return Api.messages.Messages.parse_messagesNotModified($0) }
|
dict[1951620897] = { return Api.messages.Messages.parse_messagesNotModified($0) }
|
||||||
dict[-1725551049] = { return Api.messages.Messages.parse_channelMessages($0) }
|
dict[1682413576] = { return Api.messages.Messages.parse_channelMessages($0) }
|
||||||
dict[-923939298] = { return Api.messages.Messages.parse_messagesSlice($0) }
|
dict[978610270] = { return Api.messages.Messages.parse_messagesSlice($0) }
|
||||||
dict[-1022713000] = { return Api.Invoice.parse_invoice($0) }
|
dict[-1022713000] = { return Api.Invoice.parse_invoice($0) }
|
||||||
dict[1933519201] = { return Api.PeerSettings.parse_peerSettings($0) }
|
dict[1933519201] = { return Api.PeerSettings.parse_peerSettings($0) }
|
||||||
dict[1577067778] = { return Api.auth.SentCode.parse_sentCode($0) }
|
dict[1577067778] = { return Api.auth.SentCode.parse_sentCode($0) }
|
||||||
|
@ -1093,8 +1093,8 @@ public struct messages {
|
|||||||
public enum Messages: TypeConstructorDescription {
|
public enum Messages: TypeConstructorDescription {
|
||||||
case messages(messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
case messages(messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||||
case messagesNotModified(count: Int32)
|
case messagesNotModified(count: Int32)
|
||||||
case channelMessages(flags: Int32, pts: Int32, count: Int32, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
case channelMessages(flags: Int32, pts: Int32, count: Int32, offsetIdOffset: Int32?, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||||
case messagesSlice(flags: Int32, count: Int32, nextRate: Int32?, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
case messagesSlice(flags: Int32, count: Int32, nextRate: Int32?, offsetIdOffset: Int32?, messages: [Api.Message], chats: [Api.Chat], users: [Api.User])
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
@ -1124,13 +1124,14 @@ public struct messages {
|
|||||||
}
|
}
|
||||||
serializeInt32(count, buffer: buffer, boxed: false)
|
serializeInt32(count, buffer: buffer, boxed: false)
|
||||||
break
|
break
|
||||||
case .channelMessages(let flags, let pts, let count, let messages, let chats, let users):
|
case .channelMessages(let flags, let pts, let count, let offsetIdOffset, let messages, let chats, let users):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-1725551049)
|
buffer.appendInt32(1682413576)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt32(pts, buffer: buffer, boxed: false)
|
serializeInt32(pts, buffer: buffer, boxed: false)
|
||||||
serializeInt32(count, buffer: buffer, boxed: false)
|
serializeInt32(count, buffer: buffer, boxed: false)
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||||
buffer.appendInt32(481674261)
|
buffer.appendInt32(481674261)
|
||||||
buffer.appendInt32(Int32(messages.count))
|
buffer.appendInt32(Int32(messages.count))
|
||||||
for item in messages {
|
for item in messages {
|
||||||
@ -1147,13 +1148,14 @@ public struct messages {
|
|||||||
item.serialize(buffer, true)
|
item.serialize(buffer, true)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case .messagesSlice(let flags, let count, let nextRate, let messages, let chats, let users):
|
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let messages, let chats, let users):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-923939298)
|
buffer.appendInt32(978610270)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt32(count, buffer: buffer, boxed: false)
|
serializeInt32(count, buffer: buffer, boxed: false)
|
||||||
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(nextRate!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(nextRate!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 2) != 0 {serializeInt32(offsetIdOffset!, buffer: buffer, boxed: false)}
|
||||||
buffer.appendInt32(481674261)
|
buffer.appendInt32(481674261)
|
||||||
buffer.appendInt32(Int32(messages.count))
|
buffer.appendInt32(Int32(messages.count))
|
||||||
for item in messages {
|
for item in messages {
|
||||||
@ -1179,10 +1181,10 @@ public struct messages {
|
|||||||
return ("messages", [("messages", messages), ("chats", chats), ("users", users)])
|
return ("messages", [("messages", messages), ("chats", chats), ("users", users)])
|
||||||
case .messagesNotModified(let count):
|
case .messagesNotModified(let count):
|
||||||
return ("messagesNotModified", [("count", count)])
|
return ("messagesNotModified", [("count", count)])
|
||||||
case .channelMessages(let flags, let pts, let count, let messages, let chats, let users):
|
case .channelMessages(let flags, let pts, let count, let offsetIdOffset, let messages, let chats, let users):
|
||||||
return ("channelMessages", [("flags", flags), ("pts", pts), ("count", count), ("messages", messages), ("chats", chats), ("users", users)])
|
return ("channelMessages", [("flags", flags), ("pts", pts), ("count", count), ("offsetIdOffset", offsetIdOffset), ("messages", messages), ("chats", chats), ("users", users)])
|
||||||
case .messagesSlice(let flags, let count, let nextRate, let messages, let chats, let users):
|
case .messagesSlice(let flags, let count, let nextRate, let offsetIdOffset, let messages, let chats, let users):
|
||||||
return ("messagesSlice", [("flags", flags), ("count", count), ("nextRate", nextRate), ("messages", messages), ("chats", chats), ("users", users)])
|
return ("messagesSlice", [("flags", flags), ("count", count), ("nextRate", nextRate), ("offsetIdOffset", offsetIdOffset), ("messages", messages), ("chats", chats), ("users", users)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1227,26 +1229,29 @@ public struct messages {
|
|||||||
_2 = reader.readInt32()
|
_2 = reader.readInt32()
|
||||||
var _3: Int32?
|
var _3: Int32?
|
||||||
_3 = reader.readInt32()
|
_3 = reader.readInt32()
|
||||||
var _4: [Api.Message]?
|
var _4: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||||
|
var _5: [Api.Message]?
|
||||||
if let _ = reader.readInt32() {
|
if let _ = reader.readInt32() {
|
||||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||||
}
|
}
|
||||||
var _5: [Api.Chat]?
|
var _6: [Api.Chat]?
|
||||||
if let _ = reader.readInt32() {
|
if let _ = reader.readInt32() {
|
||||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||||
}
|
}
|
||||||
var _6: [Api.User]?
|
var _7: [Api.User]?
|
||||||
if let _ = reader.readInt32() {
|
if let _ = reader.readInt32() {
|
||||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||||
}
|
}
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
let _c4 = _4 != nil
|
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||||
let _c5 = _5 != nil
|
let _c5 = _5 != nil
|
||||||
let _c6 = _6 != nil
|
let _c6 = _6 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
let _c7 = _7 != nil
|
||||||
return Api.messages.Messages.channelMessages(flags: _1!, pts: _2!, count: _3!, messages: _4!, chats: _5!, users: _6!)
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||||
|
return Api.messages.Messages.channelMessages(flags: _1!, pts: _2!, count: _3!, offsetIdOffset: _4, messages: _5!, chats: _6!, users: _7!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
@ -1259,26 +1264,29 @@ public struct messages {
|
|||||||
_2 = reader.readInt32()
|
_2 = reader.readInt32()
|
||||||
var _3: Int32?
|
var _3: Int32?
|
||||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() }
|
||||||
var _4: [Api.Message]?
|
var _4: Int32?
|
||||||
|
if Int(_1!) & Int(1 << 2) != 0 {_4 = reader.readInt32() }
|
||||||
|
var _5: [Api.Message]?
|
||||||
if let _ = reader.readInt32() {
|
if let _ = reader.readInt32() {
|
||||||
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self)
|
||||||
}
|
}
|
||||||
var _5: [Api.Chat]?
|
var _6: [Api.Chat]?
|
||||||
if let _ = reader.readInt32() {
|
if let _ = reader.readInt32() {
|
||||||
_5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||||
}
|
}
|
||||||
var _6: [Api.User]?
|
var _7: [Api.User]?
|
||||||
if let _ = reader.readInt32() {
|
if let _ = reader.readInt32() {
|
||||||
_6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
_7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||||
}
|
}
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||||
let _c4 = _4 != nil
|
let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil
|
||||||
let _c5 = _5 != nil
|
let _c5 = _5 != nil
|
||||||
let _c6 = _6 != nil
|
let _c6 = _6 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
let _c7 = _7 != nil
|
||||||
return Api.messages.Messages.messagesSlice(flags: _1!, count: _2!, nextRate: _3, messages: _4!, chats: _5!, users: _6!)
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
|
||||||
|
return Api.messages.Messages.messagesSlice(flags: _1!, count: _2!, nextRate: _3, offsetIdOffset: _4, messages: _5!, chats: _6!, users: _7!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -1461,9 +1461,9 @@ private func resolveAssociatedMessages(network: Network, state: AccountMutableSt
|
|||||||
switch result {
|
switch result {
|
||||||
case let .messages(messages, chats, users):
|
case let .messages(messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case let .messagesSlice(_, _, _, messages, chats, users):
|
case let .messagesSlice(_, _, _, _, messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case let .channelMessages(_, _, _, messages, chats, users):
|
case let .channelMessages(_, _, _, _, messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
return ([], [], [])
|
return ([], [], [])
|
||||||
|
@ -90,11 +90,11 @@ private func fetchWebpage(account: Account, messageId: MessageId) -> Signal<Void
|
|||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .messagesSlice(_, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -988,9 +988,9 @@ public final class AccountViewTracker {
|
|||||||
switch result {
|
switch result {
|
||||||
case let .messages(messages, chats, users):
|
case let .messages(messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case let .messagesSlice(_, _, _, messages, chats, users):
|
case let .messagesSlice(_, _, _, _, messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case let .channelMessages(_, _, _, messages, chats, users):
|
case let .channelMessages(_, _, _, _, messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
return ([], [], [])
|
return ([], [], [])
|
||||||
|
@ -491,11 +491,11 @@ private func validateChannelMessagesBatch(postbox: Postbox, network: Network, ac
|
|||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .messagesSlice(_, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .channelMessages(_, pts, _, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, pts, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -546,11 +546,11 @@ private func validateReplyThreadMessagesBatch(postbox: Postbox, network: Network
|
|||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .messagesSlice(_, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .channelMessages(_, pts, _, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, pts, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -587,11 +587,11 @@ private func validateScheduledMessagesBatch(postbox: Postbox, network: Network,
|
|||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .messagesSlice(_, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -664,11 +664,11 @@ private func validateBatch(postbox: Postbox, network: Network, transaction: Tran
|
|||||||
|> map { result -> Set<MessageId> in
|
|> map { result -> Set<MessageId> in
|
||||||
let apiMessages: [Api.Message]
|
let apiMessages: [Api.Message]
|
||||||
switch result {
|
switch result {
|
||||||
case let .channelMessages(_, _, _, messages, _, _):
|
case let .channelMessages(_, _, _, _, messages, _, _):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
case let .messages(messages, _, _):
|
case let .messages(messages, _, _):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
case let .messagesSlice(_, _, _, messages, _, _):
|
case let .messagesSlice(_, _, _, _, messages, _, _):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
return Set()
|
return Set()
|
||||||
@ -912,11 +912,11 @@ private func validateReplyThreadBatch(postbox: Postbox, network: Network, transa
|
|||||||
|> map { result -> Set<MessageId> in
|
|> map { result -> Set<MessageId> in
|
||||||
let apiMessages: [Api.Message]
|
let apiMessages: [Api.Message]
|
||||||
switch result {
|
switch result {
|
||||||
case let .channelMessages(_, _, _, messages, _, _):
|
case let .channelMessages(_, _, _, _, messages, _, _):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
case let .messages(messages, _, _):
|
case let .messages(messages, _, _):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
case let .messagesSlice(_, _, _, messages, _, _):
|
case let .messagesSlice(_, _, _, _, messages, _, _):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
return Set()
|
return Set()
|
||||||
|
@ -80,9 +80,9 @@ func withResolvedAssociatedMessages<T>(postbox: Postbox, source: FetchMessageHis
|
|||||||
switch result {
|
switch result {
|
||||||
case let .messages(messages, chats, users):
|
case let .messages(messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case let .messagesSlice(_, _, _, messages, chats, users):
|
case let .messagesSlice(_, _, _, _, messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case let .channelMessages(_, _, _, messages, chats, users):
|
case let .channelMessages(_, _, _, _, messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
return ([], [], [])
|
return ([], [], [])
|
||||||
@ -436,11 +436,11 @@ func fetchMessageHistoryHole(accountPeerId: PeerId, source: FetchMessageHistoryH
|
|||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .messagesSlice(_, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .channelMessages(_, pts, _, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, pts, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -670,11 +670,11 @@ func fetchCallListHole(network: Network, postbox: Postbox, accountPeerId: PeerId
|
|||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .messagesSlice(_, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
case let .messagesSlice(_, _, _, _, messages: apiMessages, chats: apiChats, users: apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
|
@ -57,9 +57,9 @@ public func getMessagesLoadIfNecessary(_ messageIds: [MessageId], postbox: Postb
|
|||||||
switch result {
|
switch result {
|
||||||
case let .messages(messages, chats, users):
|
case let .messages(messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case let .messagesSlice(_, _, _, messages, chats, users):
|
case let .messagesSlice(_, _, _, _, messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case let .channelMessages(_, _, _, messages, chats, users):
|
case let .channelMessages(_, _, _, _, messages, chats, users):
|
||||||
return (messages, chats, users)
|
return (messages, chats, users)
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
return ([], [], [])
|
return ([], [], [])
|
||||||
|
@ -37,9 +37,9 @@ public func loadedPeerFromMessage(account: Account, peerId: PeerId, messageId: M
|
|||||||
switch result {
|
switch result {
|
||||||
case let .messages(_, _, users):
|
case let .messages(_, _, users):
|
||||||
apiUsers = users
|
apiUsers = users
|
||||||
case let .messagesSlice(_, _, _, _, _, users):
|
case let .messagesSlice(_, _, _, _, _, _, users):
|
||||||
apiUsers = users
|
apiUsers = users
|
||||||
case let .channelMessages(_, _, _, _, _, users):
|
case let .channelMessages(_, _, _, _, _, _, users):
|
||||||
apiUsers = users
|
apiUsers = users
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
apiUsers = []
|
apiUsers = []
|
||||||
|
@ -72,7 +72,7 @@ public func requestPeerPhotos(postbox: Postbox, network: Network, peerId: PeerId
|
|||||||
let chats: [Api.Chat]
|
let chats: [Api.Chat]
|
||||||
let users: [Api.User]
|
let users: [Api.User]
|
||||||
switch result {
|
switch result {
|
||||||
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -80,7 +80,7 @@ public func requestPeerPhotos(postbox: Postbox, network: Network, peerId: PeerId
|
|||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .messagesSlice(_, _, _, apiMessages, apiChats, apiUsers):
|
case let .messagesSlice(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
|
@ -71,7 +71,7 @@ private func mergedState(transaction: Transaction, state: SearchMessagesPeerStat
|
|||||||
let totalCount: Int32
|
let totalCount: Int32
|
||||||
let nextRate: Int32?
|
let nextRate: Int32?
|
||||||
switch result {
|
switch result {
|
||||||
case let .channelMessages(_, _, count, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, _, count, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -83,7 +83,7 @@ private func mergedState(transaction: Transaction, state: SearchMessagesPeerStat
|
|||||||
users = apiUsers
|
users = apiUsers
|
||||||
totalCount = Int32(messages.count)
|
totalCount = Int32(messages.count)
|
||||||
nextRate = nil
|
nextRate = nil
|
||||||
case let .messagesSlice(_, count, apiNextRate, apiMessages, apiChats, apiUsers):
|
case let .messagesSlice(_, count, _, apiNextRate, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -412,7 +412,7 @@ public func downloadMessage(postbox: Postbox, network: Network, messageId: Messa
|
|||||||
let chats: [Api.Chat]
|
let chats: [Api.Chat]
|
||||||
let users: [Api.User]
|
let users: [Api.User]
|
||||||
switch result {
|
switch result {
|
||||||
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -420,7 +420,7 @@ public func downloadMessage(postbox: Postbox, network: Network, messageId: Messa
|
|||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .messagesSlice(_, _, _, apiMessages, apiChats, apiUsers):
|
case let .messagesSlice(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -497,7 +497,7 @@ func fetchRemoteMessage(postbox: Postbox, source: FetchMessageHistoryHoleSource,
|
|||||||
let chats: [Api.Chat]
|
let chats: [Api.Chat]
|
||||||
let users: [Api.User]
|
let users: [Api.User]
|
||||||
switch result {
|
switch result {
|
||||||
case let .channelMessages(_, _, _, apiMessages, apiChats, apiUsers):
|
case let .channelMessages(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -505,7 +505,7 @@ func fetchRemoteMessage(postbox: Postbox, source: FetchMessageHistoryHoleSource,
|
|||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
case let .messagesSlice(_, _, _, apiMessages, apiChats, apiUsers):
|
case let .messagesSlice(_, _, _, _, apiMessages, apiChats, apiUsers):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
chats = apiChats
|
chats = apiChats
|
||||||
users = apiUsers
|
users = apiUsers
|
||||||
@ -574,9 +574,9 @@ public func searchMessageIdByTimestamp(account: Account, peerId: PeerId, threadI
|
|||||||
switch result {
|
switch result {
|
||||||
case let .messages(apiMessages, _, _):
|
case let .messages(apiMessages, _, _):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
case let .channelMessages(_, _, _, apiMessages, _, _):
|
case let .channelMessages(_, _, _, _, apiMessages, _, _):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
case let .messagesSlice(_, _, _, apiMessages, _, _):
|
case let .messagesSlice(_, _, _, _, apiMessages, _, _):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
messages = []
|
messages = []
|
||||||
@ -604,9 +604,9 @@ public func searchMessageIdByTimestamp(account: Account, peerId: PeerId, threadI
|
|||||||
switch result {
|
switch result {
|
||||||
case let .messages(apiMessages, _, _):
|
case let .messages(apiMessages, _, _):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
case let .channelMessages(_, _, _, apiMessages, _, _):
|
case let .channelMessages(_, _, _, _, apiMessages, _, _):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
case let .messagesSlice(_, _, _, apiMessages, _, _):
|
case let .messagesSlice(_, _, _, _, apiMessages, _, _):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
messages = []
|
messages = []
|
||||||
@ -628,9 +628,9 @@ public func searchMessageIdByTimestamp(account: Account, peerId: PeerId, threadI
|
|||||||
switch result {
|
switch result {
|
||||||
case let .messages(apiMessages, _, _):
|
case let .messages(apiMessages, _, _):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
case let .channelMessages(_, _, _, apiMessages, _, _):
|
case let .channelMessages(_, _, _, _, apiMessages, _, _):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
case let .messagesSlice(_, _, _, apiMessages, _, _):
|
case let .messagesSlice(_, _, _, _, apiMessages, _, _):
|
||||||
messages = apiMessages
|
messages = apiMessages
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
messages = []
|
messages = []
|
||||||
|
@ -57,11 +57,11 @@ private func fetchMessage(transaction: Transaction, account: Account, messageId:
|
|||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
apiChats = chats
|
apiChats = chats
|
||||||
apiUsers = users
|
apiUsers = users
|
||||||
case let .messagesSlice(_, _, _, messages, chats, users):
|
case let .messagesSlice(_, _, _, _, messages, chats, users):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
apiChats = chats
|
apiChats = chats
|
||||||
apiUsers = users
|
apiUsers = users
|
||||||
case let .channelMessages(_, _, _, messages, chats, users):
|
case let .channelMessages(_, _, _, _, messages, chats, users):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
apiChats = chats
|
apiChats = chats
|
||||||
apiUsers = users
|
apiUsers = users
|
||||||
|
@ -48,11 +48,11 @@ private func dialogTopMessage(network: Network, postbox: Postbox, peerId: PeerId
|
|||||||
}
|
}
|
||||||
let apiMessages: [Api.Message]
|
let apiMessages: [Api.Message]
|
||||||
switch result {
|
switch result {
|
||||||
case let .channelMessages(_, _, _, messages, _, _):
|
case let .channelMessages(_, _, _, _, messages, _, _):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
case let .messages(messages, _, _):
|
case let .messages(messages, _, _):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
case let .messagesSlice(_, _, _, messages, _, _):
|
case let .messagesSlice(_, _, _, _, messages, _, _):
|
||||||
apiMessages = messages
|
apiMessages = messages
|
||||||
case .messagesNotModified:
|
case .messagesNotModified:
|
||||||
apiMessages = []
|
apiMessages = []
|
||||||
|
@ -170,6 +170,10 @@ public final class PrincipalThemeEssentialGraphics {
|
|||||||
public let outgoingDateAndStatusRepliesIcon: UIImage
|
public let outgoingDateAndStatusRepliesIcon: UIImage
|
||||||
public let mediaRepliesIcon: UIImage
|
public let mediaRepliesIcon: UIImage
|
||||||
public let freeRepliesIcon: UIImage
|
public let freeRepliesIcon: UIImage
|
||||||
|
public let incomingDateAndStatusPinnedIcon: UIImage
|
||||||
|
public let outgoingDateAndStatusPinnedIcon: UIImage
|
||||||
|
public let mediaPinnedIcon: UIImage
|
||||||
|
public let freePinnedIcon: UIImage
|
||||||
|
|
||||||
public let dateStaticBackground: UIImage
|
public let dateStaticBackground: UIImage
|
||||||
public let dateFloatingBackground: UIImage
|
public let dateFloatingBackground: UIImage
|
||||||
@ -333,6 +337,12 @@ public final class PrincipalThemeEssentialGraphics {
|
|||||||
self.mediaRepliesIcon = generateTintedImage(image: repliesImage, color: .white)!
|
self.mediaRepliesIcon = generateTintedImage(image: repliesImage, color: .white)!
|
||||||
self.freeRepliesIcon = generateTintedImage(image: repliesImage, color: serviceColor.primaryText)!
|
self.freeRepliesIcon = generateTintedImage(image: repliesImage, color: serviceColor.primaryText)!
|
||||||
|
|
||||||
|
let pinnedImage = UIImage(bundleImageName: "Chat/Message/Pinned")!
|
||||||
|
self.incomingDateAndStatusPinnedIcon = generateTintedImage(image: pinnedImage, color: theme.message.incoming.secondaryTextColor)!
|
||||||
|
self.outgoingDateAndStatusPinnedIcon = generateTintedImage(image: pinnedImage, color: theme.message.outgoing.secondaryTextColor)!
|
||||||
|
self.mediaPinnedIcon = generateTintedImage(image: pinnedImage, color: .white)!
|
||||||
|
self.freePinnedIcon = generateTintedImage(image: pinnedImage, color: serviceColor.primaryText)!
|
||||||
|
|
||||||
self.radialIndicatorFileIconIncoming = emptyImage
|
self.radialIndicatorFileIconIncoming = emptyImage
|
||||||
self.radialIndicatorFileIconOutgoing = emptyImage
|
self.radialIndicatorFileIconOutgoing = emptyImage
|
||||||
} else {
|
} else {
|
||||||
@ -438,6 +448,12 @@ public final class PrincipalThemeEssentialGraphics {
|
|||||||
self.mediaRepliesIcon = generateTintedImage(image: repliesImage, color: .white)!
|
self.mediaRepliesIcon = generateTintedImage(image: repliesImage, color: .white)!
|
||||||
self.freeRepliesIcon = generateTintedImage(image: repliesImage, color: serviceColor.primaryText)!
|
self.freeRepliesIcon = generateTintedImage(image: repliesImage, color: serviceColor.primaryText)!
|
||||||
|
|
||||||
|
let pinnedImage = UIImage(bundleImageName: "Chat/Message/Pinned")!
|
||||||
|
self.incomingDateAndStatusPinnedIcon = generateTintedImage(image: pinnedImage, color: theme.message.incoming.secondaryTextColor)!
|
||||||
|
self.outgoingDateAndStatusPinnedIcon = generateTintedImage(image: pinnedImage, color: theme.message.outgoing.secondaryTextColor)!
|
||||||
|
self.mediaPinnedIcon = generateTintedImage(image: pinnedImage, color: .white)!
|
||||||
|
self.freePinnedIcon = generateTintedImage(image: pinnedImage, color: serviceColor.primaryText)!
|
||||||
|
|
||||||
self.radialIndicatorFileIconIncoming = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/RadialProgressIconDocument"), color: .black)!
|
self.radialIndicatorFileIconIncoming = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/RadialProgressIconDocument"), color: .black)!
|
||||||
self.radialIndicatorFileIconOutgoing = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/RadialProgressIconDocument"), color: .black)!
|
self.radialIndicatorFileIconOutgoing = generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/RadialProgressIconDocument"), color: .black)!
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"author" : "xcode",
|
||||||
"author" : "xcode"
|
"version" : 1
|
||||||
},
|
},
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"provides-namespace" : true
|
"provides-namespace" : true
|
||||||
|
12
submodules/TelegramUI/Images.xcassets/Chat/Message/Pinned.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Message/Pinned.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "messagepin.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
submodules/TelegramUI/Images.xcassets/Chat/Message/Pinned.imageset/messagepin.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Chat/Message/Pinned.imageset/messagepin.pdf
vendored
Normal file
Binary file not shown.
@ -4882,7 +4882,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, unpinMessage: { [weak self] id in
|
}, unpinMessage: { [weak self] id, askForConfirmation in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
|
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer {
|
||||||
var canManagePin = false
|
var canManagePin = false
|
||||||
@ -4904,7 +4904,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
|
|
||||||
if canManagePin {
|
if canManagePin {
|
||||||
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.Conversation_UnpinMessageAlert, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Conversation_Unpin, action: {
|
let action: () -> Void = {
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let disposable: MetaDisposable
|
let disposable: MetaDisposable
|
||||||
if let current = strongSelf.unpinMessageDisposable {
|
if let current = strongSelf.unpinMessageDisposable {
|
||||||
@ -4915,7 +4918,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
disposable.set(requestUpdatePinnedMessage(account: strongSelf.context.account, peerId: peer.id, update: .clear(id: id)).start())
|
disposable.set(requestUpdatePinnedMessage(account: strongSelf.context.account, peerId: peer.id, update: .clear(id: id)).start())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if askForConfirmation {
|
||||||
|
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: strongSelf.presentationData.strings.Conversation_UnpinMessageAlert, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Conversation_Unpin, action: {
|
||||||
|
action()
|
||||||
}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})], actionLayout: .vertical), in: .window(.root))
|
}), TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {})], actionLayout: .vertical), in: .window(.root))
|
||||||
|
} else {
|
||||||
|
action()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let pinnedMessage = strongSelf.presentationInterfaceState.pinnedMessage {
|
if let pinnedMessage = strongSelf.presentationInterfaceState.pinnedMessage {
|
||||||
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||||
|
@ -664,7 +664,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||||||
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_Unpin, icon: { theme in
|
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_Unpin, icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Unpin"), color: theme.actionSheet.primaryTextColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Unpin"), color: theme.actionSheet.primaryTextColor)
|
||||||
}, action: { _, f in
|
}, action: { _, f in
|
||||||
interfaceInteraction.unpinMessage(pinnedSelectedMessageId)
|
interfaceInteraction.unpinMessage(pinnedSelectedMessageId, false)
|
||||||
f(.default)
|
f(.default)
|
||||||
})))
|
})))
|
||||||
} else {
|
} else {
|
||||||
|
@ -702,7 +702,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
|
|
||||||
let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .minimal, reactionCount: dateReactionCount)
|
let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .minimal, reactionCount: dateReactionCount)
|
||||||
|
|
||||||
let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies)
|
let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies, item.message.tags.contains(.pinned))
|
||||||
|
|
||||||
var viaBotApply: (TextNodeLayout, () -> TextNode)?
|
var viaBotApply: (TextNodeLayout, () -> TextNode)?
|
||||||
var replyInfoApply: (CGSize, () -> ChatMessageReplyInfoNode)?
|
var replyInfoApply: (CGSize, () -> ChatMessageReplyInfoNode)?
|
||||||
|
@ -572,7 +572,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
statusSizeAndApply = statusLayout(context, presentationData, edited, viewCount, dateText, statusType, textConstrainedSize, dateReactions, dateReplies)
|
statusSizeAndApply = statusLayout(context, presentationData, edited, viewCount, dateText, statusType, textConstrainedSize, dateReactions, dateReplies, message.tags.contains(.pinned))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
|
@ -900,7 +900,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
|||||||
forwardInfoLayout: (ChatPresentationData, PresentationStrings, ChatMessageForwardInfoType, Peer?, String?, String?, CGSize) -> (CGSize, (CGFloat) -> ChatMessageForwardInfoNode),
|
forwardInfoLayout: (ChatPresentationData, PresentationStrings, ChatMessageForwardInfoType, Peer?, String?, String?, CGSize) -> (CGSize, (CGFloat) -> ChatMessageForwardInfoNode),
|
||||||
replyInfoLayout: (ChatPresentationData, PresentationStrings, AccountContext, ChatMessageReplyInfoType, Message, CGSize) -> (CGSize, () -> ChatMessageReplyInfoNode),
|
replyInfoLayout: (ChatPresentationData, PresentationStrings, AccountContext, ChatMessageReplyInfoType, Message, CGSize) -> (CGSize, () -> ChatMessageReplyInfoNode),
|
||||||
actionButtonsLayout: (AccountContext, ChatPresentationThemeData, PresentationChatBubbleCorners, PresentationStrings, ReplyMarkupMessageAttribute, Message, CGFloat) -> (minWidth: CGFloat, layout: (CGFloat) -> (CGSize, (Bool) -> ChatMessageActionButtonsNode)),
|
actionButtonsLayout: (AccountContext, ChatPresentationThemeData, PresentationChatBubbleCorners, PresentationStrings, ReplyMarkupMessageAttribute, Message, CGFloat) -> (minWidth: CGFloat, layout: (CGFloat) -> (CGSize, (Bool) -> ChatMessageActionButtonsNode)),
|
||||||
mosaicStatusLayout: (AccountContext, ChatPresentationData, Bool, Int?, String, ChatMessageDateAndStatusType, CGSize, [MessageReaction], Int) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode),
|
mosaicStatusLayout: (AccountContext, ChatPresentationData, Bool, Int?, String, ChatMessageDateAndStatusType, CGSize, [MessageReaction], Int, Bool) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode),
|
||||||
currentShareButtonNode: HighlightableButtonNode?,
|
currentShareButtonNode: HighlightableButtonNode?,
|
||||||
layoutConstants: ChatMessageItemLayoutConstants,
|
layoutConstants: ChatMessageItemLayoutConstants,
|
||||||
currentItem: ChatMessageItem?,
|
currentItem: ChatMessageItem?,
|
||||||
@ -1437,7 +1437,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mosaicStatusSizeAndApply = mosaicStatusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: 200.0, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies)
|
mosaicStatusSizeAndApply = mosaicStatusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: 200.0, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies, message.tags.contains(.pinned))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
var statusApply: ((Bool) -> Void)?
|
var statusApply: ((Bool) -> Void)?
|
||||||
|
|
||||||
if let statusType = statusType {
|
if let statusType = statusType {
|
||||||
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies)
|
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies, item.message.tags.contains(.pinned))
|
||||||
statusSize = size
|
statusSize = size
|
||||||
statusApply = apply
|
statusApply = apply
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.dateNode)
|
self.addSubnode(self.dateNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func asyncLayout() -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ edited: Bool, _ impressionCount: Int?, _ dateText: String, _ type: ChatMessageDateAndStatusType, _ constrainedSize: CGSize, _ reactions: [MessageReaction], _ replies: Int) -> (CGSize, (Bool) -> Void) {
|
func asyncLayout() -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ edited: Bool, _ impressionCount: Int?, _ dateText: String, _ type: ChatMessageDateAndStatusType, _ constrainedSize: CGSize, _ reactions: [MessageReaction], _ replies: Int, _ isPinned: Bool) -> (CGSize, (Bool) -> Void) {
|
||||||
let dateLayout = TextNode.asyncLayout(self.dateNode)
|
let dateLayout = TextNode.asyncLayout(self.dateNode)
|
||||||
|
|
||||||
var checkReadNode = self.checkReadNode
|
var checkReadNode = self.checkReadNode
|
||||||
@ -200,7 +200,7 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
|
|
||||||
let previousLayoutSize = self.layoutSize
|
let previousLayoutSize = self.layoutSize
|
||||||
|
|
||||||
return { context, presentationData, edited, impressionCount, dateText, type, constrainedSize, reactions, replyCount in
|
return { context, presentationData, edited, impressionCount, dateText, type, constrainedSize, reactions, replyCount, isPinned in
|
||||||
let dateColor: UIColor
|
let dateColor: UIColor
|
||||||
var backgroundImage: UIImage?
|
var backgroundImage: UIImage?
|
||||||
var outgoingStatus: ChatMessageDateAndStatusOutgoingType?
|
var outgoingStatus: ChatMessageDateAndStatusOutgoingType?
|
||||||
@ -234,6 +234,8 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
if replyCount != 0 {
|
if replyCount != 0 {
|
||||||
repliesImage = graphics.incomingDateAndStatusRepliesIcon
|
repliesImage = graphics.incomingDateAndStatusRepliesIcon
|
||||||
|
} else if isPinned {
|
||||||
|
repliesImage = graphics.incomingDateAndStatusPinnedIcon
|
||||||
}
|
}
|
||||||
case let .BubbleOutgoing(status):
|
case let .BubbleOutgoing(status):
|
||||||
dateColor = presentationData.theme.theme.chat.message.outgoing.secondaryTextColor
|
dateColor = presentationData.theme.theme.chat.message.outgoing.secondaryTextColor
|
||||||
@ -248,6 +250,8 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
if replyCount != 0 {
|
if replyCount != 0 {
|
||||||
repliesImage = graphics.outgoingDateAndStatusRepliesIcon
|
repliesImage = graphics.outgoingDateAndStatusRepliesIcon
|
||||||
|
} else if isPinned {
|
||||||
|
repliesImage = graphics.outgoingDateAndStatusPinnedIcon
|
||||||
}
|
}
|
||||||
case .ImageIncoming:
|
case .ImageIncoming:
|
||||||
dateColor = presentationData.theme.theme.chat.message.mediaDateAndStatusTextColor
|
dateColor = presentationData.theme.theme.chat.message.mediaDateAndStatusTextColor
|
||||||
@ -262,6 +266,8 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
if replyCount != 0 {
|
if replyCount != 0 {
|
||||||
repliesImage = graphics.mediaRepliesIcon
|
repliesImage = graphics.mediaRepliesIcon
|
||||||
|
} else if isPinned {
|
||||||
|
repliesImage = graphics.mediaPinnedIcon
|
||||||
}
|
}
|
||||||
case let .ImageOutgoing(status):
|
case let .ImageOutgoing(status):
|
||||||
dateColor = presentationData.theme.theme.chat.message.mediaDateAndStatusTextColor
|
dateColor = presentationData.theme.theme.chat.message.mediaDateAndStatusTextColor
|
||||||
@ -277,6 +283,8 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
if replyCount != 0 {
|
if replyCount != 0 {
|
||||||
repliesImage = graphics.mediaRepliesIcon
|
repliesImage = graphics.mediaRepliesIcon
|
||||||
|
} else if isPinned {
|
||||||
|
repliesImage = graphics.mediaPinnedIcon
|
||||||
}
|
}
|
||||||
case .FreeIncoming:
|
case .FreeIncoming:
|
||||||
let serviceColor = serviceMessageColorComponents(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
let serviceColor = serviceMessageColorComponents(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||||
@ -292,6 +300,8 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
if replyCount != 0 {
|
if replyCount != 0 {
|
||||||
repliesImage = graphics.freeRepliesIcon
|
repliesImage = graphics.freeRepliesIcon
|
||||||
|
} else if isPinned {
|
||||||
|
repliesImage = graphics.freePinnedIcon
|
||||||
}
|
}
|
||||||
case let .FreeOutgoing(status):
|
case let .FreeOutgoing(status):
|
||||||
let serviceColor = serviceMessageColorComponents(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
let serviceColor = serviceMessageColorComponents(theme: presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
|
||||||
@ -308,6 +318,8 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
if replyCount != 0 {
|
if replyCount != 0 {
|
||||||
repliesImage = graphics.freeRepliesIcon
|
repliesImage = graphics.freeRepliesIcon
|
||||||
|
} else if isPinned {
|
||||||
|
repliesImage = graphics.freePinnedIcon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,6 +523,8 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
let layoutAndApply = makeReplyCountLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: countString, font: dateFont, textColor: dateColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: 100.0)))
|
let layoutAndApply = makeReplyCountLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: countString, font: dateFont, textColor: dateColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: 100.0, height: 100.0)))
|
||||||
reactionInset += 14.0 + layoutAndApply.0.size.width + 4.0
|
reactionInset += 14.0 + layoutAndApply.0.size.width + 4.0
|
||||||
replyCountLayoutAndApply = layoutAndApply
|
replyCountLayoutAndApply = layoutAndApply
|
||||||
|
} else if isPinned {
|
||||||
|
reactionInset += 12.0
|
||||||
}
|
}
|
||||||
|
|
||||||
leftInset += reactionInset
|
leftInset += reactionInset
|
||||||
@ -817,17 +831,17 @@ class ChatMessageDateAndStatusNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func asyncLayout(_ node: ChatMessageDateAndStatusNode?) -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ edited: Bool, _ impressionCount: Int?, _ dateText: String, _ type: ChatMessageDateAndStatusType, _ constrainedSize: CGSize, _ reactions: [MessageReaction], _ replies: Int) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode) {
|
static func asyncLayout(_ node: ChatMessageDateAndStatusNode?) -> (_ context: AccountContext, _ presentationData: ChatPresentationData, _ edited: Bool, _ impressionCount: Int?, _ dateText: String, _ type: ChatMessageDateAndStatusType, _ constrainedSize: CGSize, _ reactions: [MessageReaction], _ replies: Int, _ isPinned: Bool) -> (CGSize, (Bool) -> ChatMessageDateAndStatusNode) {
|
||||||
let currentLayout = node?.asyncLayout()
|
let currentLayout = node?.asyncLayout()
|
||||||
return { context, presentationData, edited, impressionCount, dateText, type, constrainedSize, reactions, replies in
|
return { context, presentationData, edited, impressionCount, dateText, type, constrainedSize, reactions, replies, isPinned in
|
||||||
let resultNode: ChatMessageDateAndStatusNode
|
let resultNode: ChatMessageDateAndStatusNode
|
||||||
let resultSizeAndApply: (CGSize, (Bool) -> Void)
|
let resultSizeAndApply: (CGSize, (Bool) -> Void)
|
||||||
if let node = node, let currentLayout = currentLayout {
|
if let node = node, let currentLayout = currentLayout {
|
||||||
resultNode = node
|
resultNode = node
|
||||||
resultSizeAndApply = currentLayout(context, presentationData, edited, impressionCount, dateText, type, constrainedSize, reactions, replies)
|
resultSizeAndApply = currentLayout(context, presentationData, edited, impressionCount, dateText, type, constrainedSize, reactions, replies, isPinned)
|
||||||
} else {
|
} else {
|
||||||
resultNode = ChatMessageDateAndStatusNode()
|
resultNode = ChatMessageDateAndStatusNode()
|
||||||
resultSizeAndApply = resultNode.asyncLayout()(context, presentationData, edited, impressionCount, dateText, type, constrainedSize, reactions, replies)
|
resultSizeAndApply = resultNode.asyncLayout()(context, presentationData, edited, impressionCount, dateText, type, constrainedSize, reactions, replies, isPinned)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (resultSizeAndApply.0, { animated in
|
return (resultSizeAndApply.0, { animated in
|
||||||
|
@ -327,7 +327,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
|||||||
|
|
||||||
let dateText = stringForMessageTimestampStatus(accountPeerId: context.account.peerId, message: message, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, strings: presentationData.strings, reactionCount: dateReactionCount)
|
let dateText = stringForMessageTimestampStatus(accountPeerId: context.account.peerId, message: message, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, strings: presentationData.strings, reactionCount: dateReactionCount)
|
||||||
|
|
||||||
let (size, apply) = statusLayout(context, presentationData, edited, viewCount, dateText, statusType, constrainedSize, dateReactions, dateReplies)
|
let (size, apply) = statusLayout(context, presentationData, edited, viewCount, dateText, statusType, constrainedSize, dateReactions, dateReplies, message.tags.contains(.pinned))
|
||||||
statusSize = size
|
statusSize = size
|
||||||
statusApply = apply
|
statusApply = apply
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||||||
} else {
|
} else {
|
||||||
maxDateAndStatusWidth = width - videoFrame.midX - 85.0
|
maxDateAndStatusWidth = width - videoFrame.midX - 85.0
|
||||||
}
|
}
|
||||||
let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: max(1.0, maxDateAndStatusWidth), height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies)
|
let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.context, item.presentationData, edited && !sentViaBot, viewCount, dateText, statusType, CGSize(width: max(1.0, maxDateAndStatusWidth), height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies, item.message.tags.contains(.pinned))
|
||||||
|
|
||||||
var contentSize = imageSize
|
var contentSize = imageSize
|
||||||
var dateAndStatusOverflow = false
|
var dateAndStatusOverflow = false
|
||||||
|
@ -246,7 +246,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
var statusApply: ((Bool) -> Void)?
|
var statusApply: ((Bool) -> Void)?
|
||||||
|
|
||||||
if let statusType = statusType {
|
if let statusType = statusType {
|
||||||
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies)
|
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: constrainedSize.width, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies, item.message.tags.contains(.pinned))
|
||||||
statusSize = size
|
statusSize = size
|
||||||
statusApply = apply
|
statusApply = apply
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
var statusApply: ((Bool) -> Void)?
|
var statusApply: ((Bool) -> Void)?
|
||||||
|
|
||||||
if let statusType = statusType {
|
if let statusType = statusType {
|
||||||
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: imageSize.width - 30.0, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies)
|
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: imageSize.width - 30.0, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies, item.message.tags.contains(.pinned))
|
||||||
statusSize = size
|
statusSize = size
|
||||||
statusApply = apply
|
statusApply = apply
|
||||||
}
|
}
|
||||||
|
@ -1074,7 +1074,7 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
var statusApply: ((Bool) -> Void)?
|
var statusApply: ((Bool) -> Void)?
|
||||||
|
|
||||||
if let statusType = statusType {
|
if let statusType = statusType {
|
||||||
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, textConstrainedSize, dateReactions, dateReplies)
|
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, textConstrainedSize, dateReactions, dateReplies, item.message.tags.contains(.pinned))
|
||||||
statusSize = size
|
statusSize = size
|
||||||
statusApply = apply
|
statusApply = apply
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ class ChatMessageRestrictedBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
var statusApply: ((Bool) -> Void)?
|
var statusApply: ((Bool) -> Void)?
|
||||||
|
|
||||||
if let statusType = statusType {
|
if let statusType = statusType {
|
||||||
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, textConstrainedSize, dateReactions, dateReplies)
|
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, textConstrainedSize, dateReactions, dateReplies, item.message.tags.contains(.pinned))
|
||||||
statusSize = size
|
statusSize = size
|
||||||
statusApply = apply
|
statusApply = apply
|
||||||
}
|
}
|
||||||
|
@ -382,7 +382,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
|||||||
|
|
||||||
let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .regular, reactionCount: dateReactionCount)
|
let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .regular, reactionCount: dateReactionCount)
|
||||||
|
|
||||||
let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies)
|
let (dateAndStatusSize, dateAndStatusApply) = makeDateAndStatusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), dateReactions, dateReplies, item.message.tags.contains(.pinned))
|
||||||
|
|
||||||
var viaBotApply: (TextNodeLayout, () -> TextNode)?
|
var viaBotApply: (TextNodeLayout, () -> TextNode)?
|
||||||
var replyInfoApply: (CGSize, () -> ChatMessageReplyInfoNode)?
|
var replyInfoApply: (CGSize, () -> ChatMessageReplyInfoNode)?
|
||||||
|
@ -169,7 +169,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
var statusApply: ((Bool) -> Void)?
|
var statusApply: ((Bool) -> Void)?
|
||||||
|
|
||||||
if let statusType = statusType {
|
if let statusType = statusType {
|
||||||
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, textConstrainedSize, dateReactions, dateReplies)
|
let (size, apply) = statusLayout(item.context, item.presentationData, edited, viewCount, dateText, statusType, textConstrainedSize, dateReactions, dateReplies, item.message.tags.contains(.pinned))
|
||||||
statusSize = size
|
statusSize = size
|
||||||
statusApply = apply
|
statusApply = apply
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ final class ChatPanelInterfaceInteraction {
|
|||||||
let sendSticker: (FileMediaReference, ASDisplayNode, CGRect) -> Bool
|
let sendSticker: (FileMediaReference, ASDisplayNode, CGRect) -> Bool
|
||||||
let unblockPeer: () -> Void
|
let unblockPeer: () -> Void
|
||||||
let pinMessage: (MessageId) -> Void
|
let pinMessage: (MessageId) -> Void
|
||||||
let unpinMessage: (MessageId) -> Void
|
let unpinMessage: (MessageId, Bool) -> Void
|
||||||
let shareAccountContact: () -> Void
|
let shareAccountContact: () -> Void
|
||||||
let reportPeer: () -> Void
|
let reportPeer: () -> Void
|
||||||
let presentPeerContact: () -> Void
|
let presentPeerContact: () -> Void
|
||||||
@ -171,7 +171,7 @@ final class ChatPanelInterfaceInteraction {
|
|||||||
sendSticker: @escaping (FileMediaReference, ASDisplayNode, CGRect) -> Bool,
|
sendSticker: @escaping (FileMediaReference, ASDisplayNode, CGRect) -> Bool,
|
||||||
unblockPeer: @escaping () -> Void,
|
unblockPeer: @escaping () -> Void,
|
||||||
pinMessage: @escaping (MessageId) -> Void,
|
pinMessage: @escaping (MessageId) -> Void,
|
||||||
unpinMessage: @escaping (MessageId) -> Void,
|
unpinMessage: @escaping (MessageId, Bool) -> Void,
|
||||||
shareAccountContact: @escaping () -> Void,
|
shareAccountContact: @escaping () -> Void,
|
||||||
reportPeer: @escaping () -> Void,
|
reportPeer: @escaping () -> Void,
|
||||||
presentPeerContact: @escaping () -> Void,
|
presentPeerContact: @escaping () -> Void,
|
||||||
|
@ -362,7 +362,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||||||
|
|
||||||
@objc func closePressed() {
|
@objc func closePressed() {
|
||||||
if let interfaceInteraction = self.interfaceInteraction, let message = self.currentMessage {
|
if let interfaceInteraction = self.interfaceInteraction, let message = self.currentMessage {
|
||||||
interfaceInteraction.unpinMessage(message.message.id)
|
interfaceInteraction.unpinMessage(message.message.id, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ final class ChatRecentActionsController: TelegramBaseController {
|
|||||||
return false
|
return false
|
||||||
}, unblockPeer: {
|
}, unblockPeer: {
|
||||||
}, pinMessage: { _ in
|
}, pinMessage: { _ in
|
||||||
}, unpinMessage: { _ in
|
}, unpinMessage: { _, _ in
|
||||||
}, shareAccountContact: {
|
}, shareAccountContact: {
|
||||||
}, reportPeer: {
|
}, reportPeer: {
|
||||||
}, presentPeerContact: {
|
}, presentPeerContact: {
|
||||||
|
@ -143,7 +143,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
|||||||
} else if params.standalone {
|
} else if params.standalone {
|
||||||
location = .recentActions(params.message)
|
location = .recentActions(params.message)
|
||||||
} else {
|
} else {
|
||||||
location = .messages(peerId: params.message.id.peerId, tagMask: .voiceOrInstantVideo, at: params.message.id)
|
location = .messages(chatLocation: params.chatLocation ?? .peer(params.message.id.peerId), tagMask: .voiceOrInstantVideo, at: params.message.id)
|
||||||
}
|
}
|
||||||
playerType = .voice
|
playerType = .voice
|
||||||
} else if file.isMusic && params.message.tags.contains(.music) {
|
} else if file.isMusic && params.message.tags.contains(.music) {
|
||||||
@ -152,7 +152,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
|||||||
} else if params.standalone {
|
} else if params.standalone {
|
||||||
location = .recentActions(params.message)
|
location = .recentActions(params.message)
|
||||||
} else {
|
} else {
|
||||||
location = .messages(peerId: params.message.id.peerId, tagMask: .music, at: params.message.id)
|
location = .messages(chatLocation: params.chatLocation ?? .peer(params.message.id.peerId), tagMask: .music, at: params.message.id)
|
||||||
}
|
}
|
||||||
playerType = .music
|
playerType = .music
|
||||||
} else {
|
} else {
|
||||||
@ -163,7 +163,7 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
|||||||
}
|
}
|
||||||
playerType = (file.isVoice || file.isInstantVideo) ? .voice : .music
|
playerType = (file.isVoice || file.isInstantVideo) ? .voice : .music
|
||||||
}
|
}
|
||||||
params.context.sharedContext.mediaManager.setPlaylist((params.context.account, PeerMessagesMediaPlaylist(postbox: params.context.account.postbox, network: params.context.account.network, location: location)), type: playerType, control: control)
|
params.context.sharedContext.mediaManager.setPlaylist((params.context.account, PeerMessagesMediaPlaylist(context: params.context, location: location, chatLocationContextHolder: params.chatLocationContextHolder)), type: playerType, control: control)
|
||||||
return true
|
return true
|
||||||
case let .gallery(gallery):
|
case let .gallery(gallery):
|
||||||
params.dismissInput()
|
params.dismissInput()
|
||||||
|
@ -405,7 +405,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
|
|||||||
return false
|
return false
|
||||||
}, unblockPeer: {
|
}, unblockPeer: {
|
||||||
}, pinMessage: { _ in
|
}, pinMessage: { _ in
|
||||||
}, unpinMessage: { _ in
|
}, unpinMessage: { _, _ in
|
||||||
}, shareAccountContact: {
|
}, shareAccountContact: {
|
||||||
}, reportPeer: {
|
}, reportPeer: {
|
||||||
}, presentPeerContact: {
|
}, presentPeerContact: {
|
||||||
|
@ -307,9 +307,9 @@ private struct PlaybackStack {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
||||||
private let postbox: Postbox
|
private let context: AccountContext
|
||||||
private let network: Network
|
|
||||||
private let messagesLocation: PeerMessagesPlaylistLocation
|
private let messagesLocation: PeerMessagesPlaylistLocation
|
||||||
|
private let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>?
|
||||||
|
|
||||||
var location: SharedMediaPlaylistLocation {
|
var location: SharedMediaPlaylistLocation {
|
||||||
return self.messagesLocation
|
return self.messagesLocation
|
||||||
@ -338,13 +338,13 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
return self.stateValue.get()
|
return self.stateValue.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(postbox: Postbox, network: Network, location: PeerMessagesPlaylistLocation) {
|
init(context: AccountContext, location: PeerMessagesPlaylistLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>?) {
|
||||||
assert(Queue.mainQueue().isCurrent())
|
assert(Queue.mainQueue().isCurrent())
|
||||||
|
|
||||||
self.id = location.playlistId
|
self.id = location.playlistId
|
||||||
|
|
||||||
self.postbox = postbox
|
self.context = context
|
||||||
self.network = network
|
self.chatLocationContextHolder = chatLocationContextHolder
|
||||||
self.messagesLocation = location
|
self.messagesLocation = location
|
||||||
|
|
||||||
switch self.messagesLocation {
|
switch self.messagesLocation {
|
||||||
@ -446,7 +446,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
self.currentlyObservedMessageId = item?.message.id
|
self.currentlyObservedMessageId = item?.message.id
|
||||||
if let id = item?.message.id {
|
if let id = item?.message.id {
|
||||||
let key: PostboxViewKey = .messages(Set([id]))
|
let key: PostboxViewKey = .messages(Set([id]))
|
||||||
self.currentlyObservedMessageDisposable.set((self.postbox.combinedView(keys: [key])
|
self.currentlyObservedMessageDisposable.set((self.context.account.postbox.combinedView(keys: [key])
|
||||||
|> filter { views in
|
|> filter { views in
|
||||||
if let view = views.views[key] as? MessagesView {
|
if let view = views.views[key] as? MessagesView {
|
||||||
if !view.messages.isEmpty {
|
if !view.messages.isEmpty {
|
||||||
@ -479,15 +479,15 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
switch anchor {
|
switch anchor {
|
||||||
case let .messageId(messageId):
|
case let .messageId(messageId):
|
||||||
switch self.messagesLocation {
|
switch self.messagesLocation {
|
||||||
case let .messages(peerId, tagMask, _):
|
case let .messages(chatLocation, tagMask, _):
|
||||||
let historySignal = self.postbox.messageAtId(messageId)
|
let historySignal = self.context.account.postbox.messageAtId(messageId)
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> mapToSignal { message -> Signal<(Message, [Message])?, NoError> in
|
|> mapToSignal { message -> Signal<(Message, [Message])?, NoError> in
|
||||||
guard let message = message else {
|
guard let message = message else {
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.postbox.aroundMessageHistoryViewForLocation(.peer(peerId), anchor: .index(message.index), count: 10, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tagMask, namespaces: namespaces, orderStatistics: [])
|
return self.context.account.postbox.aroundMessageHistoryViewForLocation(self.context.chatLocationInput(for: chatLocation, contextHolder: self.chatLocationContextHolder ?? Atomic<ChatLocationContextHolder?>(value: nil)), anchor: .index(message.index), count: 10, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tagMask, namespaces: namespaces, orderStatistics: [])
|
||||||
|> mapToSignal { view -> Signal<(Message, [Message])?, NoError> in
|
|> mapToSignal { view -> Signal<(Message, [Message])?, NoError> in
|
||||||
if let (message, aroundMessages, _) = navigatedMessageFromView(view.0, anchorIndex: message.index, position: .exact) {
|
if let (message, aroundMessages, _) = navigatedMessageFromView(view.0, anchorIndex: message.index, position: .exact) {
|
||||||
return .single((message, aroundMessages))
|
return .single((message, aroundMessages))
|
||||||
@ -539,7 +539,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
default:
|
default:
|
||||||
self.navigationDisposable.set((self.postbox.messageAtId(messageId)
|
self.navigationDisposable.set((self.context.account.postbox.messageAtId(messageId)
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] message in
|
|> deliverOnMainQueue).start(next: { [weak self] message in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
@ -559,7 +559,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
}
|
}
|
||||||
case let .index(index):
|
case let .index(index):
|
||||||
switch self.messagesLocation {
|
switch self.messagesLocation {
|
||||||
case let .messages(peerId, tagMask, _):
|
case let .messages(chatLocation, tagMask, _):
|
||||||
let inputIndex: Signal<MessageIndex, NoError>
|
let inputIndex: Signal<MessageIndex, NoError>
|
||||||
let looping = self.looping
|
let looping = self.looping
|
||||||
switch self.order {
|
switch self.order {
|
||||||
@ -567,7 +567,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
inputIndex = .single(index)
|
inputIndex = .single(index)
|
||||||
case .random:
|
case .random:
|
||||||
var playbackStack = self.playbackStack
|
var playbackStack = self.playbackStack
|
||||||
inputIndex = self.postbox.transaction { transaction -> MessageIndex in
|
inputIndex = self.context.account.postbox.transaction { transaction -> MessageIndex in
|
||||||
if case let .random(previous) = navigation, previous {
|
if case let .random(previous) = navigation, previous {
|
||||||
let _ = playbackStack.pop()
|
let _ = playbackStack.pop()
|
||||||
while true {
|
while true {
|
||||||
@ -580,12 +580,12 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return transaction.findRandomMessage(peerId: peerId, namespace: Namespaces.Message.Cloud, tag: tagMask, ignoreIds: (playbackStack.ids, playbackStack.set)) ?? index
|
return transaction.findRandomMessage(peerId: chatLocation.peerId, namespace: Namespaces.Message.Cloud, tag: tagMask, ignoreIds: (playbackStack.ids, playbackStack.set)) ?? index
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let historySignal = inputIndex
|
let historySignal = inputIndex
|
||||||
|> mapToSignal { inputIndex -> Signal<(Message, [Message])?, NoError> in
|
|> mapToSignal { inputIndex -> Signal<(Message, [Message])?, NoError> in
|
||||||
return self.postbox.aroundMessageHistoryViewForLocation(.peer(peerId), anchor: .index(inputIndex), count: 10, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tagMask, namespaces: namespaces, orderStatistics: [])
|
return self.context.account.postbox.aroundMessageHistoryViewForLocation(self.context.chatLocationInput(for: chatLocation, contextHolder: self.chatLocationContextHolder ?? Atomic<ChatLocationContextHolder?>(value: nil)), anchor: .index(inputIndex), count: 10, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tagMask, namespaces: namespaces, orderStatistics: [])
|
||||||
|> mapToSignal { view -> Signal<(Message, [Message])?, NoError> in
|
|> mapToSignal { view -> Signal<(Message, [Message])?, NoError> in
|
||||||
let position: NavigatedMessageFromViewPosition
|
let position: NavigatedMessageFromViewPosition
|
||||||
switch navigation {
|
switch navigation {
|
||||||
@ -615,7 +615,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
} else {
|
} else {
|
||||||
viewIndex = .lowerBound
|
viewIndex = .lowerBound
|
||||||
}
|
}
|
||||||
return self.postbox.aroundMessageHistoryViewForLocation(.peer(peerId), anchor: viewIndex, count: 10, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tagMask, namespaces: namespaces, orderStatistics: [])
|
return self.context.account.postbox.aroundMessageHistoryViewForLocation(self.context.chatLocationInput(for: chatLocation, contextHolder: self.chatLocationContextHolder ?? Atomic<ChatLocationContextHolder?>(value: nil)), anchor: viewIndex, count: 10, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: [], tagMask: tagMask, namespaces: namespaces, orderStatistics: [])
|
||||||
|> mapToSignal { view -> Signal<(Message, [Message])?, NoError> in
|
|> mapToSignal { view -> Signal<(Message, [Message])?, NoError> in
|
||||||
let position: NavigatedMessageFromViewPosition
|
let position: NavigatedMessageFromViewPosition
|
||||||
switch navigation {
|
switch navigation {
|
||||||
@ -657,7 +657,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
case .singleMessage:
|
case .singleMessage:
|
||||||
self.navigationDisposable.set((self.postbox.messageAtId(index.id)
|
self.navigationDisposable.set((self.context.account.postbox.messageAtId(index.id)
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] message in
|
|> deliverOnMainQueue).start(next: { [weak self] message in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
@ -815,7 +815,7 @@ final class PeerMessagesMediaPlaylist: SharedMediaPlaylist {
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
let _ = markMessageContentAsConsumedInteractively(postbox: self.postbox, messageId: item.message.id).start()
|
let _ = markMessageContentAsConsumedInteractively(postbox: self.context.account.postbox, messageId: item.message.id).start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user