mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Update API
This commit is contained in:
parent
25952cfef6
commit
189d25c32e
59 changed files with 983 additions and 393 deletions
|
|
@ -15762,6 +15762,7 @@ Error: %8$@";
|
|||
|
||||
"LeaveGroup.Title" = "Leave %@";
|
||||
"LeaveGroup.Text" = "If you leave, **%1$@** will become the owner of **%2$@** in **1 week**.";
|
||||
"LeaveGroup.LegacyGroupText" = "If you leave, **%1$@** will immediately become the owner of **%2$@**.";
|
||||
"LeaveGroup.AppointAnotherOwner" = "Appoint Another Owner";
|
||||
"LeaveGroup.Proceed" = "Leave Group";
|
||||
"AppointAnotherOwner.Title" = "Choose New Owner";
|
||||
|
|
@ -15770,6 +15771,8 @@ Error: %8$@";
|
|||
|
||||
"Group.OwnershipTransfer.DescriptionShortInfo" = "This will transfer the full **owner rights** for **%1$@** to **%2$@**.";
|
||||
|
||||
"FormattedDate.InSeconds_1" = "in %@ second";
|
||||
"FormattedDate.InSeconds_any" = "in %@ seconds";
|
||||
"FormattedDate.InMinutes_1" = "in %@ minute";
|
||||
"FormattedDate.InMinutes_any" = "in %@ minutes";
|
||||
"FormattedDate.InHours_1" = "in %@ hour";
|
||||
|
|
@ -15777,9 +15780,24 @@ Error: %8$@";
|
|||
"FormattedDate.InDays_1" = "in %@ day";
|
||||
"FormattedDate.InDays_any" = "in %@ days";
|
||||
|
||||
"FormattedDate.SecondsAgo_1" = "%@ second ago";
|
||||
"FormattedDate.SecondsAgo_any" = "%@ seconds ago";
|
||||
"FormattedDate.MinutesAgo_1" = "%@ minute ago";
|
||||
"FormattedDate.MinutesAgo_any" = "%@ minutes ago";
|
||||
"FormattedDate.HoursAgo_1" = "%@ hour ago";
|
||||
"FormattedDate.HoursAgo_any" = "%@ hours ago";
|
||||
"FormattedDate.DaysAgo_1" = "%@ day ago";
|
||||
"FormattedDate.DaysAgo_any" = "%@ days ago";
|
||||
|
||||
"FormattedDate.LongDate_m1" = "January %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m2" = "February %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m3" = "March %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m4" = "April %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m5" = "May %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m6" = "June %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m7" = "July %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m8" = "August %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m9" = "September %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m10" = "October %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m11" = "November %1$@, %2$@";
|
||||
"FormattedDate.LongDate_m12" = "December %1$@, %2$@";
|
||||
|
|
|
|||
|
|
@ -57,10 +57,18 @@ extension ChatListControllerImpl {
|
|||
AlertTitleComponent(title: self.presentationData.strings.LeaveGroup_Title(peer.compactDisplayTitle).string)
|
||||
)
|
||||
))
|
||||
|
||||
let text: String
|
||||
if case .legacyGroup = peer {
|
||||
text = self.presentationData.strings.LeaveGroup_LegacyGroupText(nextCreator.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder), peer.compactDisplayTitle).string
|
||||
} else {
|
||||
text = self.presentationData.strings.LeaveGroup_Text(nextCreator.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder), peer.compactDisplayTitle).string
|
||||
}
|
||||
|
||||
content.append(AnyComponentWithIdentity(
|
||||
id: "text",
|
||||
component: AnyComponent(
|
||||
AlertTextComponent(content: .plain(self.presentationData.strings.LeaveGroup_Text(nextCreator.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder), peer.compactDisplayTitle).string))
|
||||
AlertTextComponent(content: .plain(text))
|
||||
)
|
||||
))
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,13 @@ swift_library(
|
|||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||
"//submodules/Display:Display",
|
||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||
"//submodules/TelegramStringFormatting:TelegramStringFormatting",
|
||||
"//submodules/SegmentedControlNode:SegmentedControlNode",
|
||||
"//submodules/DirectionalPanGesture:DirectionalPanGesture",
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
"//submodules/SegmentedControlNode",
|
||||
"//submodules/DirectionalPanGesture",
|
||||
"//submodules/TextFormat",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import UIKit
|
|||
import AsyncDisplayKit
|
||||
import TelegramPresentationData
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
import SegmentedControlNode
|
||||
import DirectionalPanGesture
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import TelegramPresentationData
|
|||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
|
||||
public class ItemListCallListItem: ListViewItem, ItemListItem {
|
||||
let presentationData: ItemListPresentationData
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import SwiftSignalKit
|
|||
import TelegramCore
|
||||
import AccountContext
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
import TelegramPresentationData
|
||||
import ComponentFlow
|
||||
import AlertComponent
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import TelegramUIPreferences
|
|||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
import AccountContext
|
||||
import DeviceLocationManager
|
||||
import Geocoding
|
||||
|
|
|
|||
|
|
@ -183,12 +183,12 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1078612597] = { return Api.ChannelLocation.parse_channelLocationEmpty($0) }
|
||||
dict[-847783593] = { return Api.ChannelMessagesFilter.parse_channelMessagesFilter($0) }
|
||||
dict[-1798033689] = { return Api.ChannelMessagesFilter.parse_channelMessagesFilterEmpty($0) }
|
||||
dict[-885426663] = { return Api.ChannelParticipant.parse_channelParticipant($0) }
|
||||
dict[466961494] = { return Api.ChannelParticipant.parse_channelParticipant($0) }
|
||||
dict[885242707] = { return Api.ChannelParticipant.parse_channelParticipantAdmin($0) }
|
||||
dict[1844969806] = { return Api.ChannelParticipant.parse_channelParticipantBanned($0) }
|
||||
dict[803602899] = { return Api.ChannelParticipant.parse_channelParticipantCreator($0) }
|
||||
dict[453242886] = { return Api.ChannelParticipant.parse_channelParticipantLeft($0) }
|
||||
dict[1331723247] = { return Api.ChannelParticipant.parse_channelParticipantSelf($0) }
|
||||
dict[-1454929382] = { return Api.ChannelParticipant.parse_channelParticipantSelf($0) }
|
||||
dict[-1268741783] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsAdmins($0) }
|
||||
dict[338142689] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsBanned($0) }
|
||||
dict[-1328445861] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsBots($0) }
|
||||
|
|
@ -212,9 +212,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1634294960] = { return Api.ChatInvite.parse_chatInvitePeek($0) }
|
||||
dict[-1940201511] = { return Api.ChatInviteImporter.parse_chatInviteImporter($0) }
|
||||
dict[-264117680] = { return Api.ChatOnlines.parse_chatOnlines($0) }
|
||||
dict[-1070776313] = { return Api.ChatParticipant.parse_chatParticipant($0) }
|
||||
dict[-1600962725] = { return Api.ChatParticipant.parse_chatParticipantAdmin($0) }
|
||||
dict[-462696732] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) }
|
||||
dict[954703838] = { return Api.ChatParticipant.parse_chatParticipant($0) }
|
||||
dict[56677842] = { return Api.ChatParticipant.parse_chatParticipantAdmin($0) }
|
||||
dict[-503814216] = { return Api.ChatParticipant.parse_chatParticipantCreator($0) }
|
||||
dict[1018991608] = { return Api.ChatParticipants.parse_chatParticipants($0) }
|
||||
dict[-2023500831] = { return Api.ChatParticipants.parse_chatParticipantsForbidden($0) }
|
||||
dict[476978193] = { return Api.ChatPhoto.parse_chatPhoto($0) }
|
||||
|
|
@ -575,7 +575,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1098720356] = { return Api.MediaArea.parse_mediaAreaVenue($0) }
|
||||
dict[1235637404] = { return Api.MediaArea.parse_mediaAreaWeather($0) }
|
||||
dict[-808853502] = { return Api.MediaAreaCoordinates.parse_mediaAreaCoordinates($0) }
|
||||
dict[-1665888023] = { return Api.Message.parse_message($0) }
|
||||
dict[988112002] = { return Api.Message.parse_message($0) }
|
||||
dict[-1868117372] = { return Api.Message.parse_messageEmpty($0) }
|
||||
dict[2055212554] = { return Api.Message.parse_messageService($0) }
|
||||
dict[-872240531] = { return Api.MessageAction.parse_messageActionBoostApply($0) }
|
||||
|
|
@ -1119,6 +1119,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[1037718609] = { return Api.Update.parse_updateChatParticipantAdd($0) }
|
||||
dict[-674602590] = { return Api.Update.parse_updateChatParticipantAdmin($0) }
|
||||
dict[-483443337] = { return Api.Update.parse_updateChatParticipantDelete($0) }
|
||||
dict[-1115461703] = { return Api.Update.parse_updateChatParticipantRank($0) }
|
||||
dict[125178264] = { return Api.Update.parse_updateChatParticipants($0) }
|
||||
dict[-2092401936] = { return Api.Update.parse_updateChatUserTyping($0) }
|
||||
dict[-1574314746] = { return Api.Update.parse_updateConfig($0) }
|
||||
|
|
|
|||
|
|
@ -1023,6 +1023,7 @@ public extension Api {
|
|||
public var id: Int32
|
||||
public var fromId: Api.Peer?
|
||||
public var fromBoostsApplied: Int32?
|
||||
public var fromRank: String?
|
||||
public var peerId: Api.Peer
|
||||
public var savedPeerId: Api.Peer?
|
||||
public var fwdFrom: Api.MessageFwdHeader?
|
||||
|
|
@ -1051,12 +1052,13 @@ public extension Api {
|
|||
public var suggestedPost: Api.SuggestedPost?
|
||||
public var scheduleRepeatPeriod: Int32?
|
||||
public var summaryFromLanguage: String?
|
||||
public init(flags: Int32, flags2: Int32, id: Int32, fromId: Api.Peer?, fromBoostsApplied: Int32?, peerId: Api.Peer, savedPeerId: Api.Peer?, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int64?, viaBusinessBotId: Int64?, 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?, reactions: Api.MessageReactions?, restrictionReason: [Api.RestrictionReason]?, ttlPeriod: Int32?, quickReplyShortcutId: Int32?, effect: Int64?, factcheck: Api.FactCheck?, reportDeliveryUntilDate: Int32?, paidMessageStars: Int64?, suggestedPost: Api.SuggestedPost?, scheduleRepeatPeriod: Int32?, summaryFromLanguage: String?) {
|
||||
public init(flags: Int32, flags2: Int32, id: Int32, fromId: Api.Peer?, fromBoostsApplied: Int32?, fromRank: String?, peerId: Api.Peer, savedPeerId: Api.Peer?, fwdFrom: Api.MessageFwdHeader?, viaBotId: Int64?, viaBusinessBotId: Int64?, 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?, reactions: Api.MessageReactions?, restrictionReason: [Api.RestrictionReason]?, ttlPeriod: Int32?, quickReplyShortcutId: Int32?, effect: Int64?, factcheck: Api.FactCheck?, reportDeliveryUntilDate: Int32?, paidMessageStars: Int64?, suggestedPost: Api.SuggestedPost?, scheduleRepeatPeriod: Int32?, summaryFromLanguage: String?) {
|
||||
self.flags = flags
|
||||
self.flags2 = flags2
|
||||
self.id = id
|
||||
self.fromId = fromId
|
||||
self.fromBoostsApplied = fromBoostsApplied
|
||||
self.fromRank = fromRank
|
||||
self.peerId = peerId
|
||||
self.savedPeerId = savedPeerId
|
||||
self.fwdFrom = fwdFrom
|
||||
|
|
@ -1129,7 +1131,7 @@ public extension Api {
|
|||
switch self {
|
||||
case .message(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1665888023)
|
||||
buffer.appendInt32(988112002)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.flags2, buffer: buffer, boxed: false)
|
||||
|
|
@ -1140,6 +1142,9 @@ public extension Api {
|
|||
if Int(_data.flags) & Int(1 << 29) != 0 {
|
||||
serializeInt32(_data.fromBoostsApplied!, buffer: buffer, boxed: false)
|
||||
}
|
||||
if Int(_data.flags2) & Int(1 << 12) != 0 {
|
||||
serializeString(_data.fromRank!, buffer: buffer, boxed: false)
|
||||
}
|
||||
_data.peerId.serialize(buffer, true)
|
||||
if Int(_data.flags) & Int(1 << 28) != 0 {
|
||||
_data.savedPeerId!.serialize(buffer, true)
|
||||
|
|
@ -1268,7 +1273,7 @@ public extension Api {
|
|||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .message(let _data):
|
||||
return ("message", [("flags", _data.flags as Any), ("flags2", _data.flags2 as Any), ("id", _data.id as Any), ("fromId", _data.fromId as Any), ("fromBoostsApplied", _data.fromBoostsApplied as Any), ("peerId", _data.peerId as Any), ("savedPeerId", _data.savedPeerId as Any), ("fwdFrom", _data.fwdFrom as Any), ("viaBotId", _data.viaBotId as Any), ("viaBusinessBotId", _data.viaBusinessBotId as Any), ("replyTo", _data.replyTo as Any), ("date", _data.date as Any), ("message", _data.message as Any), ("media", _data.media as Any), ("replyMarkup", _data.replyMarkup as Any), ("entities", _data.entities as Any), ("views", _data.views as Any), ("forwards", _data.forwards as Any), ("replies", _data.replies as Any), ("editDate", _data.editDate as Any), ("postAuthor", _data.postAuthor as Any), ("groupedId", _data.groupedId as Any), ("reactions", _data.reactions as Any), ("restrictionReason", _data.restrictionReason as Any), ("ttlPeriod", _data.ttlPeriod as Any), ("quickReplyShortcutId", _data.quickReplyShortcutId as Any), ("effect", _data.effect as Any), ("factcheck", _data.factcheck as Any), ("reportDeliveryUntilDate", _data.reportDeliveryUntilDate as Any), ("paidMessageStars", _data.paidMessageStars as Any), ("suggestedPost", _data.suggestedPost as Any), ("scheduleRepeatPeriod", _data.scheduleRepeatPeriod as Any), ("summaryFromLanguage", _data.summaryFromLanguage as Any)])
|
||||
return ("message", [("flags", _data.flags as Any), ("flags2", _data.flags2 as Any), ("id", _data.id as Any), ("fromId", _data.fromId as Any), ("fromBoostsApplied", _data.fromBoostsApplied as Any), ("fromRank", _data.fromRank as Any), ("peerId", _data.peerId as Any), ("savedPeerId", _data.savedPeerId as Any), ("fwdFrom", _data.fwdFrom as Any), ("viaBotId", _data.viaBotId as Any), ("viaBusinessBotId", _data.viaBusinessBotId as Any), ("replyTo", _data.replyTo as Any), ("date", _data.date as Any), ("message", _data.message as Any), ("media", _data.media as Any), ("replyMarkup", _data.replyMarkup as Any), ("entities", _data.entities as Any), ("views", _data.views as Any), ("forwards", _data.forwards as Any), ("replies", _data.replies as Any), ("editDate", _data.editDate as Any), ("postAuthor", _data.postAuthor as Any), ("groupedId", _data.groupedId as Any), ("reactions", _data.reactions as Any), ("restrictionReason", _data.restrictionReason as Any), ("ttlPeriod", _data.ttlPeriod as Any), ("quickReplyShortcutId", _data.quickReplyShortcutId as Any), ("effect", _data.effect as Any), ("factcheck", _data.factcheck as Any), ("reportDeliveryUntilDate", _data.reportDeliveryUntilDate as Any), ("paidMessageStars", _data.paidMessageStars as Any), ("suggestedPost", _data.suggestedPost as Any), ("scheduleRepeatPeriod", _data.scheduleRepeatPeriod as Any), ("summaryFromLanguage", _data.summaryFromLanguage as Any)])
|
||||
case .messageEmpty(let _data):
|
||||
return ("messageEmpty", [("flags", _data.flags as Any), ("id", _data.id as Any), ("peerId", _data.peerId as Any)])
|
||||
case .messageService(let _data):
|
||||
|
|
@ -1293,171 +1298,176 @@ public extension Api {
|
|||
if Int(_1!) & Int(1 << 29) != 0 {
|
||||
_5 = reader.readInt32()
|
||||
}
|
||||
var _6: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_6 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
var _6: String?
|
||||
if Int(_2!) & Int(1 << 12) != 0 {
|
||||
_6 = parseString(reader)
|
||||
}
|
||||
var _7: Api.Peer?
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
var _8: Api.Peer?
|
||||
if Int(_1!) & Int(1 << 28) != 0 {
|
||||
if let signature = reader.readInt32() {
|
||||
_7 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||
}
|
||||
}
|
||||
var _8: Api.MessageFwdHeader?
|
||||
var _9: Api.MessageFwdHeader?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {
|
||||
if let signature = reader.readInt32() {
|
||||
_8 = Api.parse(reader, signature: signature) as? Api.MessageFwdHeader
|
||||
_9 = Api.parse(reader, signature: signature) as? Api.MessageFwdHeader
|
||||
}
|
||||
}
|
||||
var _9: Int64?
|
||||
if Int(_1!) & Int(1 << 11) != 0 {
|
||||
_9 = reader.readInt64()
|
||||
}
|
||||
var _10: Int64?
|
||||
if Int(_2!) & Int(1 << 0) != 0 {
|
||||
if Int(_1!) & Int(1 << 11) != 0 {
|
||||
_10 = reader.readInt64()
|
||||
}
|
||||
var _11: Api.MessageReplyHeader?
|
||||
var _11: Int64?
|
||||
if Int(_2!) & Int(1 << 0) != 0 {
|
||||
_11 = reader.readInt64()
|
||||
}
|
||||
var _12: Api.MessageReplyHeader?
|
||||
if Int(_1!) & Int(1 << 3) != 0 {
|
||||
if let signature = reader.readInt32() {
|
||||
_11 = Api.parse(reader, signature: signature) as? Api.MessageReplyHeader
|
||||
_12 = Api.parse(reader, signature: signature) as? Api.MessageReplyHeader
|
||||
}
|
||||
}
|
||||
var _12: Int32?
|
||||
_12 = reader.readInt32()
|
||||
var _13: String?
|
||||
_13 = parseString(reader)
|
||||
var _14: Api.MessageMedia?
|
||||
var _13: Int32?
|
||||
_13 = reader.readInt32()
|
||||
var _14: String?
|
||||
_14 = parseString(reader)
|
||||
var _15: Api.MessageMedia?
|
||||
if Int(_1!) & Int(1 << 9) != 0 {
|
||||
if let signature = reader.readInt32() {
|
||||
_14 = Api.parse(reader, signature: signature) as? Api.MessageMedia
|
||||
_15 = Api.parse(reader, signature: signature) as? Api.MessageMedia
|
||||
}
|
||||
}
|
||||
var _15: Api.ReplyMarkup?
|
||||
var _16: Api.ReplyMarkup?
|
||||
if Int(_1!) & Int(1 << 6) != 0 {
|
||||
if let signature = reader.readInt32() {
|
||||
_15 = Api.parse(reader, signature: signature) as? Api.ReplyMarkup
|
||||
_16 = Api.parse(reader, signature: signature) as? Api.ReplyMarkup
|
||||
}
|
||||
}
|
||||
var _16: [Api.MessageEntity]?
|
||||
var _17: [Api.MessageEntity]?
|
||||
if Int(_1!) & Int(1 << 7) != 0 {
|
||||
if let _ = reader.readInt32() {
|
||||
_16 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||
_17 = Api.parseVector(reader, elementSignature: 0, elementType: Api.MessageEntity.self)
|
||||
}
|
||||
}
|
||||
var _17: Int32?
|
||||
if Int(_1!) & Int(1 << 10) != 0 {
|
||||
_17 = reader.readInt32()
|
||||
}
|
||||
var _18: Int32?
|
||||
if Int(_1!) & Int(1 << 10) != 0 {
|
||||
_18 = reader.readInt32()
|
||||
}
|
||||
var _19: Api.MessageReplies?
|
||||
var _19: Int32?
|
||||
if Int(_1!) & Int(1 << 10) != 0 {
|
||||
_19 = reader.readInt32()
|
||||
}
|
||||
var _20: Api.MessageReplies?
|
||||
if Int(_1!) & Int(1 << 23) != 0 {
|
||||
if let signature = reader.readInt32() {
|
||||
_19 = Api.parse(reader, signature: signature) as? Api.MessageReplies
|
||||
_20 = Api.parse(reader, signature: signature) as? Api.MessageReplies
|
||||
}
|
||||
}
|
||||
var _20: Int32?
|
||||
var _21: Int32?
|
||||
if Int(_1!) & Int(1 << 15) != 0 {
|
||||
_20 = reader.readInt32()
|
||||
_21 = reader.readInt32()
|
||||
}
|
||||
var _21: String?
|
||||
var _22: String?
|
||||
if Int(_1!) & Int(1 << 16) != 0 {
|
||||
_21 = parseString(reader)
|
||||
_22 = parseString(reader)
|
||||
}
|
||||
var _22: Int64?
|
||||
var _23: Int64?
|
||||
if Int(_1!) & Int(1 << 17) != 0 {
|
||||
_22 = reader.readInt64()
|
||||
_23 = reader.readInt64()
|
||||
}
|
||||
var _23: Api.MessageReactions?
|
||||
var _24: Api.MessageReactions?
|
||||
if Int(_1!) & Int(1 << 20) != 0 {
|
||||
if let signature = reader.readInt32() {
|
||||
_23 = Api.parse(reader, signature: signature) as? Api.MessageReactions
|
||||
_24 = Api.parse(reader, signature: signature) as? Api.MessageReactions
|
||||
}
|
||||
}
|
||||
var _24: [Api.RestrictionReason]?
|
||||
var _25: [Api.RestrictionReason]?
|
||||
if Int(_1!) & Int(1 << 22) != 0 {
|
||||
if let _ = reader.readInt32() {
|
||||
_24 = Api.parseVector(reader, elementSignature: 0, elementType: Api.RestrictionReason.self)
|
||||
_25 = Api.parseVector(reader, elementSignature: 0, elementType: Api.RestrictionReason.self)
|
||||
}
|
||||
}
|
||||
var _25: Int32?
|
||||
if Int(_1!) & Int(1 << 25) != 0 {
|
||||
_25 = reader.readInt32()
|
||||
}
|
||||
var _26: Int32?
|
||||
if Int(_1!) & Int(1 << 30) != 0 {
|
||||
if Int(_1!) & Int(1 << 25) != 0 {
|
||||
_26 = reader.readInt32()
|
||||
}
|
||||
var _27: Int64?
|
||||
if Int(_2!) & Int(1 << 2) != 0 {
|
||||
_27 = reader.readInt64()
|
||||
var _27: Int32?
|
||||
if Int(_1!) & Int(1 << 30) != 0 {
|
||||
_27 = reader.readInt32()
|
||||
}
|
||||
var _28: Api.FactCheck?
|
||||
var _28: Int64?
|
||||
if Int(_2!) & Int(1 << 2) != 0 {
|
||||
_28 = reader.readInt64()
|
||||
}
|
||||
var _29: Api.FactCheck?
|
||||
if Int(_2!) & Int(1 << 3) != 0 {
|
||||
if let signature = reader.readInt32() {
|
||||
_28 = Api.parse(reader, signature: signature) as? Api.FactCheck
|
||||
_29 = Api.parse(reader, signature: signature) as? Api.FactCheck
|
||||
}
|
||||
}
|
||||
var _29: Int32?
|
||||
var _30: Int32?
|
||||
if Int(_2!) & Int(1 << 5) != 0 {
|
||||
_29 = reader.readInt32()
|
||||
_30 = reader.readInt32()
|
||||
}
|
||||
var _30: Int64?
|
||||
var _31: Int64?
|
||||
if Int(_2!) & Int(1 << 6) != 0 {
|
||||
_30 = reader.readInt64()
|
||||
_31 = reader.readInt64()
|
||||
}
|
||||
var _31: Api.SuggestedPost?
|
||||
var _32: Api.SuggestedPost?
|
||||
if Int(_2!) & Int(1 << 7) != 0 {
|
||||
if let signature = reader.readInt32() {
|
||||
_31 = Api.parse(reader, signature: signature) as? Api.SuggestedPost
|
||||
_32 = Api.parse(reader, signature: signature) as? Api.SuggestedPost
|
||||
}
|
||||
}
|
||||
var _32: Int32?
|
||||
var _33: Int32?
|
||||
if Int(_2!) & Int(1 << 10) != 0 {
|
||||
_32 = reader.readInt32()
|
||||
_33 = reader.readInt32()
|
||||
}
|
||||
var _33: String?
|
||||
var _34: String?
|
||||
if Int(_2!) & Int(1 << 11) != 0 {
|
||||
_33 = parseString(reader)
|
||||
_34 = parseString(reader)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 8) == 0) || _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 29) == 0) || _5 != nil
|
||||
let _c6 = _6 != nil
|
||||
let _c7 = (Int(_1!) & Int(1 << 28) == 0) || _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(_2!) & Int(1 << 0) == 0) || _10 != nil
|
||||
let _c11 = (Int(_1!) & Int(1 << 3) == 0) || _11 != nil
|
||||
let _c12 = _12 != nil
|
||||
let _c6 = (Int(_2!) & Int(1 << 12) == 0) || _6 != nil
|
||||
let _c7 = _7 != nil
|
||||
let _c8 = (Int(_1!) & Int(1 << 28) == 0) || _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(_2!) & Int(1 << 0) == 0) || _11 != nil
|
||||
let _c12 = (Int(_1!) & Int(1 << 3) == 0) || _12 != nil
|
||||
let _c13 = _13 != nil
|
||||
let _c14 = (Int(_1!) & Int(1 << 9) == 0) || _14 != nil
|
||||
let _c15 = (Int(_1!) & Int(1 << 6) == 0) || _15 != nil
|
||||
let _c16 = (Int(_1!) & Int(1 << 7) == 0) || _16 != nil
|
||||
let _c17 = (Int(_1!) & Int(1 << 10) == 0) || _17 != nil
|
||||
let _c14 = _14 != nil
|
||||
let _c15 = (Int(_1!) & Int(1 << 9) == 0) || _15 != nil
|
||||
let _c16 = (Int(_1!) & Int(1 << 6) == 0) || _16 != nil
|
||||
let _c17 = (Int(_1!) & Int(1 << 7) == 0) || _17 != nil
|
||||
let _c18 = (Int(_1!) & Int(1 << 10) == 0) || _18 != nil
|
||||
let _c19 = (Int(_1!) & Int(1 << 23) == 0) || _19 != nil
|
||||
let _c20 = (Int(_1!) & Int(1 << 15) == 0) || _20 != nil
|
||||
let _c21 = (Int(_1!) & Int(1 << 16) == 0) || _21 != nil
|
||||
let _c22 = (Int(_1!) & Int(1 << 17) == 0) || _22 != nil
|
||||
let _c23 = (Int(_1!) & Int(1 << 20) == 0) || _23 != nil
|
||||
let _c24 = (Int(_1!) & Int(1 << 22) == 0) || _24 != nil
|
||||
let _c25 = (Int(_1!) & Int(1 << 25) == 0) || _25 != nil
|
||||
let _c26 = (Int(_1!) & Int(1 << 30) == 0) || _26 != nil
|
||||
let _c27 = (Int(_2!) & Int(1 << 2) == 0) || _27 != nil
|
||||
let _c28 = (Int(_2!) & Int(1 << 3) == 0) || _28 != nil
|
||||
let _c29 = (Int(_2!) & Int(1 << 5) == 0) || _29 != nil
|
||||
let _c30 = (Int(_2!) & Int(1 << 6) == 0) || _30 != nil
|
||||
let _c31 = (Int(_2!) & Int(1 << 7) == 0) || _31 != nil
|
||||
let _c32 = (Int(_2!) & Int(1 << 10) == 0) || _32 != nil
|
||||
let _c33 = (Int(_2!) & Int(1 << 11) == 0) || _33 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 {
|
||||
return Api.Message.message(Cons_message(flags: _1!, flags2: _2!, id: _3!, fromId: _4, fromBoostsApplied: _5, peerId: _6!, savedPeerId: _7, fwdFrom: _8, viaBotId: _9, viaBusinessBotId: _10, replyTo: _11, date: _12!, message: _13!, media: _14, replyMarkup: _15, entities: _16, views: _17, forwards: _18, replies: _19, editDate: _20, postAuthor: _21, groupedId: _22, reactions: _23, restrictionReason: _24, ttlPeriod: _25, quickReplyShortcutId: _26, effect: _27, factcheck: _28, reportDeliveryUntilDate: _29, paidMessageStars: _30, suggestedPost: _31, scheduleRepeatPeriod: _32, summaryFromLanguage: _33))
|
||||
let _c19 = (Int(_1!) & Int(1 << 10) == 0) || _19 != nil
|
||||
let _c20 = (Int(_1!) & Int(1 << 23) == 0) || _20 != nil
|
||||
let _c21 = (Int(_1!) & Int(1 << 15) == 0) || _21 != nil
|
||||
let _c22 = (Int(_1!) & Int(1 << 16) == 0) || _22 != nil
|
||||
let _c23 = (Int(_1!) & Int(1 << 17) == 0) || _23 != nil
|
||||
let _c24 = (Int(_1!) & Int(1 << 20) == 0) || _24 != nil
|
||||
let _c25 = (Int(_1!) & Int(1 << 22) == 0) || _25 != nil
|
||||
let _c26 = (Int(_1!) & Int(1 << 25) == 0) || _26 != nil
|
||||
let _c27 = (Int(_1!) & Int(1 << 30) == 0) || _27 != nil
|
||||
let _c28 = (Int(_2!) & Int(1 << 2) == 0) || _28 != nil
|
||||
let _c29 = (Int(_2!) & Int(1 << 3) == 0) || _29 != nil
|
||||
let _c30 = (Int(_2!) & Int(1 << 5) == 0) || _30 != nil
|
||||
let _c31 = (Int(_2!) & Int(1 << 6) == 0) || _31 != nil
|
||||
let _c32 = (Int(_2!) & Int(1 << 7) == 0) || _32 != nil
|
||||
let _c33 = (Int(_2!) & Int(1 << 10) == 0) || _33 != nil
|
||||
let _c34 = (Int(_2!) & Int(1 << 11) == 0) || _34 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 && _c17 && _c18 && _c19 && _c20 && _c21 && _c22 && _c23 && _c24 && _c25 && _c26 && _c27 && _c28 && _c29 && _c30 && _c31 && _c32 && _c33 && _c34 {
|
||||
return Api.Message.message(Cons_message(flags: _1!, flags2: _2!, id: _3!, fromId: _4, fromBoostsApplied: _5, fromRank: _6, peerId: _7!, savedPeerId: _8, fwdFrom: _9, viaBotId: _10, viaBusinessBotId: _11, replyTo: _12, date: _13!, message: _14!, media: _15, replyMarkup: _16, entities: _17, views: _18, forwards: _19, replies: _20, editDate: _21, postAuthor: _22, groupedId: _23, reactions: _24, restrictionReason: _25, ttlPeriod: _26, quickReplyShortcutId: _27, effect: _28, factcheck: _29, reportDeliveryUntilDate: _30, paidMessageStars: _31, suggestedPost: _32, scheduleRepeatPeriod: _33, summaryFromLanguage: _34))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -517,6 +517,18 @@ public extension Api {
|
|||
self.version = version
|
||||
}
|
||||
}
|
||||
public class Cons_updateChatParticipantRank {
|
||||
public var chatId: Int64
|
||||
public var userId: Int64
|
||||
public var rank: String
|
||||
public var version: Int32
|
||||
public init(chatId: Int64, userId: Int64, rank: String, version: Int32) {
|
||||
self.chatId = chatId
|
||||
self.userId = userId
|
||||
self.rank = rank
|
||||
self.version = version
|
||||
}
|
||||
}
|
||||
public class Cons_updateChatParticipants {
|
||||
public var participants: Api.ChatParticipants
|
||||
public init(participants: Api.ChatParticipants) {
|
||||
|
|
@ -1485,6 +1497,7 @@ public extension Api {
|
|||
case updateChatParticipantAdd(Cons_updateChatParticipantAdd)
|
||||
case updateChatParticipantAdmin(Cons_updateChatParticipantAdmin)
|
||||
case updateChatParticipantDelete(Cons_updateChatParticipantDelete)
|
||||
case updateChatParticipantRank(Cons_updateChatParticipantRank)
|
||||
case updateChatParticipants(Cons_updateChatParticipants)
|
||||
case updateChatUserTyping(Cons_updateChatUserTyping)
|
||||
case updateConfig
|
||||
|
|
@ -2017,6 +2030,15 @@ public extension Api {
|
|||
serializeInt64(_data.userId, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.version, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .updateChatParticipantRank(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1115461703)
|
||||
}
|
||||
serializeInt64(_data.chatId, buffer: buffer, boxed: false)
|
||||
serializeInt64(_data.userId, buffer: buffer, boxed: false)
|
||||
serializeString(_data.rank, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.version, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .updateChatParticipants(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(125178264)
|
||||
|
|
@ -3100,6 +3122,8 @@ public extension Api {
|
|||
return ("updateChatParticipantAdmin", [("chatId", _data.chatId as Any), ("userId", _data.userId as Any), ("isAdmin", _data.isAdmin as Any), ("version", _data.version as Any)])
|
||||
case .updateChatParticipantDelete(let _data):
|
||||
return ("updateChatParticipantDelete", [("chatId", _data.chatId as Any), ("userId", _data.userId as Any), ("version", _data.version as Any)])
|
||||
case .updateChatParticipantRank(let _data):
|
||||
return ("updateChatParticipantRank", [("chatId", _data.chatId as Any), ("userId", _data.userId as Any), ("rank", _data.rank as Any), ("version", _data.version as Any)])
|
||||
case .updateChatParticipants(let _data):
|
||||
return ("updateChatParticipants", [("participants", _data.participants as Any)])
|
||||
case .updateChatUserTyping(let _data):
|
||||
|
|
@ -4233,6 +4257,26 @@ public extension Api {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_updateChatParticipantRank(_ reader: BufferReader) -> Update? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: String?
|
||||
_3 = parseString(reader)
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.Update.updateChatParticipantRank(Cons_updateChatParticipantRank(chatId: _1!, userId: _2!, rank: _3!, version: _4!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_updateChatParticipants(_ reader: BufferReader) -> Update? {
|
||||
var _1: Api.ChatParticipants?
|
||||
if let signature = reader.readInt32() {
|
||||
|
|
|
|||
|
|
@ -170,11 +170,13 @@ public extension Api {
|
|||
public var userId: Int64
|
||||
public var date: Int32
|
||||
public var subscriptionUntilDate: Int32?
|
||||
public init(flags: Int32, userId: Int64, date: Int32, subscriptionUntilDate: Int32?) {
|
||||
public var rank: String?
|
||||
public init(flags: Int32, userId: Int64, date: Int32, subscriptionUntilDate: Int32?, rank: String?) {
|
||||
self.flags = flags
|
||||
self.userId = userId
|
||||
self.date = date
|
||||
self.subscriptionUntilDate = subscriptionUntilDate
|
||||
self.rank = rank
|
||||
}
|
||||
}
|
||||
public class Cons_channelParticipantAdmin {
|
||||
|
|
@ -233,12 +235,14 @@ public extension Api {
|
|||
public var inviterId: Int64
|
||||
public var date: Int32
|
||||
public var subscriptionUntilDate: Int32?
|
||||
public init(flags: Int32, userId: Int64, inviterId: Int64, date: Int32, subscriptionUntilDate: Int32?) {
|
||||
public var rank: String?
|
||||
public init(flags: Int32, userId: Int64, inviterId: Int64, date: Int32, subscriptionUntilDate: Int32?, rank: String?) {
|
||||
self.flags = flags
|
||||
self.userId = userId
|
||||
self.inviterId = inviterId
|
||||
self.date = date
|
||||
self.subscriptionUntilDate = subscriptionUntilDate
|
||||
self.rank = rank
|
||||
}
|
||||
}
|
||||
case channelParticipant(Cons_channelParticipant)
|
||||
|
|
@ -252,7 +256,7 @@ public extension Api {
|
|||
switch self {
|
||||
case .channelParticipant(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-885426663)
|
||||
buffer.appendInt32(466961494)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(_data.userId, buffer: buffer, boxed: false)
|
||||
|
|
@ -260,6 +264,9 @@ public extension Api {
|
|||
if Int(_data.flags) & Int(1 << 0) != 0 {
|
||||
serializeInt32(_data.subscriptionUntilDate!, buffer: buffer, boxed: false)
|
||||
}
|
||||
if Int(_data.flags) & Int(1 << 2) != 0 {
|
||||
serializeString(_data.rank!, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .channelParticipantAdmin(let _data):
|
||||
if boxed {
|
||||
|
|
@ -306,7 +313,7 @@ public extension Api {
|
|||
break
|
||||
case .channelParticipantSelf(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(1331723247)
|
||||
buffer.appendInt32(-1454929382)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(_data.userId, buffer: buffer, boxed: false)
|
||||
|
|
@ -315,6 +322,9 @@ public extension Api {
|
|||
if Int(_data.flags) & Int(1 << 1) != 0 {
|
||||
serializeInt32(_data.subscriptionUntilDate!, buffer: buffer, boxed: false)
|
||||
}
|
||||
if Int(_data.flags) & Int(1 << 2) != 0 {
|
||||
serializeString(_data.rank!, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -322,7 +332,7 @@ public extension Api {
|
|||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .channelParticipant(let _data):
|
||||
return ("channelParticipant", [("flags", _data.flags as Any), ("userId", _data.userId as Any), ("date", _data.date as Any), ("subscriptionUntilDate", _data.subscriptionUntilDate as Any)])
|
||||
return ("channelParticipant", [("flags", _data.flags as Any), ("userId", _data.userId as Any), ("date", _data.date as Any), ("subscriptionUntilDate", _data.subscriptionUntilDate as Any), ("rank", _data.rank as Any)])
|
||||
case .channelParticipantAdmin(let _data):
|
||||
return ("channelParticipantAdmin", [("flags", _data.flags as Any), ("userId", _data.userId as Any), ("inviterId", _data.inviterId as Any), ("promotedBy", _data.promotedBy as Any), ("date", _data.date as Any), ("adminRights", _data.adminRights as Any), ("rank", _data.rank as Any)])
|
||||
case .channelParticipantBanned(let _data):
|
||||
|
|
@ -332,7 +342,7 @@ public extension Api {
|
|||
case .channelParticipantLeft(let _data):
|
||||
return ("channelParticipantLeft", [("peer", _data.peer as Any)])
|
||||
case .channelParticipantSelf(let _data):
|
||||
return ("channelParticipantSelf", [("flags", _data.flags as Any), ("userId", _data.userId as Any), ("inviterId", _data.inviterId as Any), ("date", _data.date as Any), ("subscriptionUntilDate", _data.subscriptionUntilDate as Any)])
|
||||
return ("channelParticipantSelf", [("flags", _data.flags as Any), ("userId", _data.userId as Any), ("inviterId", _data.inviterId as Any), ("date", _data.date as Any), ("subscriptionUntilDate", _data.subscriptionUntilDate as Any), ("rank", _data.rank as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -347,12 +357,17 @@ public extension Api {
|
|||
if Int(_1!) & Int(1 << 0) != 0 {
|
||||
_4 = reader.readInt32()
|
||||
}
|
||||
var _5: String?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {
|
||||
_5 = parseString(reader)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.ChannelParticipant.channelParticipant(Cons_channelParticipant(flags: _1!, userId: _2!, date: _3!, subscriptionUntilDate: _4))
|
||||
let _c5 = (Int(_1!) & Int(1 << 2) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.ChannelParticipant.channelParticipant(Cons_channelParticipant(flags: _1!, userId: _2!, date: _3!, subscriptionUntilDate: _4, rank: _5))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
@ -470,13 +485,18 @@ public extension Api {
|
|||
if Int(_1!) & Int(1 << 1) != 0 {
|
||||
_5 = reader.readInt32()
|
||||
}
|
||||
var _6: String?
|
||||
if Int(_1!) & Int(1 << 2) != 0 {
|
||||
_6 = parseString(reader)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 1) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.ChannelParticipant.channelParticipantSelf(Cons_channelParticipantSelf(flags: _1!, userId: _2!, inviterId: _3!, date: _4!, subscriptionUntilDate: _5))
|
||||
let _c6 = (Int(_1!) & Int(1 << 2) == 0) || _6 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 {
|
||||
return Api.ChannelParticipant.channelParticipantSelf(Cons_channelParticipantSelf(flags: _1!, userId: _2!, inviterId: _3!, date: _4!, subscriptionUntilDate: _5, rank: _6))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -5743,6 +5743,23 @@ public extension Api.functions.messages {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func editChatParticipantRank(peer: Api.InputPeer, participant: Api.InputPeer, rank: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-1609616720)
|
||||
peer.serialize(buffer, true)
|
||||
participant.serialize(buffer, true)
|
||||
serializeString(rank, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "messages.editChatParticipantRank", parameters: [("peer", String(describing: peer)), ("participant", String(describing: participant)), ("rank", String(describing: rank))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Updates?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Updates
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func editChatPhoto(chatId: Int64, photo: Api.InputChatPhoto) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
let buffer = Buffer()
|
||||
|
|
@ -9443,6 +9460,22 @@ public extension Api.functions.messages {
|
|||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func toggleChatCustomRanks(peer: Api.InputPeer, enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(874013158)
|
||||
peer.serialize(buffer, true)
|
||||
enabled.serialize(buffer, true)
|
||||
return (FunctionDescription(name: "messages.toggleChatCustomRanks", parameters: [("peer", String(describing: peer)), ("enabled", String(describing: enabled))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.Updates?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.Updates
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
}
|
||||
public extension Api.functions.messages {
|
||||
static func toggleDialogFilterTags(enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
|
|
|
|||
|
|
@ -115,29 +115,41 @@ public extension Api {
|
|||
public extension Api {
|
||||
enum ChatParticipant: TypeConstructorDescription {
|
||||
public class Cons_chatParticipant {
|
||||
public var flags: Int32
|
||||
public var userId: Int64
|
||||
public var inviterId: Int64
|
||||
public var date: Int32
|
||||
public init(userId: Int64, inviterId: Int64, date: Int32) {
|
||||
public var rank: String?
|
||||
public init(flags: Int32, userId: Int64, inviterId: Int64, date: Int32, rank: String?) {
|
||||
self.flags = flags
|
||||
self.userId = userId
|
||||
self.inviterId = inviterId
|
||||
self.date = date
|
||||
self.rank = rank
|
||||
}
|
||||
}
|
||||
public class Cons_chatParticipantAdmin {
|
||||
public var flags: Int32
|
||||
public var userId: Int64
|
||||
public var inviterId: Int64
|
||||
public var date: Int32
|
||||
public init(userId: Int64, inviterId: Int64, date: Int32) {
|
||||
public var rank: String?
|
||||
public init(flags: Int32, userId: Int64, inviterId: Int64, date: Int32, rank: String?) {
|
||||
self.flags = flags
|
||||
self.userId = userId
|
||||
self.inviterId = inviterId
|
||||
self.date = date
|
||||
self.rank = rank
|
||||
}
|
||||
}
|
||||
public class Cons_chatParticipantCreator {
|
||||
public var flags: Int32
|
||||
public var userId: Int64
|
||||
public init(userId: Int64) {
|
||||
public var rank: String?
|
||||
public init(flags: Int32, userId: Int64, rank: String?) {
|
||||
self.flags = flags
|
||||
self.userId = userId
|
||||
self.rank = rank
|
||||
}
|
||||
}
|
||||
case chatParticipant(Cons_chatParticipant)
|
||||
|
|
@ -148,25 +160,37 @@ public extension Api {
|
|||
switch self {
|
||||
case .chatParticipant(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1070776313)
|
||||
buffer.appendInt32(954703838)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(_data.userId, buffer: buffer, boxed: false)
|
||||
serializeInt64(_data.inviterId, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.date, buffer: buffer, boxed: false)
|
||||
if Int(_data.flags) & Int(1 << 0) != 0 {
|
||||
serializeString(_data.rank!, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .chatParticipantAdmin(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1600962725)
|
||||
buffer.appendInt32(56677842)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(_data.userId, buffer: buffer, boxed: false)
|
||||
serializeInt64(_data.inviterId, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.date, buffer: buffer, boxed: false)
|
||||
if Int(_data.flags) & Int(1 << 0) != 0 {
|
||||
serializeString(_data.rank!, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .chatParticipantCreator(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-462696732)
|
||||
buffer.appendInt32(-503814216)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt64(_data.userId, buffer: buffer, boxed: false)
|
||||
if Int(_data.flags) & Int(1 << 0) != 0 {
|
||||
serializeString(_data.rank!, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -174,54 +198,78 @@ public extension Api {
|
|||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .chatParticipant(let _data):
|
||||
return ("chatParticipant", [("userId", _data.userId as Any), ("inviterId", _data.inviterId as Any), ("date", _data.date as Any)])
|
||||
return ("chatParticipant", [("flags", _data.flags as Any), ("userId", _data.userId as Any), ("inviterId", _data.inviterId as Any), ("date", _data.date as Any), ("rank", _data.rank as Any)])
|
||||
case .chatParticipantAdmin(let _data):
|
||||
return ("chatParticipantAdmin", [("userId", _data.userId as Any), ("inviterId", _data.inviterId as Any), ("date", _data.date as Any)])
|
||||
return ("chatParticipantAdmin", [("flags", _data.flags as Any), ("userId", _data.userId as Any), ("inviterId", _data.inviterId as Any), ("date", _data.date as Any), ("rank", _data.rank as Any)])
|
||||
case .chatParticipantCreator(let _data):
|
||||
return ("chatParticipantCreator", [("userId", _data.userId as Any)])
|
||||
return ("chatParticipantCreator", [("flags", _data.flags as Any), ("userId", _data.userId as Any), ("rank", _data.rank as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_chatParticipant(_ reader: BufferReader) -> ChatParticipant? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {
|
||||
_5 = parseString(reader)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.ChatParticipant.chatParticipant(Cons_chatParticipant(userId: _1!, inviterId: _2!, date: _3!))
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.ChatParticipant.chatParticipant(Cons_chatParticipant(flags: _1!, userId: _2!, inviterId: _3!, date: _4!, rank: _5))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_chatParticipantAdmin(_ reader: BufferReader) -> ChatParticipant? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _3: Int64?
|
||||
_3 = reader.readInt64()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {
|
||||
_5 = parseString(reader)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.ChatParticipant.chatParticipantAdmin(Cons_chatParticipantAdmin(userId: _1!, inviterId: _2!, date: _3!))
|
||||
let _c4 = _4 != nil
|
||||
let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.ChatParticipant.chatParticipantAdmin(Cons_chatParticipantAdmin(flags: _1!, userId: _2!, inviterId: _3!, date: _4!, rank: _5))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_chatParticipantCreator(_ reader: BufferReader) -> ChatParticipant? {
|
||||
var _1: Int64?
|
||||
_1 = reader.readInt64()
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int64?
|
||||
_2 = reader.readInt64()
|
||||
var _3: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {
|
||||
_3 = parseString(reader)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
if _c1 {
|
||||
return Api.ChatParticipant.chatParticipantCreator(Cons_chatParticipantCreator(userId: _1!))
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
if _c1 && _c2 && _c3 {
|
||||
return Api.ChatParticipant.chatParticipantCreator(Cons_chatParticipantCreator(flags: _1!, userId: _2!, rank: _3))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import MultilineTextComponent
|
|||
import BalancedTextComponent
|
||||
import TelegramPresentationData
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
import Markdown
|
||||
import GlassControls
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ private var declaredEncodables: Void = {
|
|||
declareEncodable(ViewCountMessageAttribute.self, f: { ViewCountMessageAttribute(decoder: $0) })
|
||||
declareEncodable(ForwardCountMessageAttribute.self, f: { ForwardCountMessageAttribute(decoder: $0) })
|
||||
declareEncodable(BoostCountMessageAttribute.self, f: { BoostCountMessageAttribute(decoder: $0) })
|
||||
declareEncodable(ParticipantRankMessageAttribute.self, f: { ParticipantRankMessageAttribute(decoder: $0) })
|
||||
declareEncodable(NotificationInfoMessageAttribute.self, f: { NotificationInfoMessageAttribute(decoder: $0) })
|
||||
declareEncodable(TelegramMediaAction.self, f: { TelegramMediaAction(decoder: $0) })
|
||||
declareEncodable(TelegramPeerNotificationSettings.self, f: { TelegramPeerNotificationSettings(decoder: $0) })
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
|
|||
if (flags & Int32(1 << 25)) != 0 {
|
||||
groupFlags.insert(.copyProtectionEnabled)
|
||||
}
|
||||
if (flags & Int32(1 << 19)) != 0 {
|
||||
groupFlags.insert(.customRanksEnabled)
|
||||
}
|
||||
return TelegramGroup(id: PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(id)), title: title, photo: imageRepresentationsForApiChatPhoto(photo), participantCount: Int(participantsCount), role: role, membership: left ? .Left : .Member, flags: groupFlags, defaultBannedRights: defaultBannedRights.flatMap(TelegramChatBannedRights.init(apiBannedRights:)), migrationReference: migrationReference, creationDate: date, version: Int(version))
|
||||
case let .chatEmpty(chatEmptyData):
|
||||
let id = chatEmptyData.id
|
||||
|
|
@ -149,7 +152,9 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? {
|
|||
if (flags2 & Int32(1 << 19)) != 0 {
|
||||
channelFlags.insert(.displayForumAsTabs)
|
||||
}
|
||||
|
||||
if (flags2 & Int32(1 << 20)) != 0 {
|
||||
channelFlags.insert(.customRanksEnabled)
|
||||
}
|
||||
var storiesHidden: Bool?
|
||||
if flags2 & (1 << 2) == 0 { // stories_hidden_min
|
||||
if flags2 & (1 << 1) != 0 {
|
||||
|
|
|
|||
|
|
@ -206,8 +206,8 @@ extension ChannelParticipant {
|
|||
init(apiParticipant: Api.ChannelParticipant) {
|
||||
switch apiParticipant {
|
||||
case let .channelParticipant(channelParticipantData):
|
||||
let (_, userId, date, subscriptionUntilDate) = (channelParticipantData.flags, channelParticipantData.userId, channelParticipantData.date, channelParticipantData.subscriptionUntilDate)
|
||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil, subscriptionUntilDate: subscriptionUntilDate)
|
||||
let (_, userId, date, subscriptionUntilDate, rank) = (channelParticipantData.flags, channelParticipantData.userId, channelParticipantData.date, channelParticipantData.subscriptionUntilDate, channelParticipantData.rank)
|
||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: rank, subscriptionUntilDate: subscriptionUntilDate)
|
||||
case let .channelParticipantCreator(channelParticipantCreatorData):
|
||||
let (_, userId, adminRights, rank) = (channelParticipantCreatorData.flags, channelParticipantCreatorData.userId, channelParticipantCreatorData.adminRights, channelParticipantCreatorData.rank)
|
||||
self = .creator(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), canBeEditedByAccountPeer: true), rank: rank)
|
||||
|
|
@ -220,8 +220,8 @@ extension ChannelParticipant {
|
|||
let (flags, userId, _, promotedBy, date, adminRights, rank) = (channelParticipantAdminData.flags, channelParticipantAdminData.userId, channelParticipantAdminData.inviterId, channelParticipantAdminData.promotedBy, channelParticipantAdminData.date, channelParticipantAdminData.adminRights, channelParticipantAdminData.rank)
|
||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights) ?? TelegramChatAdminRights(rights: []), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(promotedBy)), canBeEditedByAccountPeer: (flags & (1 << 0)) != 0), banInfo: nil, rank: rank, subscriptionUntilDate: nil)
|
||||
case let .channelParticipantSelf(channelParticipantSelfData):
|
||||
let (_, userId, _, date, subscriptionUntilDate) = (channelParticipantSelfData.flags, channelParticipantSelfData.userId, channelParticipantSelfData.inviterId, channelParticipantSelfData.date, channelParticipantSelfData.subscriptionUntilDate)
|
||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil, subscriptionUntilDate: subscriptionUntilDate)
|
||||
let (_, userId, _, date, subscriptionUntilDate, rank) = (channelParticipantSelfData.flags, channelParticipantSelfData.userId, channelParticipantSelfData.inviterId, channelParticipantSelfData.date, channelParticipantSelfData.subscriptionUntilDate, channelParticipantSelfData.rank)
|
||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedAt: date, adminInfo: nil, banInfo: nil, rank: rank, subscriptionUntilDate: subscriptionUntilDate)
|
||||
case let .channelParticipantLeft(channelParticipantLeftData):
|
||||
let (userId) = (channelParticipantLeftData.peer)
|
||||
self = .member(id: userId.peerId, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil, subscriptionUntilDate: nil)
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ extension GroupParticipant {
|
|||
init(apiParticipant: Api.ChatParticipant) {
|
||||
switch apiParticipant {
|
||||
case let .chatParticipantCreator(chatParticipantCreatorData):
|
||||
let userId = chatParticipantCreatorData.userId
|
||||
self = .creator(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)))
|
||||
let (userId, rank) = (chatParticipantCreatorData.userId, chatParticipantCreatorData.rank)
|
||||
self = .creator(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), rank: rank)
|
||||
case let .chatParticipantAdmin(chatParticipantAdminData):
|
||||
let (userId, inviterId, date) = (chatParticipantAdminData.userId, chatParticipantAdminData.inviterId, chatParticipantAdminData.date)
|
||||
self = .admin(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId)), invitedAt: date)
|
||||
let (userId, inviterId, date, rank) = (chatParticipantAdminData.userId, chatParticipantAdminData.inviterId, chatParticipantAdminData.date, chatParticipantAdminData.rank)
|
||||
self = .admin(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId)), invitedAt: date, rank: rank)
|
||||
case let .chatParticipant(chatParticipantData):
|
||||
let (userId, inviterId, date) = (chatParticipantData.userId, chatParticipantData.inviterId, chatParticipantData.date)
|
||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId)), invitedAt: date)
|
||||
let (userId, inviterId, date, rank) = (chatParticipantData.userId, chatParticipantData.inviterId, chatParticipantData.date, chatParticipantData.rank)
|
||||
self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), invitedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(inviterId)), invitedAt: date, rank: rank)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -787,8 +787,10 @@ func messageTextEntitiesFromApiEntities(_ entities: [Api.MessageEntity]) -> [Mes
|
|||
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .CustomEmoji(stickerPack: nil, fileId: documentId)))
|
||||
case let .messageEntityFormattedDate(messageEntityFormattedDateData):
|
||||
let (flags, offset, length, date) = (messageEntityFormattedDateData.flags, messageEntityFormattedDateData.offset, messageEntityFormattedDateData.length, messageEntityFormattedDateData.date)
|
||||
let format: MessageTextEntityType.DateTimeFormat
|
||||
if (flags & (1 << 0)) != 0 {
|
||||
let format: MessageTextEntityType.DateTimeFormat?
|
||||
if flags == 0 {
|
||||
format = nil
|
||||
} else if (flags & (1 << 0)) != 0 {
|
||||
format = .relative
|
||||
} else {
|
||||
let timeFormat: MessageTextEntityType.DateTimeFormat.TimeFormat?
|
||||
|
|
@ -819,7 +821,7 @@ extension StoreMessage {
|
|||
convenience init?(apiMessage: Api.Message, accountPeerId: PeerId, peerIsForum: Bool, namespace: MessageId.Namespace = Namespaces.Message.Cloud) {
|
||||
switch apiMessage {
|
||||
case let .message(messageData):
|
||||
let (flags, flags2, id, fromId, boosts, chatPeerId, savedPeerId, fwdFrom, viaBotId, viaBusinessBotId, replyTo, date, message, media, replyMarkup, entities, views, forwards, replies, editDate, postAuthor, groupingId, reactions, restrictionReason, ttlPeriod, quickReplyShortcutId, messageEffectId, factCheck, reportDeliveryUntilDate, paidMessageStars, suggestedPost, scheduledRepeatPeriod, summaryFromLanguage) = (messageData.flags, messageData.flags2, messageData.id, messageData.fromId, messageData.fromBoostsApplied, messageData.peerId, messageData.savedPeerId, messageData.fwdFrom, messageData.viaBotId, messageData.viaBusinessBotId, messageData.replyTo, messageData.date, messageData.message, messageData.media, messageData.replyMarkup, messageData.entities, messageData.views, messageData.forwards, messageData.replies, messageData.editDate, messageData.postAuthor, messageData.groupedId, messageData.reactions, messageData.restrictionReason, messageData.ttlPeriod, messageData.quickReplyShortcutId, messageData.effect, messageData.factcheck, messageData.reportDeliveryUntilDate, messageData.paidMessageStars, messageData.suggestedPost, messageData.scheduleRepeatPeriod, messageData.summaryFromLanguage)
|
||||
let (flags, flags2, id, fromId, boosts, rank, chatPeerId, savedPeerId, fwdFrom, viaBotId, viaBusinessBotId, replyTo, date, message, media, replyMarkup, entities, views, forwards, replies, editDate, postAuthor, groupingId, reactions, restrictionReason, ttlPeriod, quickReplyShortcutId, messageEffectId, factCheck, reportDeliveryUntilDate, paidMessageStars, suggestedPost, scheduledRepeatPeriod, summaryFromLanguage) = (messageData.flags, messageData.flags2, messageData.id, messageData.fromId, messageData.fromBoostsApplied, messageData.fromRank, messageData.peerId, messageData.savedPeerId, messageData.fwdFrom, messageData.viaBotId, messageData.viaBusinessBotId, messageData.replyTo, messageData.date, messageData.message, messageData.media, messageData.replyMarkup, messageData.entities, messageData.views, messageData.forwards, messageData.replies, messageData.editDate, messageData.postAuthor, messageData.groupedId, messageData.reactions, messageData.restrictionReason, messageData.ttlPeriod, messageData.quickReplyShortcutId, messageData.effect, messageData.factcheck, messageData.reportDeliveryUntilDate, messageData.paidMessageStars, messageData.suggestedPost, messageData.scheduleRepeatPeriod, messageData.summaryFromLanguage)
|
||||
var attributes: [MessageAttribute] = []
|
||||
|
||||
if (flags2 & (1 << 4)) != 0 {
|
||||
|
|
@ -1069,6 +1071,10 @@ extension StoreMessage {
|
|||
}
|
||||
}
|
||||
|
||||
if let rank {
|
||||
attributes.append(ParticipantRankMessageAttribute(rank: rank))
|
||||
}
|
||||
|
||||
if let editDate = editDate {
|
||||
attributes.append(EditedMessageAttribute(date: editDate, isHidden: (flags & (1 << 21)) != 0))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ func apiEntitiesFromMessageTextEntities(_ entities: [MessageTextEntity], associa
|
|||
default:
|
||||
break
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
apiEntities.append(.messageEntityFormattedDate(.init(flags: flags, offset: offset, length: length, date: date)))
|
||||
case .Custom:
|
||||
|
|
|
|||
|
|
@ -1332,7 +1332,7 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
|||
if let current = current as? CachedGroupData, let participants = current.participants {
|
||||
var updatedParticipants = participants.participants
|
||||
if updatedParticipants.firstIndex(where: { $0.peerId == userPeerId }) == nil {
|
||||
updatedParticipants.append(.member(id: userPeerId, invitedBy: inviterPeerId, invitedAt: date))
|
||||
updatedParticipants.append(.member(id: userPeerId, invitedBy: inviterPeerId, invitedAt: date, rank: nil))
|
||||
}
|
||||
return current.withUpdatedParticipants(CachedGroupParticipants(participants: updatedParticipants, version: participants.version))
|
||||
} else {
|
||||
|
|
@ -1363,12 +1363,12 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
|||
var updatedParticipants = participants.participants
|
||||
if let index = updatedParticipants.firstIndex(where: { $0.peerId == userPeerId }) {
|
||||
if isAdmin == .boolTrue {
|
||||
if case let .member(id, invitedBy, invitedAt) = updatedParticipants[index] {
|
||||
updatedParticipants[index] = .admin(id: id, invitedBy: invitedBy, invitedAt: invitedAt)
|
||||
if case let .member(id, invitedBy, invitedAt, rank) = updatedParticipants[index] {
|
||||
updatedParticipants[index] = .admin(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
}
|
||||
} else {
|
||||
if case let .admin(id, invitedBy, invitedAt) = updatedParticipants[index] {
|
||||
updatedParticipants[index] = .member(id: id, invitedBy: invitedBy, invitedAt: invitedAt)
|
||||
if case let .admin(id, invitedBy, invitedAt, rank) = updatedParticipants[index] {
|
||||
updatedParticipants[index] = .member(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1377,6 +1377,21 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
|||
return current
|
||||
}
|
||||
})
|
||||
case let .updateChatParticipantRank(updateChatParticipantRankData):
|
||||
let (chatId, userId, rank) = (updateChatParticipantRankData.chatId, updateChatParticipantRankData.userId, updateChatParticipantRankData.rank)
|
||||
let groupPeerId = PeerId(namespace: Namespaces.Peer.CloudGroup, id: PeerId.Id._internalFromInt64Value(chatId))
|
||||
let userPeerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
|
||||
updatedState.updateCachedPeerData(groupPeerId, { current in
|
||||
if let current = current as? CachedGroupData, let participants = current.participants {
|
||||
var updatedParticipants = participants.participants
|
||||
if let index = updatedParticipants.firstIndex(where: { $0.peerId == userPeerId }) {
|
||||
updatedParticipants[index] = updatedParticipants[index].withUpdated(rank: rank)
|
||||
}
|
||||
return current.withUpdatedParticipants(CachedGroupParticipants(participants: updatedParticipants, version: participants.version))
|
||||
} else {
|
||||
return current
|
||||
}
|
||||
})
|
||||
case let .updateChatDefaultBannedRights(updateChatDefaultBannedRightsData):
|
||||
let (peer, defaultBannedRights, version) = (updateChatDefaultBannedRightsData.peer, updateChatDefaultBannedRightsData.defaultBannedRights, updateChatDefaultBannedRightsData.version)
|
||||
updatedState.updatePeer(peer.peerId, { peer in
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class UpdateMessageService: NSObject, MTMessageService {
|
|||
}
|
||||
case let .updateShortChatMessage(updateShortChatMessageData):
|
||||
let (flags, id, fromId, chatId, message, pts, ptsCount, date, fwdFrom, viaBotId, replyHeader, entities, ttlPeriod) = (updateShortChatMessageData.flags, updateShortChatMessageData.id, updateShortChatMessageData.fromId, updateShortChatMessageData.chatId, updateShortChatMessageData.message, updateShortChatMessageData.pts, updateShortChatMessageData.ptsCount, updateShortChatMessageData.date, updateShortChatMessageData.fwdFrom, updateShortChatMessageData.viaBotId, updateShortChatMessageData.replyTo, updateShortChatMessageData.entities, updateShortChatMessageData.ttlPeriod)
|
||||
let generatedMessage = Api.Message.message(.init(flags: flags, flags2: 0, id: id, fromId: .peerUser(.init(userId: fromId)), fromBoostsApplied: nil, peerId: Api.Peer.peerChat(.init(chatId: chatId)), savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, viaBusinessBotId: nil, 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, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil, effect: nil, factcheck: nil, reportDeliveryUntilDate: nil, paidMessageStars: nil, suggestedPost: nil, scheduleRepeatPeriod: nil, summaryFromLanguage: nil))
|
||||
let generatedMessage = Api.Message.message(.init(flags: flags, flags2: 0, id: id, fromId: .peerUser(.init(userId: fromId)), fromBoostsApplied: nil, fromRank: nil, peerId: Api.Peer.peerChat(.init(chatId: chatId)), savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, viaBusinessBotId: nil, 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, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil, effect: nil, factcheck: nil, reportDeliveryUntilDate: nil, paidMessageStars: nil, suggestedPost: nil, scheduleRepeatPeriod: nil, summaryFromLanguage: nil))
|
||||
let update = Api.Update.updateNewMessage(.init(message: generatedMessage, pts: pts, ptsCount: ptsCount))
|
||||
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
|
||||
if groups.count != 0 {
|
||||
|
|
@ -79,7 +79,7 @@ class UpdateMessageService: NSObject, MTMessageService {
|
|||
|
||||
let generatedPeerId = Api.Peer.peerUser(.init(userId: userId))
|
||||
|
||||
let generatedMessage = Api.Message.message(.init(flags: flags, flags2: 0, id: id, fromId: generatedFromId, fromBoostsApplied: nil, peerId: generatedPeerId, savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, viaBusinessBotId: nil, 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, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil, effect: nil, factcheck: nil, reportDeliveryUntilDate: nil, paidMessageStars: nil, suggestedPost: nil, scheduleRepeatPeriod: nil, summaryFromLanguage: nil))
|
||||
let generatedMessage = Api.Message.message(.init(flags: flags, flags2: 0, id: id, fromId: generatedFromId, fromBoostsApplied: nil, fromRank: nil, peerId: generatedPeerId, savedPeerId: nil, fwdFrom: fwdFrom, viaBotId: viaBotId, viaBusinessBotId: nil, 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, reactions: nil, restrictionReason: nil, ttlPeriod: ttlPeriod, quickReplyShortcutId: nil, effect: nil, factcheck: nil, reportDeliveryUntilDate: nil, paidMessageStars: nil, suggestedPost: nil, scheduleRepeatPeriod: nil, summaryFromLanguage: nil))
|
||||
let update = Api.Update.updateNewMessage(.init(message: generatedMessage, pts: pts, ptsCount: ptsCount))
|
||||
let groups = groupUpdates([update], users: [], chats: [], date: date, seqRange: nil)
|
||||
if groups.count != 0 {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
import Foundation
|
||||
import Postbox
|
||||
|
||||
public class ParticipantRankMessageAttribute: MessageAttribute {
|
||||
public let rank: String
|
||||
|
||||
public var associatedMessageIds: [MessageId] = []
|
||||
|
||||
public init(rank: String) {
|
||||
self.rank = rank
|
||||
}
|
||||
|
||||
required public init(decoder: PostboxDecoder) {
|
||||
self.rank = decoder.decodeStringForKey("r", orElse: "")
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeString(self.rank, forKey: "r")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
import Postbox
|
||||
|
||||
public enum GroupParticipant: PostboxCoding, Equatable {
|
||||
case member(id: PeerId, invitedBy: PeerId, invitedAt: Int32)
|
||||
case creator(id: PeerId)
|
||||
case admin(id: PeerId, invitedBy: PeerId, invitedAt: Int32)
|
||||
case member(id: PeerId, invitedBy: PeerId, invitedAt: Int32, rank: String?)
|
||||
case creator(id: PeerId, rank: String?)
|
||||
case admin(id: PeerId, invitedBy: PeerId, invitedAt: Int32, rank: String?)
|
||||
|
||||
public var peerId: PeerId {
|
||||
switch self {
|
||||
case let .member(id, _, _):
|
||||
case let .member(id, _, _, _):
|
||||
return id
|
||||
case let .creator(id):
|
||||
case let .creator(id, _):
|
||||
return id
|
||||
case let .admin(id, _, _):
|
||||
case let .admin(id, _, _, _):
|
||||
return id
|
||||
}
|
||||
}
|
||||
|
|
@ -19,44 +19,70 @@ public enum GroupParticipant: PostboxCoding, Equatable {
|
|||
public init(decoder: PostboxDecoder) {
|
||||
switch decoder.decodeInt32ForKey("v", orElse: 0) {
|
||||
case 0:
|
||||
self = .member(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedBy: PeerId(decoder.decodeInt64ForKey("b", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0))
|
||||
self = .member(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedBy: PeerId(decoder.decodeInt64ForKey("b", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0), rank: decoder.decodeOptionalStringForKey("r"))
|
||||
case 1:
|
||||
self = .creator(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)))
|
||||
self = .creator(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), rank: decoder.decodeOptionalStringForKey("r"))
|
||||
case 2:
|
||||
self = .admin(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedBy: PeerId(decoder.decodeInt64ForKey("b", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0))
|
||||
self = .admin(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedBy: PeerId(decoder.decodeInt64ForKey("b", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0), rank: decoder.decodeOptionalStringForKey("r"))
|
||||
default:
|
||||
self = .member(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedBy: PeerId(decoder.decodeInt64ForKey("b", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0))
|
||||
self = .member(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedBy: PeerId(decoder.decodeInt64ForKey("b", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0), rank: decoder.decodeOptionalStringForKey("r"))
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
switch self {
|
||||
case let .member(id, invitedBy, invitedAt):
|
||||
case let .member(id, invitedBy, invitedAt, rank):
|
||||
encoder.encodeInt32(0, forKey: "v")
|
||||
encoder.encodeInt64(id.toInt64(), forKey: "i")
|
||||
encoder.encodeInt64(invitedBy.toInt64(), forKey: "b")
|
||||
encoder.encodeInt32(invitedAt, forKey: "t")
|
||||
case let .creator(id):
|
||||
if let rank {
|
||||
encoder.encodeString(rank, forKey: "r")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "r")
|
||||
}
|
||||
case let .creator(id, rank):
|
||||
encoder.encodeInt32(1, forKey: "v")
|
||||
encoder.encodeInt64(id.toInt64(), forKey: "i")
|
||||
case let .admin(id, invitedBy, invitedAt):
|
||||
if let rank {
|
||||
encoder.encodeString(rank, forKey: "r")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "r")
|
||||
}
|
||||
case let .admin(id, invitedBy, invitedAt, rank):
|
||||
encoder.encodeInt32(2, forKey: "v")
|
||||
encoder.encodeInt64(id.toInt64(), forKey: "i")
|
||||
encoder.encodeInt64(invitedBy.toInt64(), forKey: "b")
|
||||
encoder.encodeInt32(invitedAt, forKey: "t")
|
||||
if let rank {
|
||||
encoder.encodeString(rank, forKey: "r")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "r")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var invitedBy: PeerId {
|
||||
switch self {
|
||||
case let .admin(_, invitedBy, _):
|
||||
case let .admin(_, invitedBy, _, _):
|
||||
return invitedBy
|
||||
case let .member(_, invitedBy, _):
|
||||
case let .member(_, invitedBy, _, _):
|
||||
return invitedBy
|
||||
case let .creator(id):
|
||||
case let .creator(id, _):
|
||||
return id
|
||||
}
|
||||
}
|
||||
|
||||
func withUpdated(rank: String?) -> GroupParticipant {
|
||||
switch self {
|
||||
case let .member(id, invitedBy, invitedAt, _):
|
||||
return .member(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
case let .admin(id, invitedBy, invitedAt, _):
|
||||
return .admin(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
case let .creator(id, _):
|
||||
return .creator(id: id, rank: rank)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final class CachedGroupParticipants: PostboxCoding, Equatable {
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ public struct TelegramChannelFlags: OptionSet {
|
|||
public static let autoTranslateEnabled = TelegramChannelFlags(rawValue: 1 << 12)
|
||||
public static let isMonoforum = TelegramChannelFlags(rawValue: 1 << 13)
|
||||
public static let displayForumAsTabs = TelegramChannelFlags(rawValue: 1 << 14)
|
||||
public static let customRanksEnabled = TelegramChannelFlags(rawValue: 1 << 15)
|
||||
}
|
||||
|
||||
public final class TelegramChannel: Peer, Equatable {
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ public struct TelegramGroupFlags: OptionSet {
|
|||
public static let hasVoiceChat = TelegramGroupFlags(rawValue: 1 << 2)
|
||||
public static let hasActiveVoiceChat = TelegramGroupFlags(rawValue: 1 << 3)
|
||||
public static let copyProtectionEnabled = TelegramGroupFlags(rawValue: 1 << 4)
|
||||
public static let customRanksEnabled = TelegramGroupFlags(rawValue: 1 << 5)
|
||||
}
|
||||
|
||||
public struct TelegramGroupToChannelMigrationReference: Equatable {
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public enum MessageTextEntityType: Equatable {
|
|||
case BankCard
|
||||
case Spoiler
|
||||
case CustomEmoji(stickerPack: StickerPackReference?, fileId: Int64)
|
||||
case FormattedDate(format: DateTimeFormat, date: Int32)
|
||||
case FormattedDate(format: DateTimeFormat?, date: Int32)
|
||||
case Custom(type: CustomEntityType)
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +143,7 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
let stickerPack = decoder.decodeObjectForKey("s", decoder: { StickerPackReference(decoder: $0) }) as? StickerPackReference
|
||||
self.type = .CustomEmoji(stickerPack: stickerPack, fileId: decoder.decodeInt64ForKey("f", orElse: 0))
|
||||
case 19:
|
||||
self.type = .FormattedDate(format: MessageTextEntityType.DateTimeFormat(rawValue: decoder.decodeInt32ForKey("format", orElse: 0)), date: decoder.decodeInt32ForKey("date", orElse: 0))
|
||||
self.type = .FormattedDate(format: decoder.decodeOptionalInt32ForKey("format").flatMap { MessageTextEntityType.DateTimeFormat(rawValue: $0) }, date: decoder.decodeInt32ForKey("date", orElse: 0))
|
||||
case Int32.max:
|
||||
self.type = .Custom(type: decoder.decodeInt32ForKey("type", orElse: 0))
|
||||
default:
|
||||
|
|
@ -202,7 +202,7 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
case 18:
|
||||
self.type = .CustomEmoji(stickerPack: try container.decodeIfPresent(StickerPackReference.self, forKey: "s"), fileId: try container.decode(Int64.self, forKey: "f"))
|
||||
case 19:
|
||||
self.type = .FormattedDate(format: MessageTextEntityType.DateTimeFormat(rawValue: try container.decode(Int32.self, forKey: "format")), date: try container.decode(Int32.self, forKey: "date"))
|
||||
self.type = .FormattedDate(format: try container.decodeIfPresent(Int32.self, forKey: "format").flatMap { MessageTextEntityType.DateTimeFormat(rawValue: $0) }, date: try container.decode(Int32.self, forKey: "date"))
|
||||
case Int32.max:
|
||||
let customType: Int32 = (try? container.decode(Int32.self, forKey: "type")) ?? 0
|
||||
self.type = .Custom(type: customType)
|
||||
|
|
@ -269,7 +269,11 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
encoder.encodeInt64(fileId, forKey: "f")
|
||||
case let .FormattedDate(format, date):
|
||||
encoder.encodeInt32(19, forKey: "_rawValue")
|
||||
encoder.encodeInt32(format.rawValue, forKey: "format")
|
||||
if let format {
|
||||
encoder.encodeInt32(format.rawValue, forKey: "format")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "format")
|
||||
}
|
||||
encoder.encodeInt32(date, forKey: "date")
|
||||
case let .Custom(type):
|
||||
encoder.encodeInt32(Int32.max, forKey: "_rawValue")
|
||||
|
|
@ -329,7 +333,7 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
try container.encode(fileId, forKey: "f")
|
||||
case let .FormattedDate(format, date):
|
||||
try container.encode(19 as Int32, forKey: "_rawValue")
|
||||
try container.encode(format.rawValue, forKey: "format")
|
||||
try container.encodeIfPresent(format?.rawValue, forKey: "format")
|
||||
try container.encode(date, forKey: "date")
|
||||
case let .Custom(type):
|
||||
try container.encode(Int32.max as Int32, forKey: "_rawValue")
|
||||
|
|
|
|||
|
|
@ -81,42 +81,53 @@ public extension EngineChannelParticipant {
|
|||
}
|
||||
|
||||
public enum EngineLegacyGroupParticipant: Equatable {
|
||||
case member(id: EnginePeer.Id, invitedBy: EnginePeer.Id, invitedAt: Int32)
|
||||
case creator(id: EnginePeer.Id)
|
||||
case admin(id: EnginePeer.Id, invitedBy: EnginePeer.Id, invitedAt: Int32)
|
||||
case member(id: EnginePeer.Id, invitedBy: EnginePeer.Id, invitedAt: Int32, rank: String?)
|
||||
case creator(id: EnginePeer.Id, rank: String?)
|
||||
case admin(id: EnginePeer.Id, invitedBy: EnginePeer.Id, invitedAt: Int32, rank: String?)
|
||||
|
||||
public var peerId: EnginePeer.Id {
|
||||
switch self {
|
||||
case let .member(id, _, _):
|
||||
case let .member(id, _, _, _):
|
||||
return id
|
||||
case let .creator(id):
|
||||
case let .creator(id, _):
|
||||
return id
|
||||
case let .admin(id, _, _):
|
||||
case let .admin(id, _, _, _):
|
||||
return id
|
||||
}
|
||||
}
|
||||
|
||||
public var rank: String? {
|
||||
switch self {
|
||||
case let .member(_, _, _, rank):
|
||||
return rank
|
||||
case let .creator(_, rank):
|
||||
return rank
|
||||
case let .admin(_, _, _, rank):
|
||||
return rank
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension EngineLegacyGroupParticipant {
|
||||
init(_ participant: GroupParticipant) {
|
||||
switch participant {
|
||||
case let .member(id, invitedBy, invitedAt):
|
||||
self = .member(id: id, invitedBy: invitedBy, invitedAt: invitedAt)
|
||||
case let .creator(id):
|
||||
self = .creator(id: id)
|
||||
case let .admin(id, invitedBy, invitedAt):
|
||||
self = .admin(id: id, invitedBy: invitedBy, invitedAt: invitedAt)
|
||||
case let .member(id, invitedBy, invitedAt, rank):
|
||||
self = .member(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
case let .creator(id, rank):
|
||||
self = .creator(id: id, rank: rank)
|
||||
case let .admin(id, invitedBy, invitedAt, rank):
|
||||
self = .admin(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
}
|
||||
}
|
||||
|
||||
func _asParticipant() -> GroupParticipant {
|
||||
switch self {
|
||||
case let .member(id, invitedBy, invitedAt):
|
||||
return .member(id: id, invitedBy: invitedBy, invitedAt: invitedAt)
|
||||
case let .creator(id):
|
||||
return .creator(id: id)
|
||||
case let .admin(id, invitedBy, invitedAt):
|
||||
return .admin(id: id, invitedBy: invitedBy, invitedAt: invitedAt)
|
||||
case let .member(id, invitedBy, invitedAt, rank):
|
||||
return .member(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
case let .creator(id, rank):
|
||||
return .creator(id: id, rank: rank)
|
||||
case let .admin(id, invitedBy, invitedAt, rank):
|
||||
return .admin(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2278,17 +2289,19 @@ public extension TelegramEngine.EngineData.Item {
|
|||
}
|
||||
|
||||
var key: PostboxViewKey {
|
||||
return .basicPeer(self.id)
|
||||
return .peer(peerId: self.id, components: [.cachedData])
|
||||
}
|
||||
|
||||
func extract(view: PostboxView) -> Result {
|
||||
guard let view = view as? BasicPeerView else {
|
||||
guard let view = view as? PeerView else {
|
||||
preconditionFailure()
|
||||
}
|
||||
guard let peer = view.peer else {
|
||||
guard let peer = peerViewMainPeer(view) else {
|
||||
return false
|
||||
}
|
||||
if let group = peer as? TelegramGroup {
|
||||
if let cachedPeerData = view.cachedData as? CachedUserData {
|
||||
return cachedPeerData.flags.contains(.copyProtectionEnabled)
|
||||
} else if let group = peer as? TelegramGroup {
|
||||
return group.flags.contains(.copyProtectionEnabled)
|
||||
} else if let channel = peer as? TelegramChannel {
|
||||
return channel.flags.contains(.copyProtectionEnabled)
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ func _internal_addGroupMember(account: Account, peerId: PeerId, memberId: PeerId
|
|||
}
|
||||
}
|
||||
if !found {
|
||||
updatedParticipants.append(.member(id: memberId, invitedBy: account.peerId, invitedAt: timestamp))
|
||||
updatedParticipants.append(.member(id: memberId, invitedBy: account.peerId, invitedAt: timestamp, rank: nil))
|
||||
}
|
||||
return cachedData.withUpdatedParticipants(CachedGroupParticipants(participants: updatedParticipants, version: participants.version))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ func _internal_removeGroupAdmin(account: Account, peerId: PeerId, adminId: PeerI
|
|||
for i in 0 ..< updatedParticipants.count {
|
||||
if updatedParticipants[i].peerId == adminId {
|
||||
switch updatedParticipants[i] {
|
||||
case let .admin(id, invitedBy, invitedAt):
|
||||
updatedParticipants[i] = .member(id: id, invitedBy: invitedBy, invitedAt: invitedAt)
|
||||
case let .admin(id, invitedBy, invitedAt, rank):
|
||||
updatedParticipants[i] = .member(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
@ -93,8 +93,8 @@ func _internal_addGroupAdmin(account: Account, peerId: PeerId, adminId: PeerId)
|
|||
for i in 0 ..< updatedParticipants.count {
|
||||
if updatedParticipants[i].peerId == adminId {
|
||||
switch updatedParticipants[i] {
|
||||
case let .member(id, invitedBy, invitedAt):
|
||||
updatedParticipants[i] = .admin(id: id, invitedBy: invitedBy, invitedAt: invitedAt)
|
||||
case let .member(id, invitedBy, invitedAt, rank):
|
||||
updatedParticipants[i] = .admin(id: id, invitedBy: invitedBy, invitedAt: invitedAt, rank: rank)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
import Foundation
|
||||
import Postbox
|
||||
import SwiftSignalKit
|
||||
import TelegramApi
|
||||
import MtProtoKit
|
||||
|
||||
func _internal_toggleChatCustomRanks(account: Account, peerId: PeerId, enabled: Bool) -> Signal<Void, NoError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
|
||||
if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
|
||||
return account.network.request(Api.functions.messages.toggleChatCustomRanks(peer: inputPeer, enabled: enabled ? .boolTrue : .boolFalse))
|
||||
|> `catch` { _ in
|
||||
return .complete()
|
||||
}
|
||||
|> map { updates -> Void in
|
||||
account.stateManager.addUpdates(updates)
|
||||
}
|
||||
} else {
|
||||
return .complete()
|
||||
}
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
||||
public enum UpdateChatRankError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_updateChatRank(account: Account, peerId: PeerId, userId: PeerId, rank: String?) -> Signal<Never, UpdateChatRankError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Void, UpdateChatRankError> in
|
||||
if let user = transaction.getPeer(userId), let inputUser = apiInputPeer(user), let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer) {
|
||||
return account.network.request(Api.functions.messages.editChatParticipantRank(peer: inputPeer, participant: inputUser, rank: rank ?? ""))
|
||||
|> mapError { _ -> UpdateChatRankError in
|
||||
return .generic
|
||||
}
|
||||
|> map { updates -> Void in
|
||||
account.stateManager.addUpdates(updates)
|
||||
}
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
}
|
||||
|> mapError { _ -> UpdateChatRankError in }
|
||||
|> switchToLatest
|
||||
|> ignoreValues
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -616,6 +616,14 @@ public extension TelegramEngine {
|
|||
public func getFutureCreatorAfterLeave(peerId: EnginePeer.Id) -> Signal<EnginePeer?, NoError> {
|
||||
return _internal_getFutureCreatorAfterLeave(account: self.account, peerId: peerId)
|
||||
}
|
||||
|
||||
public func toggleChatCustomRanks(peerId: PeerId, enabled: Bool) -> Signal<Void, NoError> {
|
||||
return _internal_toggleChatCustomRanks(account: self.account, peerId: peerId, enabled: enabled)
|
||||
}
|
||||
|
||||
public func updateChatRank(account: Account, peerId: PeerId, userId: PeerId, rank: String?) -> Signal<Never, UpdateChatRankError> {
|
||||
return _internal_updateChatRank(account: account, peerId: peerId, userId: userId, rank: rank)
|
||||
}
|
||||
|
||||
public func terminateSecretChat(peerId: PeerId, requestRemoteHistoryRemoval: Bool) -> Signal<Never, NoError> {
|
||||
return self.account.postbox.transaction { transaction -> Void in
|
||||
|
|
|
|||
|
|
@ -2,111 +2,7 @@ import Foundation
|
|||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
|
||||
public func stringForEntityFormattedDate(timestamp: Int32, format: MessageTextEntityType.DateTimeFormat, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat) -> String {
|
||||
switch format {
|
||||
case .relative:
|
||||
let currentTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||
let value = currentTimestamp - timestamp
|
||||
if value > 0 {
|
||||
if value <= 1 * 60 * 60 {
|
||||
return strings.FormattedDate_MinutesAgo(Int32(round(Float(value) / 60)))
|
||||
} else if value <= 24 * 60 * 60 {
|
||||
return strings.FormattedDate_HoursAgo(Int32(round(Float(value) / (60 * 60))))
|
||||
} else {
|
||||
return strings.FormattedDate_DaysAgo(Int32(round(Float(value) / (24 * 60 * 60))))
|
||||
}
|
||||
} else {
|
||||
let value = abs(value)
|
||||
if value <= 1 * 60 * 60 {
|
||||
return strings.FormattedDate_InMinutes(Int32(round(Float(value) / 60)))
|
||||
} else if value <= 24 * 60 * 60 {
|
||||
return strings.FormattedDate_InHours(Int32(round(Float(value) / (60 * 60))))
|
||||
} else {
|
||||
return strings.FormattedDate_InDays(Int32(round(Float(value) / (24 * 60 * 60))))
|
||||
}
|
||||
}
|
||||
case let .full(timeFormat, dateFormat):
|
||||
var string = ""
|
||||
if let dateFormat {
|
||||
switch dateFormat {
|
||||
case .short:
|
||||
string += stringForMediumDate(timestamp: timestamp, strings: strings, dateTimeFormat: dateTimeFormat, withTime: false)
|
||||
case .long:
|
||||
string += stringForFullDate(timestamp: timestamp, strings: strings, dateTimeFormat: dateTimeFormat)
|
||||
}
|
||||
}
|
||||
if let timeFormat {
|
||||
let timeString: String
|
||||
switch timeFormat {
|
||||
case .short:
|
||||
timeString = stringForMessageTimestamp(timestamp: timestamp, dateTimeFormat: dateTimeFormat)
|
||||
case .long:
|
||||
timeString = stringForMessageTimestamp(timestamp: timestamp, dateTimeFormat: dateTimeFormat, withSeconds: true)
|
||||
}
|
||||
if !string.isEmpty {
|
||||
string = strings.Time_AtPreciseDate(string, timeString).string
|
||||
} else {
|
||||
string = timeString
|
||||
}
|
||||
}
|
||||
return string
|
||||
}
|
||||
}
|
||||
|
||||
public func stringForShortTimestamp(hours: Int32, minutes: Int32, seconds: Int32? = nil, dateTimeFormat: PresentationDateTimeFormat, formatAsPlainText: Bool = false) -> String {
|
||||
switch dateTimeFormat.timeFormat {
|
||||
case .regular:
|
||||
let hourString: String
|
||||
if hours == 0 {
|
||||
hourString = "12"
|
||||
} else if hours > 12 {
|
||||
hourString = "\(hours - 12)"
|
||||
} else {
|
||||
hourString = "\(hours)"
|
||||
}
|
||||
|
||||
let periodString: String
|
||||
if hours >= 12 {
|
||||
periodString = "PM"
|
||||
} else {
|
||||
periodString = "AM"
|
||||
}
|
||||
|
||||
let spaceCharacter: String
|
||||
if formatAsPlainText {
|
||||
spaceCharacter = " "
|
||||
} else {
|
||||
spaceCharacter = "\u{00a0}"
|
||||
}
|
||||
|
||||
let minuteString = String(format: "%02d", arguments: [Int(minutes)])
|
||||
if let seconds {
|
||||
let secondString = String(format: "%02d", arguments: [Int(seconds)])
|
||||
return "\(hourString):\(minuteString):\(secondString)\(spaceCharacter)\(periodString)"
|
||||
} else {
|
||||
return "\(hourString):\(minuteString)\(spaceCharacter)\(periodString)"
|
||||
}
|
||||
case .military:
|
||||
if let seconds {
|
||||
return String(format: "%02d:%02d:%02d", arguments: [Int(hours), Int(minutes), Int(seconds)])
|
||||
} else {
|
||||
return String(format: "%02d:%02d", arguments: [Int(hours), Int(minutes)])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func stringForMessageTimestamp(timestamp: Int32, dateTimeFormat: PresentationDateTimeFormat, withSeconds: Bool = false, local: Bool = true) -> String {
|
||||
var t = Int(timestamp)
|
||||
var timeinfo = tm()
|
||||
if local {
|
||||
localtime_r(&t, &timeinfo)
|
||||
} else {
|
||||
gmtime_r(&t, &timeinfo)
|
||||
}
|
||||
|
||||
return stringForShortTimestamp(hours: timeinfo.tm_hour, minutes: timeinfo.tm_min, seconds: withSeconds ? timeinfo.tm_sec : nil, dateTimeFormat: dateTimeFormat)
|
||||
}
|
||||
import TextFormat
|
||||
|
||||
public func getDateTimeComponents(timestamp: Int32) -> (day: Int32, month: Int32, year: Int32, hour: Int32, minutes: Int32) {
|
||||
var t: time_t = Int(timestamp)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import Foundation
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TextFormat
|
||||
|
||||
public func stringForTimestamp(day: Int32, month: Int32, year: Int32, dateTimeFormat: PresentationDateTimeFormat) -> String {
|
||||
let separator = dateTimeFormat.dateSeparator
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ swift_library(
|
|||
"//submodules/AccountContext",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/LocalizedPeerData",
|
||||
"//submodules/Components/ReactionButtonListComponent",
|
||||
"//submodules/Components/ReactionImageComponent",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import TelegramCore
|
|||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
import LocalizedPeerData
|
||||
import AccountContext
|
||||
|
||||
|
|
|
|||
|
|
@ -147,6 +147,8 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
private var textRevealLink: SharedDisplayLinkDriver.Link?
|
||||
private var textRevealAnimationState: TextRevealAnimationState?
|
||||
|
||||
private var relativeDateTimer: (timer: SwiftSignalKit.Timer, period: Int32)?
|
||||
|
||||
override public var visibility: ListViewItemNodeVisibility {
|
||||
didSet {
|
||||
if oldValue != self.visibility {
|
||||
|
|
@ -232,6 +234,7 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
self.linkPreviewOptionsDisposable?.dispose()
|
||||
self.linkProgressDisposable?.dispose()
|
||||
self.codeHighlightState?.disposable.dispose()
|
||||
self.relativeDateTimer?.timer.invalidate()
|
||||
}
|
||||
|
||||
override public func asyncLayoutContent() -> (_ item: ChatMessageBubbleContentItem, _ layoutConstants: ChatMessageItemLayoutConstants, _ preparePosition: ChatMessageBubblePreparePosition, _ messageSelection: Bool?, _ constrainedSize: CGSize, _ avatarInset: CGFloat) -> (ChatMessageBubbleContentProperties, CGSize?, CGFloat, (CGSize, ChatMessageBubbleContentPosition) -> (CGFloat, (CGFloat) -> (CGSize, (ListViewItemUpdateAnimation, Bool, ListViewItemApply?) -> Void))) {
|
||||
|
|
@ -484,6 +487,23 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
}
|
||||
}
|
||||
|
||||
var formattedDateUpdatePeriod: Int32?
|
||||
if let messageEntities {
|
||||
for entity in messageEntities {
|
||||
if case let .FormattedDate(format, timestamp) = entity.type, case .relative = format {
|
||||
let currentTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||
let value = abs(currentTimestamp - timestamp)
|
||||
if value < 120 {
|
||||
formattedDateUpdatePeriod = 1
|
||||
} else if value <= 60 * 60 {
|
||||
formattedDateUpdatePeriod = 60
|
||||
} else {
|
||||
formattedDateUpdatePeriod = 30 * 60
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var entities: [MessageTextEntity]?
|
||||
var updatedCachedChatMessageText: CachedChatMessageText?
|
||||
if let cached = currentCachedChatMessageText, cached.matches(text: rawText, inputEntities: messageEntities) {
|
||||
|
|
@ -616,7 +636,7 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
}
|
||||
}
|
||||
|
||||
attributedText = stringWithAppliedEntities(rawText, entities: entities, baseColor: messageTheme.primaryTextColor, linkColor: messageTheme.linkTextColor, baseQuoteTintColor: mainColor, baseQuoteSecondaryTintColor: secondaryColor, baseQuoteTertiaryTintColor: tertiaryColor, codeBlockTitleColor: codeBlockTitleColor, codeBlockAccentColor: codeBlockAccentColor, codeBlockBackgroundColor: codeBlockBackgroundColor, baseFont: textFont, linkFont: textFont, boldFont: item.presentationData.messageBoldFont, italicFont: item.presentationData.messageItalicFont, boldItalicFont: item.presentationData.messageBoldItalicFont, fixedFont: item.presentationData.messageFixedFont, blockQuoteFont: item.presentationData.messageBlockQuoteFont, underlineLinks: underlineLinks, message: item.message, adjustQuoteFontSize: true, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight)
|
||||
attributedText = stringWithAppliedEntities(rawText, entities: entities, strings: item.presentationData.strings, dateTimeFormat: item.presentationData.dateTimeFormat, baseColor: messageTheme.primaryTextColor, linkColor: messageTheme.linkTextColor, baseQuoteTintColor: mainColor, baseQuoteSecondaryTintColor: secondaryColor, baseQuoteTertiaryTintColor: tertiaryColor, codeBlockTitleColor: codeBlockTitleColor, codeBlockAccentColor: codeBlockAccentColor, codeBlockBackgroundColor: codeBlockBackgroundColor, baseFont: textFont, linkFont: textFont, boldFont: item.presentationData.messageBoldFont, italicFont: item.presentationData.messageItalicFont, boldItalicFont: item.presentationData.messageBoldItalicFont, fixedFont: item.presentationData.messageFixedFont, blockQuoteFont: item.presentationData.messageBlockQuoteFont, underlineLinks: underlineLinks, message: item.message, adjustQuoteFontSize: true, cachedMessageSyntaxHighlight: cachedMessageSyntaxHighlight)
|
||||
} else if !rawText.isEmpty {
|
||||
attributedText = NSAttributedString(string: rawText, font: textFont, textColor: messageTheme.primaryTextColor)
|
||||
} else {
|
||||
|
|
@ -807,6 +827,20 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
animation.animator.updateFrame(layer: strongSelf.containerNode.layer, frame: CGRect(origin: CGPoint(), size: boundingSize), completion: nil)
|
||||
|
||||
|
||||
if let formattedDateUpdatePeriod {
|
||||
if strongSelf.relativeDateTimer?.period != formattedDateUpdatePeriod {
|
||||
strongSelf.relativeDateTimer?.timer.invalidate()
|
||||
strongSelf.relativeDateTimer = nil
|
||||
}
|
||||
strongSelf.relativeDateTimer = (SwiftSignalKit.Timer(timeout: Double(formattedDateUpdatePeriod), repeat: true, completion: { [weak self] in
|
||||
self?.requestFullUpdate?()
|
||||
}, queue: Queue.mainQueue()), formattedDateUpdatePeriod)
|
||||
strongSelf.relativeDateTimer?.timer.start()
|
||||
} else if let (timer, _) = strongSelf.relativeDateTimer {
|
||||
strongSelf.relativeDateTimer = nil
|
||||
timer.invalidate()
|
||||
}
|
||||
|
||||
if strongSelf.isSummaryApplied != isSummaryApplied {
|
||||
strongSelf.isSummaryApplied = isSummaryApplied
|
||||
itemApply?.setInvertOffsetDirection()
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ swift_library(
|
|||
"//submodules/AccountContext",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/SolidRoundedButtonNode",
|
||||
"//submodules/PresentationDataUtils",
|
||||
"//submodules/UIKitRuntimeUtils",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import Postbox
|
|||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
import AccountContext
|
||||
import SolidRoundedButtonNode
|
||||
import PresentationDataUtils
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import TelegramCore
|
|||
import ViewControllerComponent
|
||||
import TelegramPresentationData
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
import AccountContext
|
||||
import SheetComponent
|
||||
import ButtonComponent
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ private final class CraftGiftPageContent: Component {
|
|||
let starsTopUpOptionsPromise: Promise<[StarsTopUpOption]?>
|
||||
let selectGift: (Int32, GiftItem) -> Void
|
||||
let removeGift: (Int32) -> Void
|
||||
let craftAnotherGift: () -> Void
|
||||
let dismiss: () -> Void
|
||||
|
||||
init(
|
||||
|
|
@ -86,6 +87,7 @@ private final class CraftGiftPageContent: Component {
|
|||
starsTopUpOptionsPromise: Promise<[StarsTopUpOption]?>,
|
||||
selectGift: @escaping (Int32, GiftItem) -> Void,
|
||||
removeGift: @escaping (Int32) -> Void,
|
||||
craftAnotherGift: @escaping () -> Void,
|
||||
dismiss: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
|
|
@ -102,6 +104,7 @@ private final class CraftGiftPageContent: Component {
|
|||
self.starsTopUpOptionsPromise = starsTopUpOptionsPromise
|
||||
self.selectGift = selectGift
|
||||
self.removeGift = removeGift
|
||||
self.craftAnotherGift = craftAnotherGift
|
||||
self.dismiss = dismiss
|
||||
}
|
||||
|
||||
|
|
@ -1203,7 +1206,14 @@ private final class CraftGiftPageContent: Component {
|
|||
}
|
||||
if let _ = view {
|
||||
if case let .gift(gift) = component.result {
|
||||
let giftController = GiftViewScreen(context: component.context, subject: .profileGift(component.context.account.peerId, gift))
|
||||
//TODO:localize
|
||||
let giftController = GiftViewScreen(
|
||||
context: component.context,
|
||||
subject: .profileGift(component.context.account.peerId, gift),
|
||||
customAction: .init(title: environment.strings.Gift_Craft_CraftingFailed_CraftAnotherGift, action: {
|
||||
component.craftAnotherGift()
|
||||
})
|
||||
)
|
||||
if let navigationController = controller.navigationController {
|
||||
navigationController.pushViewController(giftController, animated: true)
|
||||
|
||||
|
|
@ -1548,6 +1558,36 @@ private final class SheetContainerComponent: CombinedComponent {
|
|||
}
|
||||
}
|
||||
|
||||
let navigationController = environment.controller()?.navigationController as? NavigationController
|
||||
let profileGiftsContext = (environment.controller() as? GiftCraftScreen)?.profileGiftsContext
|
||||
let resaleContext = state.resaleContext
|
||||
let starsTopUpOptionsPromise = state.starsTopUpOptionsPromise
|
||||
let craftAnotherGift = { [weak navigationController] in
|
||||
guard let navigationController else {
|
||||
return
|
||||
}
|
||||
if let genericGift = externalState.starGiftsMap[component.gift.giftId] {
|
||||
HapticFeedback().impact(.light)
|
||||
|
||||
let selectController = SelectCraftGiftScreen(
|
||||
context: component.context,
|
||||
craftContext: component.craftContext,
|
||||
resaleContext: resaleContext,
|
||||
gift: component.gift,
|
||||
genericGift: genericGift,
|
||||
selectedGiftIds: Set(),
|
||||
starsTopUpOptions: starsTopUpOptionsPromise.get(),
|
||||
selectGift: { [weak navigationController] item in
|
||||
if let navigationController{
|
||||
let craftController = GiftCraftScreen(context: component.context, gift: item.gift, profileGiftsContext: profileGiftsContext)
|
||||
navigationController.pushViewController(craftController)
|
||||
}
|
||||
}
|
||||
)
|
||||
navigationController.pushViewController(selectController)
|
||||
}
|
||||
}
|
||||
|
||||
let theme = environment.theme
|
||||
|
||||
var colors: (UIColor, UIColor, UIColor, UIColor, UIColor) = (
|
||||
|
|
@ -1720,6 +1760,7 @@ private final class SheetContainerComponent: CombinedComponent {
|
|||
state.selectedGiftIds[index] = nil
|
||||
state.updated(transition: .spring(duration: 0.4))
|
||||
},
|
||||
craftAnotherGift: craftAnotherGift,
|
||||
dismiss: {
|
||||
dismiss(true)
|
||||
}
|
||||
|
|
@ -1791,26 +1832,8 @@ private final class SheetContainerComponent: CombinedComponent {
|
|||
if state.displayInfo {
|
||||
state.displayInfo = false
|
||||
state.updated(transition: .spring(duration: 0.3))
|
||||
} else if state.displayFailure, let genericGift = externalState.starGiftsMap[component.gift.giftId] {
|
||||
HapticFeedback().impact(.light)
|
||||
|
||||
let selectController = SelectCraftGiftScreen(
|
||||
context: component.context,
|
||||
craftContext: component.craftContext,
|
||||
resaleContext: state.resaleContext,
|
||||
gift: component.gift,
|
||||
genericGift: genericGift,
|
||||
selectedGiftIds: Set(),
|
||||
starsTopUpOptions: state.starsTopUpOptionsPromise.get(),
|
||||
selectGift: { item in
|
||||
if let controller = controller() as? GiftCraftScreen, let navigationController = controller.navigationController as? NavigationController {
|
||||
let craftController = GiftCraftScreen(context: component.context, gift: item.gift, profileGiftsContext: controller.profileGiftsContext)
|
||||
controller.dismissAnimated()
|
||||
navigationController.pushViewController(craftController)
|
||||
}
|
||||
}
|
||||
)
|
||||
environment.controller()?.push(selectController)
|
||||
} else if state.displayFailure {
|
||||
craftAnotherGift()
|
||||
} else {
|
||||
HapticFeedback().impact(.medium)
|
||||
|
||||
|
|
|
|||
|
|
@ -153,6 +153,8 @@ final class SelectGiftPageContent: Component {
|
|||
}
|
||||
transition.setFrame(view: self.loadingView, frame: CGRect(origin: CGPoint(x: 0.0, y: contentHeight - 170.0), size: loadingSize))
|
||||
|
||||
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
|
||||
var itemFrame = CGRect(origin: CGPoint(x: itemSideInset, y: contentHeight), size: itemSize)
|
||||
var itemsHeight: CGFloat = 0.0
|
||||
var validIds: [AnyHashable] = []
|
||||
|
|
@ -245,6 +247,12 @@ final class SelectGiftPageContent: Component {
|
|||
}
|
||||
}
|
||||
itemTransition.setFrame(view: itemView, frame: itemFrame)
|
||||
|
||||
var canCraft = true
|
||||
if let profileGift = self.giftMap[gift.gift.id], let canCraftDate = profileGift.canCraftAt, currentTime < canCraftDate {
|
||||
canCraft = false
|
||||
}
|
||||
transition.setAlpha(view: itemView, alpha: canCraft ? 1.0 : 0.5)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -414,6 +422,7 @@ final class SelectGiftPageContent: Component {
|
|||
contentHeight += 32.0
|
||||
|
||||
contentHeight = self.updateScrolling(interactive: false, transition: transition)
|
||||
let originalContentHeight = contentHeight
|
||||
|
||||
let resaleCount = component.genericGift.availability?.resale ?? 0
|
||||
let saleTitle = environment.strings.Gift_Craft_Select_SaleGiftsCount(Int32(clamping: resaleCount)).uppercased()
|
||||
|
|
@ -483,7 +492,11 @@ final class SelectGiftPageContent: Component {
|
|||
}
|
||||
transition.setFrame(view: storeGiftsView, frame: storeGiftsFrame)
|
||||
|
||||
storeGiftsView.updateScrolling(bounds: CGRect(origin: .zero, size: availableSize), transition: .immediate)
|
||||
var effectiveBounds = CGRect(origin: .zero, size: CGSize(width: availableSize.width, height: 1000.0))
|
||||
if let bounds = self.currentBounds {
|
||||
effectiveBounds = bounds.offsetBy(dx: 0.0, dy: -originalContentHeight)
|
||||
}
|
||||
storeGiftsView.updateScrolling(bounds: effectiveBounds, transition: .immediate)
|
||||
}
|
||||
contentHeight += storeGiftsSize.height
|
||||
contentHeight += 90.0
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ public final class GiftStoreContentComponent: Component {
|
|||
if let initialCount = self.initialCount, initialCount < minimumCountToDisplayFilters {
|
||||
topInset = component.navigationHeight
|
||||
}
|
||||
|
||||
|
||||
let visibleBounds = bounds.insetBy(dx: 0.0, dy: -10.0)
|
||||
if let starGifts = self.effectiveGifts {
|
||||
let sideInset: CGFloat = 16.0 + component.safeInsets.left
|
||||
|
|
@ -1269,8 +1269,10 @@ final class GiftStoreScreenComponent: Component {
|
|||
guard let self, let component = self.component, let environment = self.environment else {
|
||||
return
|
||||
}
|
||||
let controller = component.context.sharedContext.makeStarsTransactionsScreen(context: component.context, starsContext: starsContext)
|
||||
environment.controller()?.push(controller)
|
||||
Queue.mainQueue().after(0.3) {
|
||||
let controller = component.context.sharedContext.makeStarsTransactionsScreen(context: component.context, starsContext: starsContext)
|
||||
environment.controller()?.push(controller)
|
||||
}
|
||||
}
|
||||
)))
|
||||
|
||||
|
|
@ -1283,8 +1285,10 @@ final class GiftStoreScreenComponent: Component {
|
|||
guard let self, let component = self.component, let environment = self.environment else {
|
||||
return
|
||||
}
|
||||
let controller = component.context.sharedContext.makeStarsTransactionsScreen(context: component.context, starsContext: tonContext)
|
||||
environment.controller()?.push(controller)
|
||||
Queue.mainQueue().after(0.3) {
|
||||
let controller = component.context.sharedContext.makeStarsTransactionsScreen(context: component.context, starsContext: tonContext)
|
||||
environment.controller()?.push(controller)
|
||||
}
|
||||
}
|
||||
)))
|
||||
|
||||
|
|
|
|||
|
|
@ -4677,7 +4677,26 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||
)
|
||||
|
||||
let buttonChild: _UpdatedChildComponent
|
||||
if state.canSkip {
|
||||
if let controller = controller() as? GiftViewScreen, let customAction = controller.customAction {
|
||||
buttonChild = button.update(
|
||||
component: ButtonComponent(
|
||||
background: buttonBackground,
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable("custom"),
|
||||
component: AnyComponent(MultilineTextComponent(text: .plain(NSAttributedString(string: customAction.title, font: Font.semibold(17.0), textColor: theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center))))
|
||||
),
|
||||
isEnabled: true,
|
||||
displaysProgress: state.inProgress,
|
||||
action: { [weak state] in
|
||||
if let state {
|
||||
customAction.action()
|
||||
state.dismiss(animated: true)
|
||||
}
|
||||
}),
|
||||
availableSize: buttonSize,
|
||||
transition: context.transition
|
||||
)
|
||||
} else if state.canSkip {
|
||||
buttonChild = button.update(
|
||||
component: ButtonComponent(
|
||||
background: buttonBackground,
|
||||
|
|
@ -5630,6 +5649,16 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||
}
|
||||
}
|
||||
|
||||
public struct CustomAction {
|
||||
public let title: String
|
||||
public let action: () -> Void
|
||||
|
||||
public init(title: String, action: @escaping () -> Void) {
|
||||
self.title = title
|
||||
self.action = action
|
||||
}
|
||||
}
|
||||
|
||||
private let context: AccountContext
|
||||
private let subject: GiftViewScreen.Subject
|
||||
|
||||
|
|
@ -5671,6 +5700,7 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||
fileprivate let togglePinnedToTop: ((StarGiftReference, Bool) -> Bool)?
|
||||
fileprivate let shareStory: ((StarGift.UniqueGift) -> Void)?
|
||||
fileprivate let openChatTheme: (() -> Void)?
|
||||
fileprivate let customAction: CustomAction?
|
||||
|
||||
public var disposed: () -> Void = {}
|
||||
|
||||
|
|
@ -5690,7 +5720,8 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||
updateResellStars: ((StarGiftReference, CurrencyAmount?) -> Signal<Never, UpdateStarGiftPriceError>)? = nil,
|
||||
togglePinnedToTop: ((StarGiftReference, Bool) -> Bool)? = nil,
|
||||
shareStory: ((StarGift.UniqueGift) -> Void)? = nil,
|
||||
openChatTheme: (() -> Void)? = nil
|
||||
openChatTheme: (() -> Void)? = nil,
|
||||
customAction: CustomAction? = nil
|
||||
) {
|
||||
self.context = context
|
||||
self.subject = subject
|
||||
|
|
@ -5706,6 +5737,7 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||
self.togglePinnedToTop = togglePinnedToTop
|
||||
self.shareStory = shareStory
|
||||
self.openChatTheme = openChatTheme
|
||||
self.customAction = customAction
|
||||
|
||||
if case let .unique(gift) = subject.arguments?.gift, gift.resellForTonOnly {
|
||||
self.balanceCurrency = .ton
|
||||
|
|
|
|||
|
|
@ -2289,7 +2289,7 @@ func availableActionsForMemberOfPeer(accountPeerId: PeerId, peer: Peer?, member:
|
|||
result.insert(.promote)
|
||||
case .admin:
|
||||
switch member {
|
||||
case let .legacyGroupMember(_, _, invitedBy, _, _):
|
||||
case let .legacyGroupMember(_, _, invitedBy, _, _, _):
|
||||
result.insert(.restrict)
|
||||
if invitedBy == accountPeerId {
|
||||
result.insert(.promote)
|
||||
|
|
@ -2301,7 +2301,7 @@ func availableActionsForMemberOfPeer(accountPeerId: PeerId, peer: Peer?, member:
|
|||
}
|
||||
case .member:
|
||||
switch member {
|
||||
case let .legacyGroupMember(_, _, invitedBy, _, _):
|
||||
case let .legacyGroupMember(_, _, invitedBy, _, _, _):
|
||||
if invitedBy == accountPeerId {
|
||||
result.insert(.restrict)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ enum PeerInfoMemberRole {
|
|||
|
||||
enum PeerInfoMember: Equatable {
|
||||
case channelMember(participant: RenderedChannelParticipant, storyStats: PeerStoryStats?)
|
||||
case legacyGroupMember(peer: RenderedPeer, role: PeerInfoMemberRole, invitedBy: PeerId?, presence: TelegramUserPresence?, storyStats: PeerStoryStats?)
|
||||
case legacyGroupMember(peer: RenderedPeer, role: PeerInfoMemberRole, invitedBy: PeerId?, presence: TelegramUserPresence?, storyStats: PeerStoryStats?, rank: String?)
|
||||
case account(peer: RenderedPeer)
|
||||
|
||||
var id: PeerId {
|
||||
switch self {
|
||||
case let .channelMember(participant, _):
|
||||
return participant.peer.id
|
||||
case let .legacyGroupMember(peer, _, _, _, _):
|
||||
case let .legacyGroupMember(peer, _, _, _, _, _):
|
||||
return peer.peerId
|
||||
case let .account(peer):
|
||||
return peer.peerId
|
||||
|
|
@ -31,7 +31,7 @@ enum PeerInfoMember: Equatable {
|
|||
switch self {
|
||||
case let .channelMember(participant, _):
|
||||
return participant.peer
|
||||
case let .legacyGroupMember(peer, _, _, _, _):
|
||||
case let .legacyGroupMember(peer, _, _, _, _, _):
|
||||
return peer.peers[peer.peerId]!
|
||||
case let .account(peer):
|
||||
return peer.peers[peer.peerId]!
|
||||
|
|
@ -42,7 +42,7 @@ enum PeerInfoMember: Equatable {
|
|||
switch self {
|
||||
case let .channelMember(participant, _):
|
||||
return participant.presences[participant.peer.id] as? TelegramUserPresence
|
||||
case let .legacyGroupMember(_, _, _, presence, _):
|
||||
case let .legacyGroupMember(_, _, _, presence, _, _):
|
||||
return presence
|
||||
case .account:
|
||||
return nil
|
||||
|
|
@ -62,7 +62,7 @@ enum PeerInfoMember: Equatable {
|
|||
return .member
|
||||
}
|
||||
}
|
||||
case let .legacyGroupMember(_, role, _, _, _):
|
||||
case let .legacyGroupMember(_, role, _, _, _, _):
|
||||
return role
|
||||
case .account:
|
||||
return .member
|
||||
|
|
@ -78,8 +78,8 @@ enum PeerInfoMember: Equatable {
|
|||
case let .member(_, _, _, _, rank, _):
|
||||
return rank
|
||||
}
|
||||
case .legacyGroupMember:
|
||||
return nil
|
||||
case let .legacyGroupMember(_, _, _, _, _, rank):
|
||||
return rank
|
||||
case .account:
|
||||
return nil
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ enum PeerInfoMember: Equatable {
|
|||
switch self {
|
||||
case let .channelMember(_, value):
|
||||
return value
|
||||
case let .legacyGroupMember(_, _, _, _, value):
|
||||
case let .legacyGroupMember(_, _, _, _, value, _):
|
||||
return value
|
||||
case .account:
|
||||
return nil
|
||||
|
|
@ -232,18 +232,22 @@ private final class PeerInfoMembersContextImpl {
|
|||
if let peer = view.peers[participant.peerId] {
|
||||
let role: PeerInfoMemberRole
|
||||
let invitedBy: PeerId?
|
||||
let rank: String?
|
||||
switch participant {
|
||||
case .creator:
|
||||
case let .creator(_, rankValue):
|
||||
role = .creator
|
||||
invitedBy = nil
|
||||
case let .admin(_, invitedByValue, _):
|
||||
rank = rankValue
|
||||
case let .admin(_, invitedByValue, _, rankValue):
|
||||
role = .admin
|
||||
invitedBy = invitedByValue
|
||||
case let .member(_, invitedByValue, _):
|
||||
rank = rankValue
|
||||
case let .member(_, invitedByValue, _, rankValue):
|
||||
role = .member
|
||||
invitedBy = invitedByValue
|
||||
rank = rankValue
|
||||
}
|
||||
unsortedMembers.append(.legacyGroupMember(peer: RenderedPeer(peer: peer), role: role, invitedBy: invitedBy, presence: view.peerPresences[participant.peerId] as? TelegramUserPresence, storyStats: view.memberStoryStats[participant.peerId]))
|
||||
unsortedMembers.append(.legacyGroupMember(peer: RenderedPeer(peer: peer), role: role, invitedBy: invitedBy, presence: view.peerPresences[participant.peerId] as? TelegramUserPresence, storyStats: view.memberStoryStats[participant.peerId], rank: rank))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ extension PeerInfoScreenNode {
|
|||
strongSelf.enqueueMediaMessageDisposable.set((legacyAssetPickerEnqueueMessages(context: strongSelf.context, account: strongSelf.context.account, signals: signals!)
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] messages in
|
||||
if let strongSelf = self {
|
||||
let _ = enqueueMessages(account: strongSelf.context.account, peerId: strongSelf.peerId, messages: messages.map { $0.message }).startStandalone()
|
||||
let _ = enqueueMessages(account: strongSelf.context.account, peerId: strongSelf.peerId, messages: messages.map { $0.message.withUpdatedReplyToMessageId(.init(messageId: message.id, quote: nil, todoItemId: nil)) }).startStandalone()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -508,12 +508,8 @@ final class GiftsListView: UIView {
|
|||
ribbonColor = .green
|
||||
ribbonOutline = params.presentationData.theme.list.blocksBackgroundColor
|
||||
} else {
|
||||
if product.pinnedToTop || self.canSelect || self.isCollection {
|
||||
ribbonFont = .monospaced
|
||||
ribbonText = "#\(gift.number)"
|
||||
} else {
|
||||
ribbonText = params.presentationData.strings.PeerInfo_Gifts_OneOf(compactNumericCountString(Int(gift.availability.issued), decimalSeparator: params.presentationData.dateTimeFormat.decimalSeparator)).string
|
||||
}
|
||||
ribbonFont = .monospaced
|
||||
ribbonText = "#\(gift.number)"
|
||||
for attribute in gift.attributes {
|
||||
if case let .backdrop(_, _, innerColor, outerColor, _, _, _) = attribute {
|
||||
ribbonColor = .custom(outerColor, innerColor)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import ListItemSliderSelectorComponent
|
|||
import DateSelectionUI
|
||||
import PlainButtonComponent
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
import TimeSelectionActionSheet
|
||||
|
||||
private let checkIcon: UIImage = {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ swift_library(
|
|||
"//submodules/LocationUI",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/TelegramStringFormatting",
|
||||
"//submodules/TextFormat",
|
||||
"//submodules/UIKitRuntimeUtils",
|
||||
"//submodules/TelegramUI/Components/Settings/TimezoneSelectionScreen",
|
||||
"//submodules/TelegramUI/Components/TimeSelectionActionSheet",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import LottieComponent
|
|||
import Markdown
|
||||
import LocationUI
|
||||
import TelegramStringFormatting
|
||||
import TextFormat
|
||||
import PlainButtonComponent
|
||||
import TimeSelectionActionSheet
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import Markdown
|
|||
import LocationUI
|
||||
import TelegramStringFormatting
|
||||
import TimezoneSelectionScreen
|
||||
import TextFormat
|
||||
|
||||
private func wrappedMinuteRange(range: Range<Int>, dayIndexOffset: Int = 0) -> IndexSet {
|
||||
let mappedRange = (range.lowerBound + dayIndexOffset * 24 * 60) ..< (range.upperBound + dayIndexOffset * 24 * 60)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import ChatMessageItemCommon
|
|||
import ChatControllerInteraction
|
||||
import EventKit
|
||||
import EventKitUI
|
||||
import ChatScheduleTimeController
|
||||
|
||||
extension ChatControllerImpl: EKEventEditViewDelegate {
|
||||
func openDateContextMenu(date: Int32, params: ChatControllerInteraction.LongTapParams) -> Void {
|
||||
|
|
@ -55,7 +56,7 @@ extension ChatControllerImpl: EKEventEditViewDelegate {
|
|||
|
||||
UIPasteboard.general.string = "\(date)"
|
||||
|
||||
self.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: presentationData.strings.Conversation_CardNumberCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
self.present(UndoOverlayController(presentationData: self.presentationData, content: .copy(text: "Date copied to clipboard."), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
}))
|
||||
)
|
||||
items.append(
|
||||
|
|
@ -81,6 +82,37 @@ extension ChatControllerImpl: EKEventEditViewDelegate {
|
|||
}
|
||||
}))
|
||||
)
|
||||
items.append(
|
||||
.action(ContextMenuActionItem(text: "Set a Reminder", icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Unmute"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
let controller = ChatScheduleTimeScreen(
|
||||
context: self.context,
|
||||
mode: .reminders,
|
||||
currentTime: date,
|
||||
currentRepeatPeriod: nil,
|
||||
minimalTime: nil,
|
||||
isDark: false,
|
||||
completion: { [weak self] result in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let attributes: [MessageAttribute] = [
|
||||
OutgoingScheduleInfoMessageAttribute(scheduleTime: result.time, repeatPeriod: result.repeatPeriod)
|
||||
]
|
||||
let forwardMessage: EnqueueMessage = .forward(source: message.id, threadId: nil, grouping: .auto, attributes: attributes, correlationId: nil)
|
||||
let _ = forwardMessage
|
||||
let _ = enqueueMessages(account: self.context.account, peerId: self.context.account.peerId, messages: [forwardMessage]).start()
|
||||
self.present(UndoOverlayController(presentationData: self.presentationData, content: .forward(savedMessages: true, text: "You have set a reminder in [Saved Messages]()."), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
)
|
||||
self.push(controller)
|
||||
}))
|
||||
)
|
||||
|
||||
self.canReadHistory.set(false)
|
||||
|
||||
|
|
|
|||
|
|
@ -91,11 +91,17 @@ extension ChatControllerImpl {
|
|||
if self.presentationInterfaceState.copyProtectionEnabled && !isAction && !isAd {
|
||||
if case .scheduledMessages = self.subject {
|
||||
} else {
|
||||
var isChannel = false
|
||||
if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
isChannel = true
|
||||
if let peer = self.presentationInterfaceState.renderedPeer?.peer {
|
||||
if peer is TelegramUser {
|
||||
|
||||
} else {
|
||||
var isChannel = false
|
||||
if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
isChannel = true
|
||||
}
|
||||
tip = .messageCopyProtection(isChannel: isChannel)
|
||||
}
|
||||
}
|
||||
tip = .messageCopyProtection(isChannel: isChannel)
|
||||
}
|
||||
} else {
|
||||
let numberOfComponents = message.text.components(separatedBy: CharacterSet.whitespacesAndNewlines).count
|
||||
|
|
|
|||
|
|
@ -1587,7 +1587,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
if isCaptionAbove {
|
||||
parameters = ChatSendMessageActionSheetController.SendParameters(effect: nil, textIsAboveMedia: true)
|
||||
}
|
||||
self.enqueueMediaMessages(signals: signals, silentPosting: false, parameters: parameters)
|
||||
self.enqueueMediaMessages(signals: signals, silentPosting: false, replyToSubject: .init(messageId: message.id, quote: nil, todoItemId: nil), parameters: parameters)
|
||||
}
|
||||
}, present: { [weak self] c, a in
|
||||
self?.present(c, in: .window(.root), with: a)
|
||||
|
|
@ -8353,17 +8353,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
})
|
||||
}
|
||||
|
||||
func enqueueMediaMessages(fromGallery: Bool = false, signals: [Any]?, silentPosting: Bool, scheduleTime: Int32? = nil, parameters: ChatSendMessageActionSheetController.SendParameters? = nil, getAnimatedTransitionSource: ((String) -> UIView?)? = nil, completion: @escaping () -> Void = {}) {
|
||||
func enqueueMediaMessages(fromGallery: Bool = false, signals: [Any]?, silentPosting: Bool, scheduleTime: Int32? = nil, replyToSubject: ChatInterfaceState.ReplyMessageSubject? = nil, parameters: ChatSendMessageActionSheetController.SendParameters? = nil, getAnimatedTransitionSource: ((String) -> UIView?)? = nil, completion: @escaping () -> Void = {}) {
|
||||
if let _ = self.presentationInterfaceState.sendPaidMessageStars {
|
||||
self.presentPaidMessageAlertIfNeeded(count: Int32(signals?.count ?? 1), forceDark: fromGallery, completion: { [weak self] postpone in
|
||||
self?.commitEnqueueMediaMessages(signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime, postpone: postpone, parameters: parameters, getAnimatedTransitionSource: getAnimatedTransitionSource, completion: completion)
|
||||
})
|
||||
} else {
|
||||
self.commitEnqueueMediaMessages(signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime, parameters: parameters, getAnimatedTransitionSource: getAnimatedTransitionSource, completion: completion)
|
||||
self.commitEnqueueMediaMessages(signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime, replyToSubject: replyToSubject, parameters: parameters, getAnimatedTransitionSource: getAnimatedTransitionSource, completion: completion)
|
||||
}
|
||||
}
|
||||
|
||||
private func commitEnqueueMediaMessages(signals: [Any]?, silentPosting: Bool, scheduleTime: Int32? = nil, postpone: Bool = false, parameters: ChatSendMessageActionSheetController.SendParameters? = nil, getAnimatedTransitionSource: ((String) -> UIView?)? = nil, completion: @escaping () -> Void = {}) {
|
||||
private func commitEnqueueMediaMessages(signals: [Any]?, silentPosting: Bool, scheduleTime: Int32? = nil, postpone: Bool = false, replyToSubject: ChatInterfaceState.ReplyMessageSubject? = nil, parameters: ChatSendMessageActionSheetController.SendParameters? = nil, getAnimatedTransitionSource: ((String) -> UIView?)? = nil, completion: @escaping () -> Void = {}) {
|
||||
self.enqueueMediaMessageDisposable.set((legacyAssetPickerEnqueueMessages(context: self.context, account: self.context.account, signals: signals!)
|
||||
|> deliverOnMainQueue).startStrict(next: { [weak self] items in
|
||||
guard let strongSelf = self else {
|
||||
|
|
@ -8503,7 +8503,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
}
|
||||
|
||||
let messages = strongSelf.transformEnqueueMessages(mappedMessages, silentPosting: silentPosting, scheduleTime: scheduleTime, postpone: postpone)
|
||||
let replyMessageSubject = strongSelf.presentationInterfaceState.interfaceState.replyMessageSubject
|
||||
let replyMessageSubject = replyToSubject ?? strongSelf.presentationInterfaceState.interfaceState.replyMessageSubject
|
||||
strongSelf.chatDisplayNode.setupSendActionOnViewUpdate({
|
||||
if let strongSelf = self {
|
||||
strongSelf.chatDisplayNode.collapseInput()
|
||||
|
|
|
|||
|
|
@ -893,7 +893,11 @@ extension ChatControllerImpl {
|
|||
peerVerification = cachedChannelData.verification
|
||||
}
|
||||
}
|
||||
copyProtectionEnabled = peer.isCopyProtectionEnabled
|
||||
if let cachedUserData = peerView.cachedData as? CachedUserData {
|
||||
copyProtectionEnabled = cachedUserData.flags.contains(.copyProtectionEnabled)
|
||||
} else {
|
||||
copyProtectionEnabled = peer.isCopyProtectionEnabled
|
||||
}
|
||||
if let cachedGroupData = peerView.cachedData as? CachedGroupData {
|
||||
if !cachedGroupData.botInfos.isEmpty {
|
||||
hasBots = true
|
||||
|
|
|
|||
177
submodules/TextFormat/Sources/DateFormat.swift
Normal file
177
submodules/TextFormat/Sources/DateFormat.swift
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
import Foundation
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import TelegramUIPreferences
|
||||
|
||||
public func stringForEntityFormattedDate(timestamp: Int32, format: MessageTextEntityType.DateTimeFormat, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat) -> String {
|
||||
switch format {
|
||||
case .relative:
|
||||
let currentTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||
let value = currentTimestamp - timestamp
|
||||
if value > 0 {
|
||||
if value < 60 {
|
||||
return strings.FormattedDate_SecondsAgo(value)
|
||||
} else if value <= 1 * 60 * 60 {
|
||||
return strings.FormattedDate_MinutesAgo(Int32(round(Float(value) / 60)))
|
||||
} else if value <= 24 * 60 * 60 {
|
||||
return strings.FormattedDate_HoursAgo(Int32(round(Float(value) / (60 * 60))))
|
||||
} else {
|
||||
return strings.FormattedDate_DaysAgo(Int32(round(Float(value) / (24 * 60 * 60))))
|
||||
}
|
||||
} else {
|
||||
let value = abs(value)
|
||||
if value < 60 {
|
||||
return strings.FormattedDate_InSeconds(value)
|
||||
} else if value <= 1 * 60 * 60 {
|
||||
return strings.FormattedDate_InMinutes(Int32(round(Float(value) / 60)))
|
||||
} else if value <= 24 * 60 * 60 {
|
||||
return strings.FormattedDate_InHours(Int32(round(Float(value) / (60 * 60))))
|
||||
} else {
|
||||
return strings.FormattedDate_InDays(Int32(round(Float(value) / (24 * 60 * 60))))
|
||||
}
|
||||
}
|
||||
case let .full(timeFormat, dateFormat):
|
||||
var string = ""
|
||||
if let dateFormat {
|
||||
switch dateFormat {
|
||||
case .short:
|
||||
string += stringForShortDate(timestamp: timestamp, strings: strings, dateTimeFormat: dateTimeFormat)
|
||||
case .long:
|
||||
string += stringForFullDate(timestamp: timestamp, strings: strings, dateTimeFormat: dateTimeFormat)
|
||||
}
|
||||
}
|
||||
if let timeFormat {
|
||||
let timeString: String
|
||||
switch timeFormat {
|
||||
case .short:
|
||||
timeString = stringForMessageTimestamp(timestamp: timestamp, dateTimeFormat: dateTimeFormat)
|
||||
case .long:
|
||||
timeString = stringForMessageTimestamp(timestamp: timestamp, dateTimeFormat: dateTimeFormat, withSeconds: true)
|
||||
}
|
||||
if !string.isEmpty {
|
||||
string = strings.Time_AtPreciseDate(string, timeString).string
|
||||
} else {
|
||||
string = timeString
|
||||
}
|
||||
}
|
||||
return string
|
||||
}
|
||||
}
|
||||
|
||||
public func stringForShortTimestamp(hours: Int32, minutes: Int32, seconds: Int32? = nil, dateTimeFormat: PresentationDateTimeFormat, formatAsPlainText: Bool = false) -> String {
|
||||
switch dateTimeFormat.timeFormat {
|
||||
case .regular:
|
||||
let hourString: String
|
||||
if hours == 0 {
|
||||
hourString = "12"
|
||||
} else if hours > 12 {
|
||||
hourString = "\(hours - 12)"
|
||||
} else {
|
||||
hourString = "\(hours)"
|
||||
}
|
||||
|
||||
let periodString: String
|
||||
if hours >= 12 {
|
||||
periodString = "PM"
|
||||
} else {
|
||||
periodString = "AM"
|
||||
}
|
||||
|
||||
let spaceCharacter: String
|
||||
if formatAsPlainText {
|
||||
spaceCharacter = " "
|
||||
} else {
|
||||
spaceCharacter = "\u{00a0}"
|
||||
}
|
||||
|
||||
let minuteString = String(format: "%02d", arguments: [Int(minutes)])
|
||||
if let seconds {
|
||||
let secondString = String(format: "%02d", arguments: [Int(seconds)])
|
||||
return "\(hourString):\(minuteString):\(secondString)\(spaceCharacter)\(periodString)"
|
||||
} else {
|
||||
return "\(hourString):\(minuteString)\(spaceCharacter)\(periodString)"
|
||||
}
|
||||
case .military:
|
||||
if let seconds {
|
||||
return String(format: "%02d:%02d:%02d", arguments: [Int(hours), Int(minutes), Int(seconds)])
|
||||
} else {
|
||||
return String(format: "%02d:%02d", arguments: [Int(hours), Int(minutes)])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func stringForMessageTimestamp(timestamp: Int32, dateTimeFormat: PresentationDateTimeFormat, withSeconds: Bool = false, local: Bool = true) -> String {
|
||||
var t = Int(timestamp)
|
||||
var timeinfo = tm()
|
||||
if local {
|
||||
localtime_r(&t, &timeinfo)
|
||||
} else {
|
||||
gmtime_r(&t, &timeinfo)
|
||||
}
|
||||
|
||||
return stringForShortTimestamp(hours: timeinfo.tm_hour, minutes: timeinfo.tm_min, seconds: withSeconds ? timeinfo.tm_sec : nil, dateTimeFormat: dateTimeFormat)
|
||||
}
|
||||
|
||||
private func stringForShortDate(timestamp: Int32, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, withTime: Bool = true) -> String {
|
||||
var t: time_t = Int(timestamp)
|
||||
var timeinfo = tm()
|
||||
localtime_r(&t, &timeinfo);
|
||||
|
||||
let day = timeinfo.tm_mday
|
||||
let month = timeinfo.tm_mon + 1
|
||||
let year = timeinfo.tm_year
|
||||
|
||||
let dateString: String
|
||||
let separator = dateTimeFormat.dateSeparator
|
||||
let suffix = dateTimeFormat.dateSuffix
|
||||
let displayYear = dateTimeFormat.requiresFullYear ? year - 100 + 2000 : year - 100
|
||||
switch dateTimeFormat.dateFormat {
|
||||
case .monthFirst:
|
||||
dateString = String(format: "%02d%@%02d%@%02d%@", month, separator, day, separator, displayYear, suffix)
|
||||
case .dayFirst:
|
||||
dateString = String(format: "%02d%@%02d%@%02d%@", day, separator, month, separator, displayYear, suffix)
|
||||
}
|
||||
|
||||
return dateString
|
||||
}
|
||||
|
||||
private func stringForFullDate(timestamp: Int32, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat) -> String {
|
||||
var t: time_t = Int(timestamp)
|
||||
var timeinfo = tm()
|
||||
localtime_r(&t, &timeinfo);
|
||||
|
||||
let dayString = "\(timeinfo.tm_mday)"
|
||||
let yearString = "\(2000 + timeinfo.tm_year - 100)"
|
||||
|
||||
let monthFormat: (String, String) -> PresentationStrings.FormattedString
|
||||
switch timeinfo.tm_mon + 1 {
|
||||
case 1:
|
||||
monthFormat = strings.FormattedDate_LongDate_m1
|
||||
case 2:
|
||||
monthFormat = strings.FormattedDate_LongDate_m2
|
||||
case 3:
|
||||
monthFormat = strings.FormattedDate_LongDate_m3
|
||||
case 4:
|
||||
monthFormat = strings.FormattedDate_LongDate_m4
|
||||
case 5:
|
||||
monthFormat = strings.FormattedDate_LongDate_m5
|
||||
case 6:
|
||||
monthFormat = strings.FormattedDate_LongDate_m6
|
||||
case 7:
|
||||
monthFormat = strings.FormattedDate_LongDate_m7
|
||||
case 8:
|
||||
monthFormat = strings.FormattedDate_LongDate_m8
|
||||
case 9:
|
||||
monthFormat = strings.FormattedDate_LongDate_m9
|
||||
case 10:
|
||||
monthFormat = strings.FormattedDate_LongDate_m10
|
||||
case 11:
|
||||
monthFormat = strings.FormattedDate_LongDate_m11
|
||||
case 12:
|
||||
monthFormat = strings.FormattedDate_LongDate_m12
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
||||
return monthFormat(dayString, yearString).string
|
||||
}
|
||||
|
|
@ -299,7 +299,30 @@ public func generateTextEntities(_ text: String, enabledTypes: EnabledEntityType
|
|||
|
||||
type = .Url
|
||||
} else if result.resultType == NSTextCheckingResult.CheckingType.date, let date = result.date?.timeIntervalSince1970 {
|
||||
type = .FormattedDate(format: .relative, date: Int32(date))
|
||||
#if DEBUG
|
||||
var format: MessageTextEntityType.DateTimeFormat?
|
||||
if text.contains("[rel]") {
|
||||
format = .relative
|
||||
}
|
||||
var timeFormat: MessageTextEntityType.DateTimeFormat.TimeFormat?
|
||||
if text.contains("[st]") {
|
||||
timeFormat = .short
|
||||
} else if text.contains("[lt]") {
|
||||
timeFormat = .long
|
||||
}
|
||||
var dateFormat: MessageTextEntityType.DateTimeFormat.DateFormat?
|
||||
if text.contains("[sd]") {
|
||||
dateFormat = .short
|
||||
} else if text.contains("[ld]") {
|
||||
dateFormat = .long
|
||||
}
|
||||
if timeFormat != nil || dateFormat != nil {
|
||||
format = .full(timeFormat: timeFormat, dateFormat: dateFormat)
|
||||
}
|
||||
type = .FormattedDate(format: format, date: Int32(date))
|
||||
#else
|
||||
type = .FormattedDate(format: nil, date: Int32(date))
|
||||
#endif
|
||||
} else {
|
||||
type = .PhoneNumber
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import TelegramCore
|
|||
import Display
|
||||
import libprisma
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
|
||||
public func chatInputStateStringWithAppliedEntities(_ text: String, entities: [MessageTextEntity]) -> NSAttributedString {
|
||||
var nsString: NSString?
|
||||
|
|
@ -80,7 +81,7 @@ public func chatInputStateStringWithAppliedEntities(_ text: String, entities: [M
|
|||
|
||||
private let syntaxHighlighter = Syntaxer()
|
||||
|
||||
public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], baseColor: UIColor, linkColor: UIColor, baseQuoteTintColor: UIColor? = nil, baseQuoteSecondaryTintColor: UIColor? = nil, baseQuoteTertiaryTintColor: UIColor? = nil, codeBlockTitleColor: UIColor? = nil, codeBlockAccentColor: UIColor? = nil, codeBlockBackgroundColor: UIColor? = nil, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: Message?, entityFiles: [MediaId: TelegramMediaFile] = [:], adjustQuoteFontSize: Bool = false, cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, paragraphAlignment: NSTextAlignment? = nil) -> NSAttributedString {
|
||||
public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEntity], strings: PresentationStrings? = nil, dateTimeFormat: PresentationDateTimeFormat? = nil, baseColor: UIColor, linkColor: UIColor, baseQuoteTintColor: UIColor? = nil, baseQuoteSecondaryTintColor: UIColor? = nil, baseQuoteTertiaryTintColor: UIColor? = nil, codeBlockTitleColor: UIColor? = nil, codeBlockAccentColor: UIColor? = nil, codeBlockBackgroundColor: UIColor? = nil, baseFont: UIFont, linkFont: UIFont, boldFont: UIFont, italicFont: UIFont, boldItalicFont: UIFont, fixedFont: UIFont, blockQuoteFont: UIFont, underlineLinks: Bool = true, external: Bool = false, message: Message?, entityFiles: [MediaId: TelegramMediaFile] = [:], adjustQuoteFontSize: Bool = false, cachedMessageSyntaxHighlight: CachedMessageSyntaxHighlight? = nil, paragraphAlignment: NSTextAlignment? = nil) -> NSAttributedString {
|
||||
let baseQuoteTintColor = baseQuoteTintColor ?? baseColor
|
||||
|
||||
var nsString: NSString?
|
||||
|
|
@ -94,7 +95,7 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti
|
|||
|
||||
var adjustedRanges: [NSRange?] = []
|
||||
adjustedRanges.reserveCapacity(entities.count)
|
||||
let rangeDelta = 0
|
||||
var rangeDelta = 0
|
||||
for entity in entities {
|
||||
let originalRange = NSRange(location: entity.range.lowerBound, length: entity.range.upperBound - entity.range.lowerBound)
|
||||
var range = NSRange(location: originalRange.location + rangeDelta, length: originalRange.length)
|
||||
|
|
@ -106,23 +107,22 @@ public func stringWithAppliedEntities(_ text: String, entities: [MessageTextEnti
|
|||
range.length = stringLength - range.location
|
||||
}
|
||||
|
||||
// switch entity.type {
|
||||
// case let .FormattedDate(format, date):
|
||||
// let replacement = stringForEntityFormattedDate()
|
||||
// switch format {
|
||||
// case .relative:
|
||||
// replacement = relative
|
||||
// case let .full(timeFormat, dateFormat):
|
||||
// }
|
||||
//
|
||||
// let replacementString = NSAttributedString(string: replacement, attributes: baseAttributes)
|
||||
// string.replaceCharacters(in: range, with: replacementString)
|
||||
// let newRange = NSRange(location: range.location, length: (replacement as NSString).length)
|
||||
// adjustedRanges.append(newRange)
|
||||
// rangeDelta += newRange.length - range.length
|
||||
// default:
|
||||
switch entity.type {
|
||||
case let .FormattedDate(format, date):
|
||||
if let format, let strings, let dateTimeFormat {
|
||||
let replacement = stringForEntityFormattedDate(timestamp: date, format: format, strings: strings, dateTimeFormat: dateTimeFormat)
|
||||
|
||||
let replacementString = NSAttributedString(string: replacement, attributes: baseAttributes)
|
||||
string.replaceCharacters(in: range, with: replacementString)
|
||||
let newRange = NSRange(location: range.location, length: (replacement as NSString).length)
|
||||
adjustedRanges.append(newRange)
|
||||
rangeDelta += newRange.length - range.length
|
||||
} else {
|
||||
adjustedRanges.append(range)
|
||||
}
|
||||
default:
|
||||
adjustedRanges.append(range)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
var fontAttributeMask: [ChatTextFontAttributes] = Array(repeating: [], count: string.length)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue