Comments update

This commit is contained in:
Ali 2020-09-08 12:25:37 +01:00
parent 70b5832d17
commit 01ca998b2c
24 changed files with 2595 additions and 2419 deletions

View File

@ -3,7 +3,7 @@
@implementation Serialization @implementation Serialization
- (NSUInteger)currentLayer { - (NSUInteger)currentLayer {
return 120; return 119;
} }
- (id _Nullable)parseMessage:(NSData * _Nullable)data { - (id _Nullable)parseMessage:(NSData * _Nullable)data {

View File

@ -5755,3 +5755,5 @@ Any member of this group will be able to see messages in the channel.";
"ChatList.Search.NoResults" = "No Results"; "ChatList.Search.NoResults" = "No Results";
"ChatList.Search.NoResultsDescription" = "There were no results for \"%@\".\nTry a new search."; "ChatList.Search.NoResultsDescription" = "There were no results for \"%@\".\nTry a new search.";
"Conversation.InputTextAnonymousPlaceholder" = "Send anonymously";

View File

@ -15,8 +15,8 @@ public enum ChatHistoryLocation: Equatable {
} }
public struct ChatHistoryLocationInput: Equatable { public struct ChatHistoryLocationInput: Equatable {
public let content: ChatHistoryLocation public var content: ChatHistoryLocation
public let id: Int32 public var id: Int32
public init(content: ChatHistoryLocation, id: Int32) { public init(content: ChatHistoryLocation, id: Int32) {
self.content = content self.content = content

View File

@ -487,7 +487,7 @@ private func stringForRight(strings: PresentationStrings, right: TelegramChatAdm
return strings.Channel_EditAdmin_PermissionPinMessages return strings.Channel_EditAdmin_PermissionPinMessages
} else if right.contains(.canAddAdmins) { } else if right.contains(.canAddAdmins) {
return strings.Channel_EditAdmin_PermissionAddAdmins return strings.Channel_EditAdmin_PermissionAddAdmins
} else if right.contans(.canBeAnonymous) { } else if right.contains(.canBeAnonymous) {
return strings.Channel_AdminLog_CanBeAnonymous return strings.Channel_AdminLog_CanBeAnonymous
} else { } else {
return "" return ""
@ -617,6 +617,37 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
} }
if isCreator { if isCreator {
if isGroup {
entries.append(.rightsTitle(presentationData.theme, presentationData.strings.Channel_EditAdmin_PermissionsHeader))
let accountUserRightsFlags: TelegramChatAdminRightsFlags
if channel.flags.contains(.isCreator) {
accountUserRightsFlags = maskRightsFlags
} else if let adminRights = channel.adminRights {
accountUserRightsFlags = maskRightsFlags.intersection(adminRights.flags)
} else {
accountUserRightsFlags = []
}
let currentRightsFlags: TelegramChatAdminRightsFlags
if let updatedFlags = state.updatedFlags {
currentRightsFlags = updatedFlags
} else if let initialParticipant = initialParticipant, case let .member(_, _, maybeAdminRights, _, _) = initialParticipant, let adminRights = maybeAdminRights {
currentRightsFlags = adminRights.rights.flags
} else if let initialParticipant = initialParticipant, case let .creator(_, maybeAdminRights, _) = initialParticipant, let adminRights = maybeAdminRights {
currentRightsFlags = adminRights.rights.flags
} else {
currentRightsFlags = accountUserRightsFlags.subtracting(.canAddAdmins)
}
var index = 0
for right in rightsOrder {
if accountUserRightsFlags.contains(right) {
entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, defaultBannedRights: channel.defaultBannedRights), right, currentRightsFlags, currentRightsFlags.contains(right), right == .canBeAnonymous))
index += 1
}
}
}
} else { } else {
entries.append(.rightsTitle(presentationData.theme, presentationData.strings.Channel_EditAdmin_PermissionsHeader)) entries.append(.rightsTitle(presentationData.theme, presentationData.strings.Channel_EditAdmin_PermissionsHeader))

View File

@ -550,12 +550,12 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1387279939] = { return Api.MessageInteractionCounters.parse_messageInteractionCounters($0) } dict[-1387279939] = { return Api.MessageInteractionCounters.parse_messageInteractionCounters($0) }
dict[-1107852396] = { return Api.stats.BroadcastStats.parse_broadcastStats($0) } dict[-1107852396] = { return Api.stats.BroadcastStats.parse_broadcastStats($0) }
dict[-484987010] = { return Api.Updates.parse_updatesTooLong($0) } dict[-484987010] = { return Api.Updates.parse_updatesTooLong($0) }
dict[-1857044719] = { return Api.Updates.parse_updateShortMessage($0) }
dict[377562760] = { return Api.Updates.parse_updateShortChatMessage($0) }
dict[2027216577] = { return Api.Updates.parse_updateShort($0) } dict[2027216577] = { return Api.Updates.parse_updateShort($0) }
dict[1918567619] = { return Api.Updates.parse_updatesCombined($0) } dict[1918567619] = { return Api.Updates.parse_updatesCombined($0) }
dict[1957577280] = { return Api.Updates.parse_updates($0) } dict[1957577280] = { return Api.Updates.parse_updates($0) }
dict[301019932] = { return Api.Updates.parse_updateShortSentMessage($0) } dict[301019932] = { return Api.Updates.parse_updateShortSentMessage($0) }
dict[580309704] = { return Api.Updates.parse_updateShortMessage($0) }
dict[1076714939] = { return Api.Updates.parse_updateShortChatMessage($0) }
dict[-276825834] = { return Api.stats.MegagroupStats.parse_megagroupStats($0) } dict[-276825834] = { return Api.stats.MegagroupStats.parse_megagroupStats($0) }
dict[-884757282] = { return Api.StatsAbsValueAndPrev.parse_statsAbsValueAndPrev($0) } dict[-884757282] = { return Api.StatsAbsValueAndPrev.parse_statsAbsValueAndPrev($0) }
dict[1038967584] = { return Api.MessageMedia.parse_messageMediaEmpty($0) } dict[1038967584] = { return Api.MessageMedia.parse_messageMediaEmpty($0) }
@ -607,7 +607,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1820043071] = { return Api.User.parse_user($0) } dict[-1820043071] = { return Api.User.parse_user($0) }
dict[-2082087340] = { return Api.Message.parse_messageEmpty($0) } dict[-2082087340] = { return Api.Message.parse_messageEmpty($0) }
dict[998150060] = { return Api.Message.parse_message($0) } dict[998150060] = { return Api.Message.parse_message($0) }
dict[797820163] = { return Api.Message.parse_messageService($0) } dict[-1245570157] = { return Api.Message.parse_messageService($0) }
dict[831924812] = { return Api.StatsGroupTopInviter.parse_statsGroupTopInviter($0) } dict[831924812] = { return Api.StatsGroupTopInviter.parse_statsGroupTopInviter($0) }
dict[186120336] = { return Api.messages.RecentStickers.parse_recentStickersNotModified($0) } dict[186120336] = { return Api.messages.RecentStickers.parse_recentStickersNotModified($0) }
dict[586395571] = { return Api.messages.RecentStickers.parse_recentStickers($0) } dict[586395571] = { return Api.messages.RecentStickers.parse_recentStickers($0) }

View File

@ -15841,12 +15841,12 @@ public extension Api {
} }
public enum Updates: TypeConstructorDescription { public enum Updates: TypeConstructorDescription {
case updatesTooLong case updatesTooLong
case updateShortMessage(flags: Int32, id: Int32, userId: Int32, message: String, pts: Int32, ptsCount: Int32, date: Int32, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int32?, replyToMsgId: Int32?, entities: [Api.MessageEntity]?)
case updateShortChatMessage(flags: Int32, id: Int32, fromId: Int32, chatId: Int32, message: String, pts: Int32, ptsCount: Int32, date: Int32, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int32?, replyToMsgId: Int32?, entities: [Api.MessageEntity]?)
case updateShort(update: Api.Update, date: Int32) case updateShort(update: Api.Update, date: Int32)
case updatesCombined(updates: [Api.Update], users: [Api.User], chats: [Api.Chat], date: Int32, seqStart: Int32, seq: Int32) case updatesCombined(updates: [Api.Update], users: [Api.User], chats: [Api.Chat], date: Int32, seqStart: Int32, seq: Int32)
case updates(updates: [Api.Update], users: [Api.User], chats: [Api.Chat], date: Int32, seq: Int32) case updates(updates: [Api.Update], users: [Api.User], chats: [Api.Chat], date: Int32, seq: Int32)
case updateShortSentMessage(flags: Int32, id: Int32, pts: Int32, ptsCount: Int32, date: Int32, media: Api.MessageMedia?, entities: [Api.MessageEntity]?) case updateShortSentMessage(flags: Int32, id: Int32, pts: Int32, ptsCount: Int32, date: Int32, media: Api.MessageMedia?, entities: [Api.MessageEntity]?)
case updateShortMessage(flags: Int32, id: Int32, userId: Int32, message: String, pts: Int32, ptsCount: Int32, date: Int32, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int32?, replyTo: Api.MessageReplyHeader?, entities: [Api.MessageEntity]?)
case updateShortChatMessage(flags: Int32, id: Int32, fromId: Int32, chatId: Int32, message: String, pts: Int32, ptsCount: Int32, date: Int32, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int32?, replyTo: Api.MessageReplyHeader?, entities: [Api.MessageEntity]?)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
@ -15855,47 +15855,6 @@ public extension Api {
buffer.appendInt32(-484987010) buffer.appendInt32(-484987010)
} }
break
case .updateShortMessage(let flags, let id, let userId, let message, let pts, let ptsCount, let date, let fwdFrom, let viaBotId, let replyToMsgId, let entities):
if boxed {
buffer.appendInt32(-1857044719)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
serializeInt32(userId, buffer: buffer, boxed: false)
serializeString(message, buffer: buffer, boxed: false)
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 2) != 0 {fwdFrom!.serialize(buffer, true)}
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(viaBotId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 7) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(entities!.count))
for item in entities! {
item.serialize(buffer, true)
}}
break
case .updateShortChatMessage(let flags, let id, let fromId, let chatId, let message, let pts, let ptsCount, let date, let fwdFrom, let viaBotId, let replyToMsgId, let entities):
if boxed {
buffer.appendInt32(377562760)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
serializeInt32(fromId, buffer: buffer, boxed: false)
serializeInt32(chatId, buffer: buffer, boxed: false)
serializeString(message, buffer: buffer, boxed: false)
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 2) != 0 {fwdFrom!.serialize(buffer, true)}
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(viaBotId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 7) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(entities!.count))
for item in entities! {
item.serialize(buffer, true)
}}
break break
case .updateShort(let update, let date): case .updateShort(let update, let date):
if boxed { if boxed {
@ -15965,6 +15924,47 @@ public extension Api {
item.serialize(buffer, true) item.serialize(buffer, true)
}} }}
break break
case .updateShortMessage(let flags, let id, let userId, let message, let pts, let ptsCount, let date, let fwdFrom, let viaBotId, let replyTo, let entities):
if boxed {
buffer.appendInt32(580309704)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
serializeInt32(userId, buffer: buffer, boxed: false)
serializeString(message, buffer: buffer, boxed: false)
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 2) != 0 {fwdFrom!.serialize(buffer, true)}
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(viaBotId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 3) != 0 {replyTo!.serialize(buffer, true)}
if Int(flags) & Int(1 << 7) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(entities!.count))
for item in entities! {
item.serialize(buffer, true)
}}
break
case .updateShortChatMessage(let flags, let id, let fromId, let chatId, let message, let pts, let ptsCount, let date, let fwdFrom, let viaBotId, let replyTo, let entities):
if boxed {
buffer.appendInt32(1076714939)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false)
serializeInt32(fromId, buffer: buffer, boxed: false)
serializeInt32(chatId, buffer: buffer, boxed: false)
serializeString(message, buffer: buffer, boxed: false)
serializeInt32(pts, buffer: buffer, boxed: false)
serializeInt32(ptsCount, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 2) != 0 {fwdFrom!.serialize(buffer, true)}
if Int(flags) & Int(1 << 11) != 0 {serializeInt32(viaBotId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 3) != 0 {replyTo!.serialize(buffer, true)}
if Int(flags) & Int(1 << 7) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(entities!.count))
for item in entities! {
item.serialize(buffer, true)
}}
break
} }
} }
@ -15972,10 +15972,6 @@ public extension Api {
switch self { switch self {
case .updatesTooLong: case .updatesTooLong:
return ("updatesTooLong", []) return ("updatesTooLong", [])
case .updateShortMessage(let flags, let id, let userId, let message, let pts, let ptsCount, let date, let fwdFrom, let viaBotId, let replyToMsgId, let entities):
return ("updateShortMessage", [("flags", flags), ("id", id), ("userId", userId), ("message", message), ("pts", pts), ("ptsCount", ptsCount), ("date", date), ("fwdFrom", fwdFrom), ("viaBotId", viaBotId), ("replyToMsgId", replyToMsgId), ("entities", entities)])
case .updateShortChatMessage(let flags, let id, let fromId, let chatId, let message, let pts, let ptsCount, let date, let fwdFrom, let viaBotId, let replyToMsgId, let entities):
return ("updateShortChatMessage", [("flags", flags), ("id", id), ("fromId", fromId), ("chatId", chatId), ("message", message), ("pts", pts), ("ptsCount", ptsCount), ("date", date), ("fwdFrom", fwdFrom), ("viaBotId", viaBotId), ("replyToMsgId", replyToMsgId), ("entities", entities)])
case .updateShort(let update, let date): case .updateShort(let update, let date):
return ("updateShort", [("update", update), ("date", date)]) return ("updateShort", [("update", update), ("date", date)])
case .updatesCombined(let updates, let users, let chats, let date, let seqStart, let seq): case .updatesCombined(let updates, let users, let chats, let date, let seqStart, let seq):
@ -15984,105 +15980,16 @@ public extension Api {
return ("updates", [("updates", updates), ("users", users), ("chats", chats), ("date", date), ("seq", seq)]) return ("updates", [("updates", updates), ("users", users), ("chats", chats), ("date", date), ("seq", seq)])
case .updateShortSentMessage(let flags, let id, let pts, let ptsCount, let date, let media, let entities): case .updateShortSentMessage(let flags, let id, let pts, let ptsCount, let date, let media, let entities):
return ("updateShortSentMessage", [("flags", flags), ("id", id), ("pts", pts), ("ptsCount", ptsCount), ("date", date), ("media", media), ("entities", entities)]) return ("updateShortSentMessage", [("flags", flags), ("id", id), ("pts", pts), ("ptsCount", ptsCount), ("date", date), ("media", media), ("entities", entities)])
case .updateShortMessage(let flags, let id, let userId, let message, let pts, let ptsCount, let date, let fwdFrom, let viaBotId, let replyTo, let entities):
return ("updateShortMessage", [("flags", flags), ("id", id), ("userId", userId), ("message", message), ("pts", pts), ("ptsCount", ptsCount), ("date", date), ("fwdFrom", fwdFrom), ("viaBotId", viaBotId), ("replyTo", replyTo), ("entities", entities)])
case .updateShortChatMessage(let flags, let id, let fromId, let chatId, let message, let pts, let ptsCount, let date, let fwdFrom, let viaBotId, let replyTo, let entities):
return ("updateShortChatMessage", [("flags", flags), ("id", id), ("fromId", fromId), ("chatId", chatId), ("message", message), ("pts", pts), ("ptsCount", ptsCount), ("date", date), ("fwdFrom", fwdFrom), ("viaBotId", viaBotId), ("replyTo", replyTo), ("entities", entities)])
} }
} }
public static func parse_updatesTooLong(_ reader: BufferReader) -> Updates? { public static func parse_updatesTooLong(_ reader: BufferReader) -> Updates? {
return Api.Updates.updatesTooLong return Api.Updates.updatesTooLong
} }
public static func parse_updateShortMessage(_ reader: BufferReader) -> Updates? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: String?
_4 = parseString(reader)
var _5: Int32?
_5 = reader.readInt32()
var _6: Int32?
_6 = reader.readInt32()
var _7: Int32?
_7 = reader.readInt32()
var _8: Api.MessageFwdHeader?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_8 = Api.parse(reader, signature: signature) as? Api.MessageFwdHeader
} }
var _9: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_9 = reader.readInt32() }
var _10: Int32?
if Int(_1!) & Int(1 << 3) != 0 {_10 = reader.readInt32() }
var _11: [Api.MessageEntity]?
if Int(_1!) & Int(1 << 7) != 0 {if let _ = reader.readInt32() {
_11 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
let _c8 = (Int(_1!) & Int(1 << 2) == 0) || _8 != nil
let _c9 = (Int(_1!) & Int(1 << 11) == 0) || _9 != nil
let _c10 = (Int(_1!) & Int(1 << 3) == 0) || _10 != nil
let _c11 = (Int(_1!) & Int(1 << 7) == 0) || _11 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 {
return Api.Updates.updateShortMessage(flags: _1!, id: _2!, userId: _3!, message: _4!, pts: _5!, ptsCount: _6!, date: _7!, fwdFrom: _8, viaBotId: _9, replyToMsgId: _10, entities: _11)
}
else {
return nil
}
}
public static func parse_updateShortChatMessage(_ reader: BufferReader) -> Updates? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
var _5: String?
_5 = parseString(reader)
var _6: Int32?
_6 = reader.readInt32()
var _7: Int32?
_7 = reader.readInt32()
var _8: Int32?
_8 = reader.readInt32()
var _9: Api.MessageFwdHeader?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_9 = Api.parse(reader, signature: signature) as? Api.MessageFwdHeader
} }
var _10: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_10 = reader.readInt32() }
var _11: Int32?
if Int(_1!) & Int(1 << 3) != 0 {_11 = reader.readInt32() }
var _12: [Api.MessageEntity]?
if Int(_1!) & Int(1 << 7) != 0 {if let _ = reader.readInt32() {
_12 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
let _c8 = _8 != nil
let _c9 = (Int(_1!) & Int(1 << 2) == 0) || _9 != nil
let _c10 = (Int(_1!) & Int(1 << 11) == 0) || _10 != nil
let _c11 = (Int(_1!) & Int(1 << 3) == 0) || _11 != nil
let _c12 = (Int(_1!) & Int(1 << 7) == 0) || _12 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 {
return Api.Updates.updateShortChatMessage(flags: _1!, id: _2!, fromId: _3!, chatId: _4!, message: _5!, pts: _6!, ptsCount: _7!, date: _8!, fwdFrom: _9, viaBotId: _10, replyToMsgId: _11, entities: _12)
}
else {
return nil
}
}
public static func parse_updateShort(_ reader: BufferReader) -> Updates? { public static func parse_updateShort(_ reader: BufferReader) -> Updates? {
var _1: Api.Update? var _1: Api.Update?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -16193,6 +16100,103 @@ public extension Api {
return nil return nil
} }
} }
public static func parse_updateShortMessage(_ reader: BufferReader) -> Updates? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: String?
_4 = parseString(reader)
var _5: Int32?
_5 = reader.readInt32()
var _6: Int32?
_6 = reader.readInt32()
var _7: Int32?
_7 = reader.readInt32()
var _8: Api.MessageFwdHeader?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_8 = Api.parse(reader, signature: signature) as? Api.MessageFwdHeader
} }
var _9: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_9 = reader.readInt32() }
var _10: Api.MessageReplyHeader?
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
_10 = Api.parse(reader, signature: signature) as? Api.MessageReplyHeader
} }
var _11: [Api.MessageEntity]?
if Int(_1!) & Int(1 << 7) != 0 {if let _ = reader.readInt32() {
_11 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
let _c8 = (Int(_1!) & Int(1 << 2) == 0) || _8 != nil
let _c9 = (Int(_1!) & Int(1 << 11) == 0) || _9 != nil
let _c10 = (Int(_1!) & Int(1 << 3) == 0) || _10 != nil
let _c11 = (Int(_1!) & Int(1 << 7) == 0) || _11 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 {
return Api.Updates.updateShortMessage(flags: _1!, id: _2!, userId: _3!, message: _4!, pts: _5!, ptsCount: _6!, date: _7!, fwdFrom: _8, viaBotId: _9, replyTo: _10, entities: _11)
}
else {
return nil
}
}
public static func parse_updateShortChatMessage(_ reader: BufferReader) -> Updates? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int32?
_2 = reader.readInt32()
var _3: Int32?
_3 = reader.readInt32()
var _4: Int32?
_4 = reader.readInt32()
var _5: String?
_5 = parseString(reader)
var _6: Int32?
_6 = reader.readInt32()
var _7: Int32?
_7 = reader.readInt32()
var _8: Int32?
_8 = reader.readInt32()
var _9: Api.MessageFwdHeader?
if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() {
_9 = Api.parse(reader, signature: signature) as? Api.MessageFwdHeader
} }
var _10: Int32?
if Int(_1!) & Int(1 << 11) != 0 {_10 = reader.readInt32() }
var _11: Api.MessageReplyHeader?
if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
_11 = Api.parse(reader, signature: signature) as? Api.MessageReplyHeader
} }
var _12: [Api.MessageEntity]?
if Int(_1!) & Int(1 << 7) != 0 {if let _ = reader.readInt32() {
_12 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
} }
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
let _c4 = _4 != nil
let _c5 = _5 != nil
let _c6 = _6 != nil
let _c7 = _7 != nil
let _c8 = _8 != nil
let _c9 = (Int(_1!) & Int(1 << 2) == 0) || _9 != nil
let _c10 = (Int(_1!) & Int(1 << 11) == 0) || _10 != nil
let _c11 = (Int(_1!) & Int(1 << 3) == 0) || _11 != nil
let _c12 = (Int(_1!) & Int(1 << 7) == 0) || _12 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 {
return Api.Updates.updateShortChatMessage(flags: _1!, id: _2!, fromId: _3!, chatId: _4!, message: _5!, pts: _6!, ptsCount: _7!, date: _8!, fwdFrom: _9, viaBotId: _10, replyTo: _11, entities: _12)
}
else {
return nil
}
}
} }
public enum StatsAbsValueAndPrev: TypeConstructorDescription { public enum StatsAbsValueAndPrev: TypeConstructorDescription {
@ -17422,7 +17426,7 @@ public extension Api {
public enum Message: TypeConstructorDescription { public enum Message: TypeConstructorDescription {
case messageEmpty(id: Int32) case messageEmpty(id: Int32)
case message(flags: Int32, id: Int32, fromId: Api.Peer, peerId: Api.Peer, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int32?, replyTo: Api.MessageReplyHeader?, date: Int32, message: String, media: Api.MessageMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, views: Int32?, forwards: Int32?, replies: Api.MessageReplies?, editDate: Int32?, postAuthor: String?, groupedId: Int64?, restrictionReason: [Api.RestrictionReason]?) case message(flags: Int32, id: Int32, fromId: Api.Peer, peerId: Api.Peer, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int32?, replyTo: Api.MessageReplyHeader?, date: Int32, message: String, media: Api.MessageMedia?, replyMarkup: Api.ReplyMarkup?, entities: [Api.MessageEntity]?, views: Int32?, forwards: Int32?, replies: Api.MessageReplies?, editDate: Int32?, postAuthor: String?, groupedId: Int64?, restrictionReason: [Api.RestrictionReason]?)
case messageService(flags: Int32, id: Int32, fromId: Api.Peer, peerId: Api.Peer, replyToMsgId: Int32?, date: Int32, action: Api.MessageAction) case messageService(flags: Int32, id: Int32, fromId: Api.Peer, peerId: Api.Peer, replyTo: Api.MessageReplyHeader?, date: Int32, action: Api.MessageAction)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
@ -17464,15 +17468,15 @@ public extension Api {
item.serialize(buffer, true) item.serialize(buffer, true)
}} }}
break break
case .messageService(let flags, let id, let fromId, let peerId, let replyToMsgId, let date, let action): case .messageService(let flags, let id, let fromId, let peerId, let replyTo, let date, let action):
if boxed { if boxed {
buffer.appendInt32(797820163) buffer.appendInt32(-1245570157)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false) serializeInt32(id, buffer: buffer, boxed: false)
fromId.serialize(buffer, true) fromId.serialize(buffer, true)
peerId.serialize(buffer, true) peerId.serialize(buffer, true)
if Int(flags) & Int(1 << 3) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 3) != 0 {replyTo!.serialize(buffer, true)}
serializeInt32(date, buffer: buffer, boxed: false) serializeInt32(date, buffer: buffer, boxed: false)
action.serialize(buffer, true) action.serialize(buffer, true)
break break
@ -17485,8 +17489,8 @@ public extension Api {
return ("messageEmpty", [("id", id)]) return ("messageEmpty", [("id", id)])
case .message(let flags, let id, let fromId, let peerId, let fwdFrom, let viaBotId, let replyTo, let date, let message, let media, let replyMarkup, let entities, let views, let forwards, let replies, let editDate, let postAuthor, let groupedId, let restrictionReason): case .message(let flags, let id, let fromId, let peerId, let fwdFrom, let viaBotId, let replyTo, let date, let message, let media, let replyMarkup, let entities, let views, let forwards, let replies, let editDate, let postAuthor, let groupedId, let restrictionReason):
return ("message", [("flags", flags), ("id", id), ("fromId", fromId), ("peerId", peerId), ("fwdFrom", fwdFrom), ("viaBotId", viaBotId), ("replyTo", replyTo), ("date", date), ("message", message), ("media", media), ("replyMarkup", replyMarkup), ("entities", entities), ("views", views), ("forwards", forwards), ("replies", replies), ("editDate", editDate), ("postAuthor", postAuthor), ("groupedId", groupedId), ("restrictionReason", restrictionReason)]) return ("message", [("flags", flags), ("id", id), ("fromId", fromId), ("peerId", peerId), ("fwdFrom", fwdFrom), ("viaBotId", viaBotId), ("replyTo", replyTo), ("date", date), ("message", message), ("media", media), ("replyMarkup", replyMarkup), ("entities", entities), ("views", views), ("forwards", forwards), ("replies", replies), ("editDate", editDate), ("postAuthor", postAuthor), ("groupedId", groupedId), ("restrictionReason", restrictionReason)])
case .messageService(let flags, let id, let fromId, let peerId, let replyToMsgId, let date, let action): case .messageService(let flags, let id, let fromId, let peerId, let replyTo, let date, let action):
return ("messageService", [("flags", flags), ("id", id), ("fromId", fromId), ("peerId", peerId), ("replyToMsgId", replyToMsgId), ("date", date), ("action", action)]) return ("messageService", [("flags", flags), ("id", id), ("fromId", fromId), ("peerId", peerId), ("replyTo", replyTo), ("date", date), ("action", action)])
} }
} }
@ -17597,8 +17601,10 @@ public extension Api {
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
_4 = Api.parse(reader, signature: signature) as? Api.Peer _4 = Api.parse(reader, signature: signature) as? Api.Peer
} }
var _5: Int32? var _5: Api.MessageReplyHeader?
if Int(_1!) & Int(1 << 3) != 0 {_5 = reader.readInt32() } if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() {
_5 = Api.parse(reader, signature: signature) as? Api.MessageReplyHeader
} }
var _6: Int32? var _6: Int32?
_6 = reader.readInt32() _6 = reader.readInt32()
var _7: Api.MessageAction? var _7: Api.MessageAction?
@ -17613,7 +17619,7 @@ public extension Api {
let _c6 = _6 != nil let _c6 = _6 != nil
let _c7 = _7 != nil let _c7 = _7 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 { if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 {
return Api.Message.messageService(flags: _1!, id: _2!, fromId: _3!, peerId: _4!, replyToMsgId: _5, date: _6!, action: _7!) return Api.Message.messageService(flags: _1!, id: _2!, fromId: _3!, peerId: _4!, replyTo: _5, date: _6!, action: _7!)
} }
else { else {
return nil return nil

View File

@ -366,8 +366,14 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
} }
let authorId: PeerId? let authorId: PeerId?
if let peer = peer as? TelegramChannel, case .broadcast = peer.info { if let peer = peer as? TelegramChannel {
authorId = peer.id if case .broadcast = peer.info {
authorId = peer.id
} else if case .group = peer.info, peer.hasPermission(.canBeAnonymous) {
authorId = peer.id
} else {
authorId = account.peerId
}
} else { } else {
authorId = account.peerId authorId = account.peerId
} }
@ -529,8 +535,14 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
} }
let authorId: PeerId? let authorId: PeerId?
if let peer = peer as? TelegramChannel, case .broadcast = peer.info { if let peer = peer as? TelegramChannel {
authorId = peer.id if case .broadcast = peer.info {
authorId = peer.id
} else if case .group = peer.info, peer.hasPermission(.canBeAnonymous) {
authorId = peer.id
} else {
authorId = account.peerId
}
} else { } else {
authorId = account.peerId authorId = account.peerId
} }

View File

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization { public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt { public func currentLayer() -> UInt {
return 120 return 119
} }
public func parseMessage(_ data: Data!) -> Any! { public func parseMessage(_ data: Data!) -> Any! {

View File

@ -217,11 +217,12 @@ func apiMessageAssociatedMessageIds(_ message: Api.Message) -> [MessageId]? {
} }
case .messageEmpty: case .messageEmpty:
break break
case let .messageService(flags, _, fromId, chatPeerId, replyToMsgId, _, _): case let .messageService(flags, _, fromId, chatPeerId, replyHeader, _, _):
if let replyToMsgId = replyToMsgId { if let replyHeader = replyHeader {
let peerId: PeerId = chatPeerId.peerId switch replyHeader {
case let .messageReplyHeader(_, replyToMsgId, replyToPeerId, _):
return [MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId)] return [MessageId(peerId: replyToPeerId?.peerId ?? chatPeerId.peerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId)]
}
} }
} }
return nil return nil
@ -581,20 +582,35 @@ extension StoreMessage {
self.init(id: MessageId(peerId: peerId, namespace: namespace, id: id), globallyUniqueId: nil, groupingKey: groupingId, threadId: threadId, timestamp: date, flags: storeFlags, tags: tags, globalTags: globalTags, localTags: [], forwardInfo: forwardInfo, authorId: authorId, text: messageText, attributes: attributes, media: medias) self.init(id: MessageId(peerId: peerId, namespace: namespace, id: id), globallyUniqueId: nil, groupingKey: groupingId, threadId: threadId, timestamp: date, flags: storeFlags, tags: tags, globalTags: globalTags, localTags: [], forwardInfo: forwardInfo, authorId: authorId, text: messageText, attributes: attributes, media: medias)
case .messageEmpty: case .messageEmpty:
return nil return nil
case let .messageService(flags, id, fromId, chatPeerId, replyToMsgId, date, action): case let .messageService(flags, id, fromId, chatPeerId, replyTo, date, action):
let peerId: PeerId = chatPeerId.peerId let peerId: PeerId = chatPeerId.peerId
var authorId: PeerId? = fromId.peerId var authorId: PeerId? = fromId.peerId
var attributes: [MessageAttribute] = [] var attributes: [MessageAttribute] = []
if let replyToMsgId = replyToMsgId {
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: nil)) var threadId: Int64?
if let replyTo = replyTo {
var threadMessageId: MessageId?
switch replyTo {
case let .messageReplyHeader(_, replyToMsgId, replyToPeerId, replyToTopId):
let replyPeerId = replyToPeerId?.peerId ?? peerId
if let replyToTopId = replyToTopId {
let threadIdValue = MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToTopId)
threadMessageId = threadIdValue
threadId = makeMessageThreadId(threadIdValue)
} else if peerId.namespace == Namespaces.Peer.CloudChannel {
let threadIdValue = MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId)
threadMessageId = threadIdValue
threadId = makeMessageThreadId(threadIdValue)
}
attributes.append(ReplyMessageAttribute(messageId: MessageId(peerId: replyPeerId, namespace: Namespaces.Message.Cloud, id: replyToMsgId), threadMessageId: threadMessageId))
}
} }
if (flags & (1 << 17)) != 0 { if (flags & (1 << 17)) != 0 {
attributes.append(ContentRequiresValidationMessageAttribute()) attributes.append(ContentRequiresValidationMessageAttribute())
} }
var storeFlags = StoreMessageFlags() var storeFlags = StoreMessageFlags()
if (flags & 2) == 0 { if (flags & 2) == 0 {
let _ = storeFlags.insert(.Incoming) let _ = storeFlags.insert(.Incoming)
@ -624,7 +640,7 @@ extension StoreMessage {
storeFlags.insert(.WasScheduled) storeFlags.insert(.WasScheduled)
} }
self.init(id: MessageId(peerId: peerId, namespace: namespace, id: id), globallyUniqueId: nil, groupingKey: nil, threadId: nil, timestamp: date, flags: storeFlags, tags: tags, globalTags: globalTags, localTags: [], forwardInfo: nil, authorId: authorId, text: "", attributes: attributes, media: media) self.init(id: MessageId(peerId: peerId, namespace: namespace, id: id), globallyUniqueId: nil, groupingKey: nil, threadId: threadId, timestamp: date, flags: storeFlags, tags: tags, globalTags: globalTags, localTags: [], forwardInfo: nil, authorId: authorId, text: "", attributes: attributes, media: media)
} }
} }
} }

View File

@ -18,6 +18,13 @@ public enum TelegramChannelPermission {
public extension TelegramChannel { public extension TelegramChannel {
func hasPermission(_ permission: TelegramChannelPermission) -> Bool { func hasPermission(_ permission: TelegramChannelPermission) -> Bool {
if self.flags.contains(.isCreator) { if self.flags.contains(.isCreator) {
if case .canBeAnonymous = permission {
if let adminRights = self.adminRights {
return adminRights.flags.contains(.canBeAnonymous)
} else {
return false
}
}
return true return true
} }
switch permission { switch permission {

View File

@ -57,17 +57,14 @@ class UpdateMessageService: NSObject, MTMessageService {
if groups.count != 0 { if groups.count != 0 {
self.putNext(groups) self.putNext(groups)
} }
case let .updateShortChatMessage(flags, id, fromId, chatId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyToMsgId, entities): case let .updateShortChatMessage(flags, id, fromId, chatId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyHeader, entities):
let replyHeader = replyToMsgId.flatMap { replyToMsgId -> Api.MessageReplyHeader in
return Api.MessageReplyHeader.messageReplyHeader(flags: 0, replyToMsgId: replyToMsgId, replyToPeerId: nil, replyToTopId: nil)
}
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: .peerChat(chatId: fromId), peerId: Api.Peer.peerChat(chatId: chatId), fwdFrom: fwdFrom, viaBotId: viaBotId, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, restrictionReason: nil) let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: .peerChat(chatId: fromId), peerId: Api.Peer.peerChat(chatId: chatId), fwdFrom: fwdFrom, viaBotId: viaBotId, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, restrictionReason: nil)
let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount) let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount)
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil) let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
if groups.count != 0 { if groups.count != 0 {
self.putNext(groups) self.putNext(groups)
} }
case let .updateShortMessage(flags, id, userId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyToMsgId, entities): case let .updateShortMessage(flags, id, userId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyHeader, entities):
let generatedFromId: Api.Peer let generatedFromId: Api.Peer
if (Int(flags) & 1 << 1) != 0 { if (Int(flags) & 1 << 1) != 0 {
generatedFromId = Api.Peer.peerUser(userId: self.peerId.id) generatedFromId = Api.Peer.peerUser(userId: self.peerId.id)
@ -77,10 +74,6 @@ class UpdateMessageService: NSObject, MTMessageService {
let generatedPeerId = Api.Peer.peerUser(userId: userId) let generatedPeerId = Api.Peer.peerUser(userId: userId)
let replyHeader = replyToMsgId.flatMap { replyToMsgId -> Api.MessageReplyHeader in
return Api.MessageReplyHeader.messageReplyHeader(flags: 0, replyToMsgId: replyToMsgId, replyToPeerId: nil, replyToTopId: nil)
}
let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: generatedFromId, peerId: generatedPeerId, fwdFrom: fwdFrom, viaBotId: viaBotId, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, restrictionReason: nil) let generatedMessage = Api.Message.message(flags: flags, id: id, fromId: generatedFromId, peerId: generatedPeerId, fwdFrom: fwdFrom, viaBotId: viaBotId, replyTo: replyHeader, date: date, message: message, media: Api.MessageMedia.messageMediaEmpty, replyMarkup: nil, entities: entities, views: nil, forwards: nil, replies: nil, editDate: nil, postAuthor: nil, groupedId: nil, restrictionReason: nil)
let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount) let update = Api.Update.updateNewMessage(message: generatedMessage, pts: pts, ptsCount: ptsCount)
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil) let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)

View File

@ -229,6 +229,9 @@ public enum PresentationResourceKey: Int32 {
case groupInfoMembersIcon case groupInfoMembersIcon
case emptyChatListCheckIcon case emptyChatListCheckIcon
case chatFreeCommentButtonBackground
case chatFreeCommentButtonIcon
} }
public enum PresentationResourceParameterKey: Hashable { public enum PresentationResourceParameterKey: Hashable {

View File

@ -1106,4 +1106,17 @@ public struct PresentationResourcesChat {
return generateTintedImage(image: UIImage(bundleImageName: "Item List/DisclosureArrow"), color: messageTheme.accentTextColor) return generateTintedImage(image: UIImage(bundleImageName: "Item List/DisclosureArrow"), color: messageTheme.accentTextColor)
}) })
} }
public static func chatFreeCommentButtonBackground(_ theme: PresentationTheme, wallpaper: TelegramWallpaper) -> UIImage? {
return theme.image(PresentationResourceKey.chatFreeCommentButtonBackground.rawValue, { _ in
let strokeColor = bubbleVariableColor(variableColor: theme.chat.message.shareButtonStrokeColor, wallpaper: wallpaper)
return generateStretchableFilledCircleImage(diameter: 30.0, color: bubbleVariableColor(variableColor: theme.chat.message.shareButtonFillColor, wallpaper: wallpaper), strokeColor: strokeColor, strokeWidth: strokeColor.alpha.isZero ? nil : 1.0)
})
}
public static func chatFreeCommentButtonIcon(_ theme: PresentationTheme, wallpaper: TelegramWallpaper) -> UIImage? {
return theme.image(PresentationResourceKey.chatFreeCommentButtonIcon.rawValue, { _ in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/FreeRepliesIcon"), color: bubbleVariableColor(variableColor: theme.chat.message.shareButtonForegroundColor, wallpaper: wallpaper))
})
}
} }

View File

@ -3740,6 +3740,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory() strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory()
} else if case let .peer(peerId) = strongSelf.chatLocation { } else if case let .peer(peerId) = strongSelf.chatLocation {
strongSelf.navigateToMessage(messageLocation: .upperBound(peerId), animated: true) strongSelf.navigateToMessage(messageLocation: .upperBound(peerId), animated: true)
} else if case .replyThread = strongSelf.chatLocation {
strongSelf.scrollToEndOfHistory()
} else { } else {
strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory() strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory()
} }
@ -8065,7 +8067,67 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
func scrollToEndOfHistory() { func scrollToEndOfHistory() {
self.chatDisplayNode.historyNode.scrollToEndOfHistory() let locationInput = ChatHistoryLocationInput(content: .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true), id: 0)
let historyView = preloadedChatHistoryViewForLocation(locationInput, context: self.context, chatLocation: self.chatLocation, chatLocationContextHolder: self.chatLocationContextHolder, fixedCombinedReadStates: nil, tagMask: nil, additionalData: [])
let signal = historyView
|> mapToSignal { historyView -> Signal<(MessageIndex?, Bool), NoError> in
switch historyView {
case .Loading:
return .single((nil, true))
case .HistoryView:
return .single((nil, false))
}
}
|> take(until: { index in
return SignalTakeAction(passthrough: true, complete: !index.1)
})
var cancelImpl: (() -> Void)?
let presentationData = self.presentationData
let displayTime = CACurrentMediaTime()
let progressSignal = Signal<Never, NoError> { [weak self] subscriber in
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: {
if CACurrentMediaTime() - displayTime > 1.5 {
cancelImpl?()
}
}))
self?.present(controller, in: .window(.root))
return ActionDisposable { [weak controller] in
Queue.mainQueue().async() {
controller?.dismiss()
}
}
}
|> runOn(Queue.mainQueue())
|> delay(0.05, queue: Queue.mainQueue())
let progressDisposable = MetaDisposable()
var progressStarted = false
self.messageIndexDisposable.set((signal
|> afterDisposed {
Queue.mainQueue().async {
progressDisposable.dispose()
}
}
|> deliverOnMainQueue).start(next: { [weak self] index in
if index.1 {
if !progressStarted {
progressStarted = true
progressDisposable.set(progressSignal.start())
}
}
}, completed: { [weak self] in
if let strongSelf = self {
strongSelf.loadingMessage.set(false)
strongSelf.chatDisplayNode.historyNode.scrollToEndOfHistory()
}
}))
cancelImpl = { [weak self] in
if let strongSelf = self {
strongSelf.loadingMessage.set(false)
strongSelf.messageIndexDisposable.set(nil)
}
}
} }
func updateDownButtonVisibility() { func updateDownButtonVisibility() {

View File

@ -419,6 +419,7 @@ private struct ChatHistoryAnimatedEmojiConfiguration {
public final class ChatHistoryListNode: ListView, ChatHistoryNode { public final class ChatHistoryListNode: ListView, ChatHistoryNode {
private let context: AccountContext private let context: AccountContext
private let chatLocation: ChatLocation private let chatLocation: ChatLocation
private let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>
private let subject: ChatControllerSubject? private let subject: ChatControllerSubject?
private let tagMask: MessageTags? private let tagMask: MessageTags?
private let controllerInteraction: ChatControllerInteraction private let controllerInteraction: ChatControllerInteraction
@ -532,6 +533,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles) { public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles) {
self.context = context self.context = context
self.chatLocation = chatLocation self.chatLocation = chatLocation
self.chatLocationContextHolder = chatLocationContextHolder
self.subject = subject self.subject = subject
self.tagMask = tagMask self.tagMask = tagMask
self.controllerInteraction = controllerInteraction self.controllerInteraction = controllerInteraction
@ -706,6 +708,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
} else { } else {
if let subject = subject, case let .message(messageId) = subject { if let subject = subject, case let .message(messageId) = subject {
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0) strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .InitialSearch(location: .id(messageId), count: 60), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
} else if var chatHistoryLocation = strongSelf.chatHistoryLocationValue {
chatHistoryLocation.id += 1
strongSelf.chatHistoryLocationValue = chatHistoryLocation
} else { } else {
strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: 60), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0) strongSelf.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Initial(count: 60), id: (strongSelf.chatHistoryLocationValue?.id).flatMap({ $0 + 1 }) ?? 0)
} }
@ -1286,7 +1291,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
case .known(0.0): case .known(0.0):
break break
default: default:
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true), id: self.takeNextHistoryLocationId()) let locationInput = ChatHistoryLocationInput(content: .Scroll(index: .upperBound, anchorIndex: .upperBound, sourceIndex: .lowerBound, scrollPosition: .top(0.0), animated: true), id: self.takeNextHistoryLocationId())
self.chatHistoryLocationValue = locationInput
} }
} }
@ -1522,12 +1528,14 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
if transition.animateIn || animateIn { if transition.animateIn || animateIn {
let heightNorm = strongSelf.bounds.height - strongSelf.insets.top let heightNorm = strongSelf.bounds.height - strongSelf.insets.top
strongSelf.forEachVisibleItemNode { itemNode in strongSelf.forEachVisibleItemNode { itemNode in
let delayFactor = itemNode.frame.minY / heightNorm
let delay = Double(delayFactor * 0.1)
if let itemNode = itemNode as? ChatMessageItemView { if let itemNode = itemNode as? ChatMessageItemView {
let delayFactor = itemNode.frame.minY / heightNorm
let delay = Double(delayFactor * 0.1)
itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, delay: delay) itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, delay: delay)
itemNode.layer.animateScale(from: 0.9, to: 1.0, duration: 0.4, delay: delay, timingFunction: kCAMediaTimingFunctionSpring) itemNode.layer.animateScale(from: 0.94, to: 1.0, duration: 0.4, delay: delay, timingFunction: kCAMediaTimingFunctionSpring)
} else if let itemNode = itemNode as? ChatUnreadItemNode {
itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, delay: delay)
} }
} }
strongSelf.forEachItemHeaderNode { itemNode in strongSelf.forEachItemHeaderNode { itemNode in
@ -1535,7 +1543,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
let delay = Double(delayFactor * 0.2) let delay = Double(delayFactor * 0.2)
itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, delay: delay) itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, delay: delay)
itemNode.layer.animateScale(from: 0.9, to: 1.0, duration: 0.4, delay: delay, timingFunction: kCAMediaTimingFunctionSpring) itemNode.layer.animateScale(from: 0.94, to: 1.0, duration: 0.4, delay: delay, timingFunction: kCAMediaTimingFunctionSpring)
} }
} }

View File

@ -211,6 +211,12 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, context: A
|> map { view, updateType, initialData -> ChatHistoryViewUpdate in |> map { view, updateType, initialData -> ChatHistoryViewUpdate in
let (cachedData, cachedDataMessages, readStateData) = extractAdditionalData(view: view, chatLocation: chatLocation) let (cachedData, cachedDataMessages, readStateData) = extractAdditionalData(view: view, chatLocation: chatLocation)
let combinedInitialData = ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData)
if view.isLoading {
return ChatHistoryViewUpdate.Loading(initialData: combinedInitialData, type: .Generic(type: updateType))
}
let genericType: ViewUpdateType let genericType: ViewUpdateType
let scrollPosition: ChatHistoryViewScrollPosition? = first ? chatScrollPosition : nil let scrollPosition: ChatHistoryViewScrollPosition? = first ? chatScrollPosition : nil
if first { if first {
@ -219,7 +225,7 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocationInput, context: A
} else { } else {
genericType = updateType genericType = updateType
} }
return .HistoryView(view: view, type: .Generic(type: genericType), scrollPosition: scrollPosition, flashIndicators: animated, originalScrollPosition: chatScrollPosition, initialData: ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData), id: location.id) return .HistoryView(view: view, type: .Generic(type: genericType), scrollPosition: scrollPosition, flashIndicators: animated, originalScrollPosition: chatScrollPosition, initialData: combinedInitialData, id: location.id)
} }
} }
} }

View File

@ -32,7 +32,7 @@ extension AnimatedStickerNode: GenericAnimatedStickerNode {
} }
class ChatMessageShareButton: HighlightTrackingButtonNode { class ChatMessageShareButton: HighlightableButtonNode {
private let backgroundNode: ASImageNode private let backgroundNode: ASImageNode
private let iconNode: ASImageNode private let iconNode: ASImageNode
@ -74,17 +74,23 @@ class ChatMessageShareButton: HighlightTrackingButtonNode {
let graphics = PresentationResourcesChat.additionalGraphics(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners) let graphics = PresentationResourcesChat.additionalGraphics(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper, bubbleCorners: presentationData.chatBubbleCorners)
var updatedShareButtonBackground: UIImage? var updatedShareButtonBackground: UIImage?
var updatedIconImage: UIImage?
if isReplies { if isReplies {
updatedShareButtonBackground = chatBubbleActionButtonImage(fillColor: bubbleVariableColor(variableColor: presentationData.theme.theme.chat.message.shareButtonFillColor, wallpaper: presentationData.theme.wallpaper), strokeColor: bubbleVariableColor(variableColor: presentationData.theme.theme.chat.message.shareButtonStrokeColor, wallpaper: presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: presentationData.theme.wallpaper), image: UIImage(bundleImageName: "Chat/Message/FreeRepliesIcon"), iconOffset: CGPoint(x: 0.5, y: 1.0))?.stretchableImage(withLeftCapWidth: 29 / 2, topCapHeight: 29 / 2) updatedShareButtonBackground = PresentationResourcesChat.chatFreeCommentButtonBackground(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
updatedIconImage = PresentationResourcesChat.chatFreeCommentButtonIcon(presentationData.theme.theme, wallpaper: presentationData.theme.wallpaper)
} else if message.id.peerId == account.peerId { } else if message.id.peerId == account.peerId {
updatedShareButtonBackground = graphics.chatBubbleNavigateButtonImage updatedShareButtonBackground = graphics.chatBubbleNavigateButtonImage
} else { } else {
updatedShareButtonBackground = graphics.chatBubbleShareButtonImage updatedShareButtonBackground = graphics.chatBubbleShareButtonImage
} }
self.backgroundNode.image = updatedShareButtonBackground self.backgroundNode.image = updatedShareButtonBackground
self.iconNode.image = updatedIconImage
} }
var size = CGSize(width: 29.0, height: 29.0) var size = CGSize(width: 30.0, height: 30.0)
var offsetIcon = false
if isReplies, replyCount > 0 { if isReplies, replyCount > 0 {
offsetIcon = true
let textNode: ImmediateTextNode let textNode: ImmediateTextNode
if let current = self.textNode { if let current = self.textNode {
textNode = current textNode = current
@ -94,11 +100,29 @@ class ChatMessageShareButton: HighlightTrackingButtonNode {
self.addSubnode(textNode) self.addSubnode(textNode)
} }
let textColor = bubbleVariableColor(variableColor: presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: presentationData.theme.wallpaper)
let countString: String
if replyCount >= 1000 * 1000 {
countString = "\(replyCount / 1000_000)M"
} else if replyCount >= 1000 {
countString = "\(replyCount / 1000)K"
} else {
countString = "\(replyCount)"
}
textNode.attributedText = NSAttributedString(string: countString, font: Font.regular(11.0), textColor: textColor)
let textSize = textNode.updateLayout(CGSize(width: 100.0, height: 100.0))
size.height += textSize.height - 1.0
textNode.frame = CGRect(origin: CGPoint(x: floor((size.width - textSize.width) / 2.0), y: size.height - textSize.height - 4.0), size: textSize)
} else if let textNode = self.textNode { } else if let textNode = self.textNode {
self.textNode = nil self.textNode = nil
textNode.removeFromSupernode() textNode.removeFromSupernode()
} }
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size) self.backgroundNode.frame = CGRect(origin: CGPoint(), size: size)
if let image = self.iconNode.image {
self.iconNode.frame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) / 2.0), y: floor((size.width - image.size.width) / 2.0) - (offsetIcon ? 1.0 : 0.0)), size: image.size)
}
return size return size
} }
} }
@ -898,7 +922,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
updatedShareButtonNode.addTarget(strongSelf, action: #selector(strongSelf.shareButtonPressed), forControlEvents: .touchUpInside) updatedShareButtonNode.addTarget(strongSelf, action: #selector(strongSelf.shareButtonPressed), forControlEvents: .touchUpInside)
} }
let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, message: item.message, account: item.context.account) let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, message: item.message, account: item.context.account)
updatedShareButtonNode.frame = CGRect(origin: CGPoint(x: updatedImageFrame.maxX + 8.0, y: updatedImageFrame.maxY - 30.0), size: buttonSize) updatedShareButtonNode.frame = CGRect(origin: CGPoint(x: updatedImageFrame.maxX + 8.0, y: updatedImageFrame.maxY - buttonSize.height), size: buttonSize)
} else if let shareButtonNode = strongSelf.shareButtonNode { } else if let shareButtonNode = strongSelf.shareButtonNode {
shareButtonNode.removeFromSupernode() shareButtonNode.removeFromSupernode()
strongSelf.shareButtonNode = nil strongSelf.shareButtonNode = nil

View File

@ -831,7 +831,14 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode
displayAuthorInfo = !mergedTop.merged && incoming && effectiveAuthor != nil displayAuthorInfo = !mergedTop.merged && incoming && effectiveAuthor != nil
} else { } else {
effectiveAuthor = firstMessage.author effectiveAuthor = firstMessage.author
displayAuthorInfo = !mergedTop.merged && incoming && peerId.isGroupOrChannel && effectiveAuthor != nil
var allowAuthor = incoming
if let author = firstMessage.author, author is TelegramChannel, author.id == firstMessage.id.peerId, !incoming {
allowAuthor = true
}
displayAuthorInfo = !mergedTop.merged && allowAuthor && peerId.isGroupOrChannel && effectiveAuthor != nil
if let forwardInfo = firstMessage.forwardInfo, forwardInfo.psaType != nil { if let forwardInfo = firstMessage.forwardInfo, forwardInfo.psaType != nil {
displayAuthorInfo = false displayAuthorInfo = false
} }
@ -1152,7 +1159,12 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePrevewItemNode
authorNameColor = chatMessagePeerIdColors[Int(peer.id.id % 7)] authorNameColor = chatMessagePeerIdColors[Int(peer.id.id % 7)]
} else if let effectiveAuthor = effectiveAuthor { } else if let effectiveAuthor = effectiveAuthor {
authorNameString = effectiveAuthor.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder) authorNameString = effectiveAuthor.displayTitle(strings: item.presentationData.strings, displayOrder: item.presentationData.nameDisplayOrder)
authorNameColor = chatMessagePeerIdColors[Int(effectiveAuthor.id.id % 7)]
if incoming {
authorNameColor = chatMessagePeerIdColors[Int(effectiveAuthor.id.id % 7)]
} else {
authorNameColor = item.presentationData.theme.theme.chat.message.outgoing.accentTextColor
}
var isScam = effectiveAuthor.isScam var isScam = effectiveAuthor.isScam
if case let .peer(peerId) = item.chatLocation, let authorPeerId = item.message.author?.id, authorPeerId == peerId { if case let .peer(peerId) = item.chatLocation, let authorPeerId = item.message.author?.id, authorPeerId == peerId {

View File

@ -26,7 +26,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
private var selectionNode: ChatMessageSelectionNode? private var selectionNode: ChatMessageSelectionNode?
private var deliveryFailedNode: ChatMessageDeliveryFailedNode? private var deliveryFailedNode: ChatMessageDeliveryFailedNode?
private var shareButtonNode: HighlightableButtonNode? private var shareButtonNode: ChatMessageShareButton?
private var swipeToReplyNode: ChatMessageSwipeToReplyNode? private var swipeToReplyNode: ChatMessageSwipeToReplyNode?
private var swipeToReplyFeedback: HapticFeedback? private var swipeToReplyFeedback: HapticFeedback?
@ -360,28 +360,12 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
var updatedShareButtonBackground: UIImage? var updatedShareButtonBackground: UIImage?
var updatedShareButtonNode: HighlightableButtonNode? var updatedShareButtonNode: ChatMessageShareButton?
if needShareButton { if needShareButton {
if currentShareButtonNode != nil { if currentShareButtonNode != nil {
updatedShareButtonNode = currentShareButtonNode updatedShareButtonNode = currentShareButtonNode
if item.presentationData.theme !== currentItem?.presentationData.theme {
let graphics = PresentationResourcesChat.additionalGraphics(item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper, bubbleCorners: item.presentationData.chatBubbleCorners)
if item.message.id.peerId == item.context.account.peerId {
updatedShareButtonBackground = graphics.chatBubbleNavigateButtonImage
} else {
updatedShareButtonBackground = graphics.chatBubbleShareButtonImage
}
}
} else { } else {
let buttonNode = HighlightableButtonNode() let buttonNode = ChatMessageShareButton()
let buttonIcon: UIImage?
let graphics = PresentationResourcesChat.additionalGraphics(item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper, bubbleCorners: item.presentationData.chatBubbleCorners)
if item.message.id.peerId == item.context.account.peerId {
buttonIcon = graphics.chatBubbleNavigateButtonImage
} else {
buttonIcon = graphics.chatBubbleShareButtonImage
}
buttonNode.setBackgroundImage(buttonIcon, for: [.normal])
updatedShareButtonNode = buttonNode updatedShareButtonNode = buttonNode
} }
} }
@ -483,18 +467,13 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
strongSelf.addSubnode(updatedShareButtonNode) strongSelf.addSubnode(updatedShareButtonNode)
updatedShareButtonNode.addTarget(strongSelf, action: #selector(strongSelf.shareButtonPressed), forControlEvents: .touchUpInside) updatedShareButtonNode.addTarget(strongSelf, action: #selector(strongSelf.shareButtonPressed), forControlEvents: .touchUpInside)
} }
if let updatedShareButtonBackground = updatedShareButtonBackground { let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, message: item.message, account: item.context.account)
strongSelf.shareButtonNode?.setBackgroundImage(updatedShareButtonBackground, for: [.normal]) updatedShareButtonNode.frame = CGRect(origin: CGPoint(x: videoFrame.maxX - 7.0, y: videoFrame.maxY - 24.0 - buttonSize.height), size: buttonSize)
}
} else if let shareButtonNode = strongSelf.shareButtonNode { } else if let shareButtonNode = strongSelf.shareButtonNode {
shareButtonNode.removeFromSupernode() shareButtonNode.removeFromSupernode()
strongSelf.shareButtonNode = nil strongSelf.shareButtonNode = nil
} }
if let shareButtonNode = strongSelf.shareButtonNode {
shareButtonNode.frame = CGRect(origin: CGPoint(x: videoFrame.maxX - 7.0, y: videoFrame.maxY - 54.0), size: CGSize(width: 29.0, height: 29.0))
}
if let updatedReplyBackgroundNode = updatedReplyBackgroundNode { if let updatedReplyBackgroundNode = updatedReplyBackgroundNode {
if strongSelf.replyBackgroundNode == nil { if strongSelf.replyBackgroundNode == nil {
strongSelf.replyBackgroundNode = updatedReplyBackgroundNode strongSelf.replyBackgroundNode = updatedReplyBackgroundNode
@ -760,6 +739,15 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
@objc func shareButtonPressed() { @objc func shareButtonPressed() {
if let item = self.item { if let item = self.item {
if let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = channel.info {
for attribute in item.message.attributes {
if let _ = attribute as? ReplyThreadMessageAttribute {
item.controllerInteraction.openMessageReplies(item.message.id)
return
}
}
}
if item.content.firstMessage.id.peerId == item.context.account.peerId { if item.content.firstMessage.id.peerId == item.context.account.peerId {
for attribute in item.content.firstMessage.attributes { for attribute in item.content.firstMessage.attributes {
if let attribute = attribute as? SourceReferenceMessageAttribute { if let attribute = attribute as? SourceReferenceMessageAttribute {

View File

@ -136,6 +136,10 @@ private func messagesShouldBeMerged(accountPeerId: PeerId, _ lhs: Message, _ rhs
} }
if abs(lhs.timestamp - rhs.timestamp) < Int32(10 * 60) && sameAuthor { if abs(lhs.timestamp - rhs.timestamp) < Int32(10 * 60) && sameAuthor {
if let channel = lhs.peers[lhs.id.peerId] as? TelegramChannel, case .group = channel.info, lhsEffectiveAuthor?.id == channel.id, !lhs.effectivelyIncoming(accountPeerId) {
return .none
}
var upperStyle: Int32 = ChatMessageMerge.fullyMerged.rawValue var upperStyle: Int32 = ChatMessageMerge.fullyMerged.rawValue
var lowerStyle: Int32 = ChatMessageMerge.fullyMerged.rawValue var lowerStyle: Int32 = ChatMessageMerge.fullyMerged.rawValue
for media in lhs.media { for media in lhs.media {

View File

@ -28,7 +28,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
private var selectionNode: ChatMessageSelectionNode? private var selectionNode: ChatMessageSelectionNode?
private var deliveryFailedNode: ChatMessageDeliveryFailedNode? private var deliveryFailedNode: ChatMessageDeliveryFailedNode?
private var shareButtonNode: HighlightableButtonNode? private var shareButtonNode: ChatMessageShareButton?
var telegramFile: TelegramMediaFile? var telegramFile: TelegramMediaFile?
private let fetchDisposable = MetaDisposable() private let fetchDisposable = MetaDisposable()
@ -444,30 +444,12 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
replyBackgroundImage = graphics.chatFreeformContentAdditionalInfoBackgroundImage replyBackgroundImage = graphics.chatFreeformContentAdditionalInfoBackgroundImage
} }
var updatedShareButtonBackground: UIImage? var updatedShareButtonNode: ChatMessageShareButton?
var updatedShareButtonNode: HighlightableButtonNode?
if needShareButton { if needShareButton {
if currentShareButtonNode != nil { if currentShareButtonNode != nil {
updatedShareButtonNode = currentShareButtonNode updatedShareButtonNode = currentShareButtonNode
if item.presentationData.theme !== currentItem?.presentationData.theme {
let graphics = PresentationResourcesChat.additionalGraphics(item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper, bubbleCorners: item.presentationData.chatBubbleCorners)
if item.message.id.peerId == item.context.account.peerId {
updatedShareButtonBackground = graphics.chatBubbleNavigateButtonImage
} else {
updatedShareButtonBackground = graphics.chatBubbleShareButtonImage
}
}
} else { } else {
let buttonNode = HighlightableButtonNode() let buttonNode = ChatMessageShareButton()
let buttonIcon: UIImage?
let graphics = PresentationResourcesChat.additionalGraphics(item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper, bubbleCorners: item.presentationData.chatBubbleCorners)
if item.message.id.peerId == item.context.account.peerId {
buttonIcon = graphics.chatBubbleNavigateButtonImage
} else {
buttonIcon = graphics.chatBubbleShareButtonImage
}
buttonNode.setBackgroundImage(buttonIcon, for: [.normal])
updatedShareButtonNode = buttonNode updatedShareButtonNode = buttonNode
} }
} }
@ -533,20 +515,15 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
strongSelf.addSubnode(updatedShareButtonNode) strongSelf.addSubnode(updatedShareButtonNode)
updatedShareButtonNode.addTarget(strongSelf, action: #selector(strongSelf.shareButtonPressed), forControlEvents: .touchUpInside) updatedShareButtonNode.addTarget(strongSelf, action: #selector(strongSelf.shareButtonPressed), forControlEvents: .touchUpInside)
} }
if let updatedShareButtonBackground = updatedShareButtonBackground { let buttonSize = updatedShareButtonNode.update(presentationData: item.presentationData, message: item.message, account: item.context.account)
strongSelf.shareButtonNode?.setBackgroundImage(updatedShareButtonBackground, for: [.normal]) var shareButtonFrame = CGRect(origin: CGPoint(x: updatedImageFrame.maxX + 8.0, y: updatedImageFrame.maxY - 10.0 - buttonSize.height), size: buttonSize)
}
} else if let shareButtonNode = strongSelf.shareButtonNode {
shareButtonNode.removeFromSupernode()
strongSelf.shareButtonNode = nil
}
if let shareButtonNode = strongSelf.shareButtonNode {
var shareButtonFrame = CGRect(origin: CGPoint(x: updatedImageFrame.maxX + 8.0, y: updatedImageFrame.maxY - 30.0 - 10.0), size: CGSize(width: 29.0, height: 29.0))
if isEmoji && incoming { if isEmoji && incoming {
shareButtonFrame.origin.x = dateAndStatusFrame.maxX + 8.0 shareButtonFrame.origin.x = dateAndStatusFrame.maxX + 8.0
} }
transition.updateFrame(node: shareButtonNode, frame: shareButtonFrame) transition.updateFrame(node: updatedShareButtonNode, frame: shareButtonFrame)
} else if let shareButtonNode = strongSelf.shareButtonNode {
shareButtonNode.removeFromSupernode()
strongSelf.shareButtonNode = nil
} }
if let updatedReplyBackgroundNode = updatedReplyBackgroundNode { if let updatedReplyBackgroundNode = updatedReplyBackgroundNode {
@ -795,6 +772,15 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
@objc func shareButtonPressed() { @objc func shareButtonPressed() {
if let item = self.item { if let item = self.item {
if let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, case .broadcast = channel.info {
for attribute in item.message.attributes {
if let _ = attribute as? ReplyThreadMessageAttribute {
item.controllerInteraction.openMessageReplies(item.message.id)
return
}
}
}
if item.content.firstMessage.id.peerId == item.context.account.peerId { if item.content.firstMessage.id.peerId == item.context.account.peerId {
for attribute in item.content.firstMessage.attributes { for attribute in item.content.firstMessage.attributes {
if let attribute = attribute as? SourceReferenceMessageAttribute { if let attribute = attribute as? SourceReferenceMessageAttribute {

View File

@ -790,6 +790,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate {
} else { } else {
placeholder = interfaceState.strings.Conversation_InputTextBroadcastPlaceholder placeholder = interfaceState.strings.Conversation_InputTextBroadcastPlaceholder
} }
} else if let channel = peer as? TelegramChannel, case .group = channel.info, channel.hasPermission(.canBeAnonymous) {
placeholder = interfaceState.strings.Conversation_InputTextAnonymousPlaceholder
} else if case .replyThread = interfaceState.chatLocation { } else if case .replyThread = interfaceState.chatLocation {
//TODO:localize //TODO:localize
placeholder = "Reply" placeholder = "Reply"