From 461c538d6229ab9f546dc05f2f748616f258185c Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Fri, 19 Jul 2019 01:08:18 +0200 Subject: [PATCH] Update API --- submodules/Display/Display/UIKitUtils.swift | 12 ++ submodules/TelegramApi/Sources/Api0.swift | 9 +- submodules/TelegramApi/Sources/Api1.swift | 66 ++++++----- submodules/TelegramApi/Sources/Api2.swift | 60 ++++++---- submodules/TelegramApi/Sources/Api3.swift | 68 +++++------ .../TelegramCore/AccountState.swift | 37 ++---- .../TelegramCore/AddPeerMember.swift | 10 +- .../TelegramCore/ApiGroupOrChannel.swift | 4 +- .../TelegramCore/Authorization.swift | 112 ++++++++---------- .../TelegramCore/BotPaymentForm.swift | 2 +- .../CachedChannelParticipants.swift | 62 ++++++---- .../TelegramCore/CancelAccountReset.swift | 4 +- .../ChangeAccountPhoneNumber.swift | 4 +- .../TelegramCore/ChannelAdmins.swift | 4 +- .../TelegramCore/ChannelBlacklist.swift | 12 +- .../ChannelOwnershipTransfer.swift | 8 +- .../TelegramCore/JoinChannel.swift | 2 +- .../TelegramCore/PeerAdmins.swift | 22 ++-- .../TelegramCore/TelegramGroup.swift | 24 ++-- .../TelegramCore/VerifySecureIdValue.swift | 2 +- .../Sources/PresentationData.swift | 4 +- .../AuthorizationSequenceController.swift | 8 +- .../TelegramUI/ChannelAdminController.swift | 20 ++-- .../TelegramUI/ChannelAdminsController.swift | 26 ++-- .../ChannelBannedMemberController.swift | 14 +-- .../ChannelBlacklistController.swift | 4 +- .../ChannelMemberCategoryListContext.swift | 20 +++- .../ChannelMembersSearchContainerNode.swift | 24 ++-- .../ChannelMembersSearchControllerNode.swift | 6 +- .../ChannelPermissionsController.swift | 4 +- .../TelegramUI/ChatController.swift | 14 +-- ...ChatMessageActionSheetControllerNode.swift | 8 +- .../ChatRecentActionsControllerNode.swift | 11 +- .../ChatRecentActionsHistoryTransition.swift | 8 +- .../TelegramUI/CreateChannelController.swift | 2 +- .../TelegramUI/CreateGroupController.swift | 2 +- .../TelegramUI/GroupInfoController.swift | 34 +++--- .../TelegramUI/LogoutOptionsController.swift | 2 +- ...annelMemberCategoriesContextsManager.swift | 6 +- .../ThemeAutoNightSettingsController.swift | 11 +- .../ThemeSettingsColorSliderNode.swift | 73 +++++------- .../TelegramUI/ThemeSettingsController.swift | 24 +++- .../TelegramUI/ThemeSettingsThemeItem.swift | 6 +- .../Sources/PresentationThemeSettings.swift | 45 +++++-- 44 files changed, 483 insertions(+), 417 deletions(-) diff --git a/submodules/Display/Display/UIKitUtils.swift b/submodules/Display/Display/UIKitUtils.swift index 13cd3dafe9..3a35f30661 100644 --- a/submodules/Display/Display/UIKitUtils.swift +++ b/submodules/Display/Display/UIKitUtils.swift @@ -152,6 +152,18 @@ public extension UIColor { } return self } + + func interpolateTo(_ color: UIColor, fraction: CGFloat) -> UIColor? { + let f = min(max(0, fraction), 1) + + guard let c1 = self.cgColor.components, let c2 = color.cgColor.components else { return nil } + let r: CGFloat = CGFloat(c1[0] + (c2[0] - c1[0]) * f) + let g: CGFloat = CGFloat(c1[1] + (c2[1] - c1[1]) * f) + let b: CGFloat = CGFloat(c1[2] + (c2[2] - c1[2]) * f) + let a: CGFloat = CGFloat(c1[3] + (c2[3] - c1[3]) * f) + + return UIColor(red: r, green: g, blue: b, alpha: a) + } } public extension CGSize { diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 48f6783946..c07fbd6e77 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -128,6 +128,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-1802240206] = { return Api.messages.SentEncryptedMessage.parse_sentEncryptedFile($0) } dict[1571494644] = { return Api.ExportedMessageLink.parse_exportedMessageLink($0) } dict[-855308010] = { return Api.auth.Authorization.parse_authorization($0) } + dict[1148485274] = { return Api.auth.Authorization.parse_authorizationSignUpRequired($0) } dict[-181407105] = { return Api.InputFile.parse_inputFile($0) } dict[-95482955] = { return Api.InputFile.parse_inputFileBig($0) } dict[-1649296275] = { return Api.Peer.parse_peerUser($0) } @@ -238,9 +239,9 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) } dict[367766557] = { return Api.ChannelParticipant.parse_channelParticipant($0) } dict[-1557620115] = { return Api.ChannelParticipant.parse_channelParticipantSelf($0) } - dict[-471670279] = { return Api.ChannelParticipant.parse_channelParticipantCreator($0) } dict[470789295] = { return Api.ChannelParticipant.parse_channelParticipantBanned($0) } - dict[1571450403] = { return Api.ChannelParticipant.parse_channelParticipantAdmin($0) } + dict[-859915345] = { return Api.ChannelParticipant.parse_channelParticipantAdmin($0) } + dict[-2138237532] = { return Api.ChannelParticipant.parse_channelParticipantCreator($0) } dict[471043349] = { return Api.contacts.Blocked.parse_blocked($0) } dict[-1878523231] = { return Api.contacts.Blocked.parse_blockedSlice($0) } dict[-55902537] = { return Api.InputDialogPeer.parse_inputDialogPeer($0) } @@ -349,7 +350,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[295067450] = { return Api.BotInlineResult.parse_botInlineResult($0) } dict[911761060] = { return Api.messages.BotCallbackAnswer.parse_botCallbackAnswer($0) } dict[1314881805] = { return Api.payments.PaymentResult.parse_paymentResult($0) } - dict[1800845601] = { return Api.payments.PaymentResult.parse_paymentVerficationNeeded($0) } + dict[-666824391] = { return Api.payments.PaymentResult.parse_paymentVerificationNeeded($0) } dict[1694474197] = { return Api.messages.Chats.parse_chats($0) } dict[-1663561404] = { return Api.messages.Chats.parse_chatsSlice($0) } dict[482797855] = { return Api.InputSingleMedia.parse_inputSingleMedia($0) } @@ -488,7 +489,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-923939298] = { return Api.messages.Messages.parse_messagesSlice($0) } dict[-1022713000] = { return Api.Invoice.parse_invoice($0) } dict[-2122045747] = { return Api.PeerSettings.parse_peerSettings($0) } - dict[955951967] = { return Api.auth.SentCode.parse_sentCode($0) } + dict[1577067778] = { return Api.auth.SentCode.parse_sentCode($0) } dict[480546647] = { return Api.InputChatPhoto.parse_inputChatPhotoEmpty($0) } dict[-1837345356] = { return Api.InputChatPhoto.parse_inputChatUploadedPhoto($0) } dict[-1991004873] = { return Api.InputChatPhoto.parse_inputChatPhoto($0) } diff --git a/submodules/TelegramApi/Sources/Api1.swift b/submodules/TelegramApi/Sources/Api1.swift index ec550c5be8..11639e00bd 100644 --- a/submodules/TelegramApi/Sources/Api1.swift +++ b/submodules/TelegramApi/Sources/Api1.swift @@ -6064,9 +6064,9 @@ public extension Api { public enum ChannelParticipant: TypeConstructorDescription { case channelParticipant(userId: Int32, date: Int32) case channelParticipantSelf(userId: Int32, inviterId: Int32, date: Int32) - case channelParticipantCreator(userId: Int32) case channelParticipantBanned(flags: Int32, userId: Int32, kickedBy: Int32, date: Int32, bannedRights: Api.ChatBannedRights) - case channelParticipantAdmin(flags: Int32, userId: Int32, inviterId: Int32?, promotedBy: Int32, date: Int32, adminRights: Api.ChatAdminRights) + case channelParticipantAdmin(flags: Int32, userId: Int32, inviterId: Int32?, promotedBy: Int32, date: Int32, adminRights: Api.ChatAdminRights, rank: String?) + case channelParticipantCreator(flags: Int32, userId: Int32, rank: String?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -6085,12 +6085,6 @@ public extension Api { serializeInt32(inviterId, buffer: buffer, boxed: false) serializeInt32(date, buffer: buffer, boxed: false) break - case .channelParticipantCreator(let userId): - if boxed { - buffer.appendInt32(-471670279) - } - serializeInt32(userId, buffer: buffer, boxed: false) - break case .channelParticipantBanned(let flags, let userId, let kickedBy, let date, let bannedRights): if boxed { buffer.appendInt32(470789295) @@ -6101,9 +6095,9 @@ public extension Api { serializeInt32(date, buffer: buffer, boxed: false) bannedRights.serialize(buffer, true) break - case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights): + case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights, let rank): if boxed { - buffer.appendInt32(1571450403) + buffer.appendInt32(-859915345) } serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(userId, buffer: buffer, boxed: false) @@ -6111,6 +6105,15 @@ public extension Api { serializeInt32(promotedBy, buffer: buffer, boxed: false) serializeInt32(date, buffer: buffer, boxed: false) adminRights.serialize(buffer, true) + if Int(flags) & Int(1 << 2) != 0 {serializeString(rank!, buffer: buffer, boxed: false)} + break + case .channelParticipantCreator(let flags, let userId, let rank): + if boxed { + buffer.appendInt32(-2138237532) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeInt32(userId, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {serializeString(rank!, buffer: buffer, boxed: false)} break } } @@ -6121,12 +6124,12 @@ public extension Api { return ("channelParticipant", [("userId", userId), ("date", date)]) case .channelParticipantSelf(let userId, let inviterId, let date): return ("channelParticipantSelf", [("userId", userId), ("inviterId", inviterId), ("date", date)]) - case .channelParticipantCreator(let userId): - return ("channelParticipantCreator", [("userId", userId)]) case .channelParticipantBanned(let flags, let userId, let kickedBy, let date, let bannedRights): return ("channelParticipantBanned", [("flags", flags), ("userId", userId), ("kickedBy", kickedBy), ("date", date), ("bannedRights", bannedRights)]) - case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights): - return ("channelParticipantAdmin", [("flags", flags), ("userId", userId), ("inviterId", inviterId), ("promotedBy", promotedBy), ("date", date), ("adminRights", adminRights)]) + case .channelParticipantAdmin(let flags, let userId, let inviterId, let promotedBy, let date, let adminRights, let rank): + return ("channelParticipantAdmin", [("flags", flags), ("userId", userId), ("inviterId", inviterId), ("promotedBy", promotedBy), ("date", date), ("adminRights", adminRights), ("rank", rank)]) + case .channelParticipantCreator(let flags, let userId, let rank): + return ("channelParticipantCreator", [("flags", flags), ("userId", userId), ("rank", rank)]) } } @@ -6161,17 +6164,6 @@ public extension Api { return nil } } - public static func parse_channelParticipantCreator(_ reader: BufferReader) -> ChannelParticipant? { - var _1: Int32? - _1 = reader.readInt32() - let _c1 = _1 != nil - if _c1 { - return Api.ChannelParticipant.channelParticipantCreator(userId: _1!) - } - else { - return nil - } - } public static func parse_channelParticipantBanned(_ reader: BufferReader) -> ChannelParticipant? { var _1: Int32? _1 = reader.readInt32() @@ -6212,14 +6204,34 @@ public extension Api { if let signature = reader.readInt32() { _6 = Api.parse(reader, signature: signature) as? Api.ChatAdminRights } + var _7: String? + if Int(_1!) & Int(1 << 2) != 0 {_7 = parseString(reader) } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil let _c4 = _4 != nil let _c5 = _5 != nil let _c6 = _6 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 { - return Api.ChannelParticipant.channelParticipantAdmin(flags: _1!, userId: _2!, inviterId: _3, promotedBy: _4!, date: _5!, adminRights: _6!) + let _c7 = (Int(_1!) & Int(1 << 2) == 0) || _7 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 { + return Api.ChannelParticipant.channelParticipantAdmin(flags: _1!, userId: _2!, inviterId: _3, promotedBy: _4!, date: _5!, adminRights: _6!, rank: _7) + } + else { + return nil + } + } + public static func parse_channelParticipantCreator(_ reader: BufferReader) -> ChannelParticipant? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Int32? + _2 = reader.readInt32() + var _3: String? + if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil + if _c1 && _c2 && _c3 { + return Api.ChannelParticipant.channelParticipantCreator(flags: _1!, userId: _2!, rank: _3) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api2.swift b/submodules/TelegramApi/Sources/Api2.swift index 7df19d0089..02f63a3f26 100644 --- a/submodules/TelegramApi/Sources/Api2.swift +++ b/submodules/TelegramApi/Sources/Api2.swift @@ -226,7 +226,7 @@ public struct payments { } public enum PaymentResult: TypeConstructorDescription { case paymentResult(updates: Api.Updates) - case paymentVerficationNeeded(url: String) + case paymentVerificationNeeded(url: String) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -236,9 +236,9 @@ public struct payments { } updates.serialize(buffer, true) break - case .paymentVerficationNeeded(let url): + case .paymentVerificationNeeded(let url): if boxed { - buffer.appendInt32(1800845601) + buffer.appendInt32(-666824391) } serializeString(url, buffer: buffer, boxed: false) break @@ -249,8 +249,8 @@ public struct payments { switch self { case .paymentResult(let updates): return ("paymentResult", [("updates", updates)]) - case .paymentVerficationNeeded(let url): - return ("paymentVerficationNeeded", [("url", url)]) + case .paymentVerificationNeeded(let url): + return ("paymentVerificationNeeded", [("url", url)]) } } @@ -267,12 +267,12 @@ public struct payments { return nil } } - public static func parse_paymentVerficationNeeded(_ reader: BufferReader) -> PaymentResult? { + public static func parse_paymentVerificationNeeded(_ reader: BufferReader) -> PaymentResult? { var _1: String? _1 = parseString(reader) let _c1 = _1 != nil if _c1 { - return Api.payments.PaymentResult.paymentVerficationNeeded(url: _1!) + return Api.payments.PaymentResult.paymentVerificationNeeded(url: _1!) } else { return nil @@ -496,6 +496,7 @@ public extension Api { public struct auth { public enum Authorization: TypeConstructorDescription { case authorization(flags: Int32, tmpSessions: Int32?, user: Api.User) + case authorizationSignUpRequired(flags: Int32, termsOfService: Api.help.TermsOfService?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -507,6 +508,13 @@ public struct auth { if Int(flags) & Int(1 << 0) != 0 {serializeInt32(tmpSessions!, buffer: buffer, boxed: false)} user.serialize(buffer, true) break + case .authorizationSignUpRequired(let flags, let termsOfService): + if boxed { + buffer.appendInt32(1148485274) + } + serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {termsOfService!.serialize(buffer, true)} + break } } @@ -514,6 +522,8 @@ public struct auth { switch self { case .authorization(let flags, let tmpSessions, let user): return ("authorization", [("flags", flags), ("tmpSessions", tmpSessions), ("user", user)]) + case .authorizationSignUpRequired(let flags, let termsOfService): + return ("authorizationSignUpRequired", [("flags", flags), ("termsOfService", termsOfService)]) } } @@ -536,6 +546,22 @@ public struct auth { return nil } } + public static func parse_authorizationSignUpRequired(_ reader: BufferReader) -> Authorization? { + var _1: Int32? + _1 = reader.readInt32() + var _2: Api.help.TermsOfService? + if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() { + _2 = Api.parse(reader, signature: signature) as? Api.help.TermsOfService + } } + let _c1 = _1 != nil + let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil + if _c1 && _c2 { + return Api.auth.Authorization.authorizationSignUpRequired(flags: _1!, termsOfService: _2) + } + else { + return nil + } + } } public enum PasswordRecovery: TypeConstructorDescription { @@ -647,28 +673,27 @@ public struct auth { } public enum SentCode: TypeConstructorDescription { - case sentCode(flags: Int32, type: Api.auth.SentCodeType, phoneCodeHash: String, nextType: Api.auth.CodeType?, timeout: Int32?, termsOfService: Api.help.TermsOfService?) + case sentCode(flags: Int32, type: Api.auth.SentCodeType, phoneCodeHash: String, nextType: Api.auth.CodeType?, timeout: Int32?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .sentCode(let flags, let type, let phoneCodeHash, let nextType, let timeout, let termsOfService): + case .sentCode(let flags, let type, let phoneCodeHash, let nextType, let timeout): if boxed { - buffer.appendInt32(955951967) + buffer.appendInt32(1577067778) } serializeInt32(flags, buffer: buffer, boxed: false) type.serialize(buffer, true) serializeString(phoneCodeHash, buffer: buffer, boxed: false) if Int(flags) & Int(1 << 1) != 0 {nextType!.serialize(buffer, true)} if Int(flags) & Int(1 << 2) != 0 {serializeInt32(timeout!, buffer: buffer, boxed: false)} - if Int(flags) & Int(1 << 3) != 0 {termsOfService!.serialize(buffer, true)} break } } public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .sentCode(let flags, let type, let phoneCodeHash, let nextType, let timeout, let termsOfService): - return ("sentCode", [("flags", flags), ("type", type), ("phoneCodeHash", phoneCodeHash), ("nextType", nextType), ("timeout", timeout), ("termsOfService", termsOfService)]) + case .sentCode(let flags, let type, let phoneCodeHash, let nextType, let timeout): + return ("sentCode", [("flags", flags), ("type", type), ("phoneCodeHash", phoneCodeHash), ("nextType", nextType), ("timeout", timeout)]) } } @@ -687,18 +712,13 @@ public struct auth { } } var _5: Int32? if Int(_1!) & Int(1 << 2) != 0 {_5 = reader.readInt32() } - var _6: Api.help.TermsOfService? - if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() { - _6 = Api.parse(reader, signature: signature) as? Api.help.TermsOfService - } } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil let _c5 = (Int(_1!) & Int(1 << 2) == 0) || _5 != nil - let _c6 = (Int(_1!) & Int(1 << 3) == 0) || _6 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 { - return Api.auth.SentCode.sentCode(flags: _1!, type: _2!, phoneCodeHash: _3!, nextType: _4, timeout: _5, termsOfService: _6) + if _c1 && _c2 && _c3 && _c4 && _c5 { + return Api.auth.SentCode.sentCode(flags: _1!, type: _2!, phoneCodeHash: _3!, nextType: _4, timeout: _5) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api3.swift b/submodules/TelegramApi/Sources/Api3.swift index 86116c0e3f..d5a1815eb7 100644 --- a/submodules/TelegramApi/Sources/Api3.swift +++ b/submodules/TelegramApi/Sources/Api3.swift @@ -3367,22 +3367,6 @@ public extension Api { }) } - public static func editAdmin(channel: Api.InputChannel, userId: Api.InputUser, adminRights: Api.ChatAdminRights) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(1895338938) - channel.serialize(buffer, true) - userId.serialize(buffer, true) - adminRights.serialize(buffer, true) - return (FunctionDescription(name: "channels.editAdmin", parameters: [("channel", channel), ("userId", userId), ("adminRights", adminRights)]), 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 static func editBanned(channel: Api.InputChannel, userId: Api.InputUser, bannedRights: Api.ChatBannedRights) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() buffer.appendInt32(1920559378) @@ -3520,6 +3504,23 @@ public extension Api { return result }) } + + public static func editAdmin(channel: Api.InputChannel, userId: Api.InputUser, adminRights: Api.ChatAdminRights, rank: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(-751007486) + channel.serialize(buffer, true) + userId.serialize(buffer, true) + adminRights.serialize(buffer, true) + serializeString(rank, buffer: buffer, boxed: false) + return (FunctionDescription(name: "channels.editAdmin", parameters: [("channel", channel), ("userId", userId), ("adminRights", adminRights), ("rank", 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 struct payments { public static func getPaymentForm(msgId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { @@ -3645,24 +3646,6 @@ public extension Api { }) } - public static func signUp(phoneNumber: String, phoneCodeHash: String, phoneCode: String, firstName: String, lastName: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(453408308) - serializeString(phoneNumber, buffer: buffer, boxed: false) - serializeString(phoneCodeHash, buffer: buffer, boxed: false) - serializeString(phoneCode, buffer: buffer, boxed: false) - serializeString(firstName, buffer: buffer, boxed: false) - serializeString(lastName, buffer: buffer, boxed: false) - return (FunctionDescription(name: "auth.signUp", parameters: [("phoneNumber", phoneNumber), ("phoneCodeHash", phoneCodeHash), ("phoneCode", phoneCode), ("firstName", firstName), ("lastName", lastName)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.auth.Authorization? in - let reader = BufferReader(buffer) - var result: Api.auth.Authorization? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.auth.Authorization - } - return result - }) - } - public static func signIn(phoneNumber: String, phoneCodeHash: String, phoneCode: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() buffer.appendInt32(-1126886015) @@ -3878,6 +3861,23 @@ public extension Api { return result }) } + + public static func signUp(phoneNumber: String, phoneCodeHash: String, firstName: String, lastName: String) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(-2131827673) + serializeString(phoneNumber, buffer: buffer, boxed: false) + serializeString(phoneCodeHash, buffer: buffer, boxed: false) + serializeString(firstName, buffer: buffer, boxed: false) + serializeString(lastName, buffer: buffer, boxed: false) + return (FunctionDescription(name: "auth.signUp", parameters: [("phoneNumber", phoneNumber), ("phoneCodeHash", phoneCodeHash), ("firstName", firstName), ("lastName", lastName)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.auth.Authorization? in + let reader = BufferReader(buffer) + var result: Api.auth.Authorization? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.auth.Authorization + } + return result + }) + } } public struct bots { public static func sendCustomRequest(customMethod: String, params: Api.DataJSON) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { diff --git a/submodules/TelegramCore/TelegramCore/AccountState.swift b/submodules/TelegramCore/TelegramCore/AccountState.swift index 337c5a7a6c..ca57a4b82a 100644 --- a/submodules/TelegramCore/TelegramCore/AccountState.swift +++ b/submodules/TelegramCore/TelegramCore/AccountState.swift @@ -147,11 +147,11 @@ extension UnauthorizedAccountTermsOfService { public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable { case empty case phoneEntry(countryCode: Int32, number: String) - case confirmationCodeEntry(number: String, type: SentAuthorizationCodeType, hash: String, timeout: Int32?, nextType: AuthorizationCodeNextType?, termsOfService: (UnauthorizedAccountTermsOfService, Bool)?, syncContacts: Bool) + case confirmationCodeEntry(number: String, type: SentAuthorizationCodeType, hash: String, timeout: Int32?, nextType: AuthorizationCodeNextType?, syncContacts: Bool) case passwordEntry(hint: String, number: String?, code: String?, suggestReset: Bool, syncContacts: Bool) case passwordRecovery(hint: String, number: String?, code: String?, emailPattern: String, syncContacts: Bool) case awaitingAccountReset(protectedUntil: Int32, number: String?, syncContacts: Bool) - case signUp(number: String, codeHash: String, code: String, firstName: String, lastName: String, termsOfService: UnauthorizedAccountTermsOfService?, syncContacts: Bool) + case signUp(number: String, codeHash: String, firstName: String, lastName: String, termsOfService: UnauthorizedAccountTermsOfService?, syncContacts: Bool) public init(decoder: PostboxDecoder) { switch decoder.decodeInt32ForKey("v", orElse: 0) { @@ -164,11 +164,7 @@ public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable { if let value = decoder.decodeOptionalInt32ForKey("nt") { nextType = AuthorizationCodeNextType(rawValue: value) } - var termsOfService: (UnauthorizedAccountTermsOfService, Bool)? - if let termsValue = decoder.decodeObjectForKey("tos", decoder: { UnauthorizedAccountTermsOfService(decoder: $0) }) as? UnauthorizedAccountTermsOfService { - termsOfService = (termsValue, decoder.decodeInt32ForKey("tose", orElse: 0) != 0) - } - self = .confirmationCodeEntry(number: decoder.decodeStringForKey("num", orElse: ""), type: decoder.decodeObjectForKey("t", decoder: { SentAuthorizationCodeType(decoder: $0) }) as! SentAuthorizationCodeType, hash: decoder.decodeStringForKey("h", orElse: ""), timeout: decoder.decodeOptionalInt32ForKey("tm"), nextType: nextType, termsOfService: termsOfService, syncContacts: decoder.decodeInt32ForKey("syncContacts", orElse: 1) != 0) + self = .confirmationCodeEntry(number: decoder.decodeStringForKey("num", orElse: ""), type: decoder.decodeObjectForKey("t", decoder: { SentAuthorizationCodeType(decoder: $0) }) as! SentAuthorizationCodeType, hash: decoder.decodeStringForKey("h", orElse: ""), timeout: decoder.decodeOptionalInt32ForKey("tm"), nextType: nextType, syncContacts: decoder.decodeInt32ForKey("syncContacts", orElse: 1) != 0) case UnauthorizedAccountStateContentsValue.passwordEntry.rawValue: self = .passwordEntry(hint: decoder.decodeStringForKey("h", orElse: ""), number: decoder.decodeOptionalStringForKey("n"), code: decoder.decodeOptionalStringForKey("c"), suggestReset: decoder.decodeInt32ForKey("suggestReset", orElse: 0) != 0, syncContacts: decoder.decodeInt32ForKey("syncContacts", orElse: 1) != 0) case UnauthorizedAccountStateContentsValue.passwordRecovery.rawValue: @@ -176,7 +172,7 @@ public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable { case UnauthorizedAccountStateContentsValue.awaitingAccountReset.rawValue: self = .awaitingAccountReset(protectedUntil: decoder.decodeInt32ForKey("protectedUntil", orElse: 0), number: decoder.decodeOptionalStringForKey("number"), syncContacts: decoder.decodeInt32ForKey("syncContacts", orElse: 1) != 0) case UnauthorizedAccountStateContentsValue.signUp.rawValue: - self = .signUp(number: decoder.decodeStringForKey("n", orElse: ""), codeHash: decoder.decodeStringForKey("h", orElse: ""), code: decoder.decodeStringForKey("c", orElse: ""), firstName: decoder.decodeStringForKey("f", orElse: ""), lastName: decoder.decodeStringForKey("l", orElse: ""), termsOfService: decoder.decodeObjectForKey("tos", decoder: { UnauthorizedAccountTermsOfService(decoder: $0) }) as? UnauthorizedAccountTermsOfService, syncContacts: decoder.decodeInt32ForKey("syncContacts", orElse: 1) != 0) + self = .signUp(number: decoder.decodeStringForKey("n", orElse: ""), codeHash: decoder.decodeStringForKey("h", orElse: ""), firstName: decoder.decodeStringForKey("f", orElse: ""), lastName: decoder.decodeStringForKey("l", orElse: ""), termsOfService: decoder.decodeObjectForKey("tos", decoder: { UnauthorizedAccountTermsOfService(decoder: $0) }) as? UnauthorizedAccountTermsOfService, syncContacts: decoder.decodeInt32ForKey("syncContacts", orElse: 1) != 0) default: assertionFailure() self = .empty @@ -191,7 +187,7 @@ public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable { encoder.encodeInt32(UnauthorizedAccountStateContentsValue.phoneEntry.rawValue, forKey: "v") encoder.encodeInt32(countryCode, forKey: "cc") encoder.encodeString(number, forKey: "n") - case let .confirmationCodeEntry(number, type, hash, timeout, nextType, termsOfService, syncContacts): + case let .confirmationCodeEntry(number, type, hash, timeout, nextType, syncContacts): encoder.encodeInt32(UnauthorizedAccountStateContentsValue.confirmationCodeEntry.rawValue, forKey: "v") encoder.encodeString(number, forKey: "num") encoder.encodeObject(type, forKey: "t") @@ -206,12 +202,6 @@ public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable { } else { encoder.encodeNil(forKey: "nt") } - if let (termsOfService, exclusive) = termsOfService { - encoder.encodeObject(termsOfService, forKey: "tos") - encoder.encodeInt32(exclusive ? 1 : 0, forKey: "tose") - } else { - encoder.encodeNil(forKey: "tos") - } encoder.encodeInt32(syncContacts ? 1 : 0, forKey: "syncContacts") case let .passwordEntry(hint, number, code, suggestReset, syncContacts): encoder.encodeInt32(UnauthorizedAccountStateContentsValue.passwordEntry.rawValue, forKey: "v") @@ -252,11 +242,10 @@ public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable { encoder.encodeNil(forKey: "number") } encoder.encodeInt32(syncContacts ? 1 : 0, forKey: "syncContacts") - case let .signUp(number, codeHash, code, firstName, lastName, termsOfService, syncContacts): + case let .signUp(number, codeHash, firstName, lastName, termsOfService, syncContacts): encoder.encodeInt32(UnauthorizedAccountStateContentsValue.signUp.rawValue, forKey: "v") encoder.encodeString(number, forKey: "n") encoder.encodeString(codeHash, forKey: "h") - encoder.encodeString(code, forKey: "c") encoder.encodeString(firstName, forKey: "f") encoder.encodeString(lastName, forKey: "l") if let termsOfService = termsOfService { @@ -282,8 +271,8 @@ public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable { } else { return false } - case let .confirmationCodeEntry(lhsNumber, lhsType, lhsHash, lhsTimeout, lhsNextType, lhsTermsOfService, lhsSyncContacts): - if case let .confirmationCodeEntry(rhsNumber, rhsType, rhsHash, rhsTimeout, rhsNextType, rhsTermsOfService, rhsSyncContacts) = rhs { + case let .confirmationCodeEntry(lhsNumber, lhsType, lhsHash, lhsTimeout, lhsNextType, lhsSyncContacts): + if case let .confirmationCodeEntry(rhsNumber, rhsType, rhsHash, rhsTimeout, rhsNextType, rhsSyncContacts) = rhs { if lhsNumber != rhsNumber { return false } @@ -299,12 +288,6 @@ public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable { if lhsNextType != rhsNextType { return false } - if lhsTermsOfService?.0 != rhsTermsOfService?.0 { - return false - } - if lhsTermsOfService?.1 != rhsTermsOfService?.1 { - return false - } if lhsSyncContacts != rhsSyncContacts { return false } @@ -330,8 +313,8 @@ public enum UnauthorizedAccountStateContents: PostboxCoding, Equatable { } else { return false } - case let .signUp(number, codeHash, code, firstName, lastName, termsOfService, syncContacts): - if case .signUp(number, codeHash, code, firstName, lastName, termsOfService, syncContacts) = rhs { + case let .signUp(number, codeHash, firstName, lastName, termsOfService, syncContacts): + if case .signUp(number, codeHash, firstName, lastName, termsOfService, syncContacts) = rhs { return true } else { return false diff --git a/submodules/TelegramCore/TelegramCore/AddPeerMember.swift b/submodules/TelegramCore/TelegramCore/AddPeerMember.swift index 2a105a78a4..446c878aee 100644 --- a/submodules/TelegramCore/TelegramCore/AddPeerMember.swift +++ b/submodules/TelegramCore/TelegramCore/AddPeerMember.swift @@ -91,10 +91,10 @@ public func addChannelMember(account: Account, peerId: PeerId, memberId: PeerId) if let peer = transaction.getPeer(peerId), let memberPeer = transaction.getPeer(memberId), let inputUser = apiInputUser(memberPeer) { if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) { let updatedParticipant: ChannelParticipant - if let currentParticipant = currentParticipant, case let .member(_, invitedAt, adminInfo, _) = currentParticipant { - updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: invitedAt, adminInfo: adminInfo, banInfo: nil) + if let currentParticipant = currentParticipant, case let .member(_, invitedAt, adminInfo, _, rank) = currentParticipant { + updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: invitedAt, adminInfo: adminInfo, banInfo: nil, rank: rank) } else { - updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: nil, banInfo: nil) + updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: nil, banInfo: nil, rank: nil) } return account.network.request(Api.functions.channels.inviteToChannel(channel: inputChannel, users: [inputUser])) |> map { [$0] } @@ -131,7 +131,7 @@ public func addChannelMember(account: Account, peerId: PeerId, memberId: PeerId) switch currentParticipant { case .creator: break - case let .member(_, _, _, banInfo): + case let .member(_, _, _, banInfo, _): if let banInfo = banInfo { wasBanned = true wasMember = !banInfo.rights.flags.contains(.banReadMessages) @@ -158,7 +158,7 @@ public func addChannelMember(account: Account, peerId: PeerId, memberId: PeerId) if let presence = transaction.getPeerPresence(peerId: memberPeer.id) { presences[memberPeer.id] = presence } - if case let .member(_, _, maybeAdminInfo, maybeBannedInfo) = updatedParticipant { + if case let .member(_, _, maybeAdminInfo, maybeBannedInfo, _) = updatedParticipant { if let adminInfo = maybeAdminInfo { if let peer = transaction.getPeer(adminInfo.promotedBy) { peers[peer.id] = peer diff --git a/submodules/TelegramCore/TelegramCore/ApiGroupOrChannel.swift b/submodules/TelegramCore/TelegramCore/ApiGroupOrChannel.swift index 02e1cbf52f..268792417f 100644 --- a/submodules/TelegramCore/TelegramCore/ApiGroupOrChannel.swift +++ b/submodules/TelegramCore/TelegramCore/ApiGroupOrChannel.swift @@ -47,9 +47,9 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? { var groupFlags = TelegramGroupFlags() var role: TelegramGroupRole = .member if (flags & (1 << 0)) != 0 { - role = .creator + role = .creator(rank: nil) } else if let adminRights = adminRights { - role = .admin(TelegramChatAdminRights(apiAdminRights: adminRights)) + role = .admin(TelegramChatAdminRights(apiAdminRights: adminRights), rank: nil) } if (flags & (1 << 5)) != 0 { groupFlags.insert(.deactivated) diff --git a/submodules/TelegramCore/TelegramCore/Authorization.swift b/submodules/TelegramCore/TelegramCore/Authorization.swift index 8f7b39bd21..e2b25d5ca5 100644 --- a/submodules/TelegramCore/TelegramCore/Authorization.swift +++ b/submodules/TelegramCore/TelegramCore/Authorization.swift @@ -83,22 +83,12 @@ public func sendAuthorizationCode(accountManager: AccountManager, account: Unaut |> mapToSignal { (sentCode, account) -> Signal in return account.postbox.transaction { transaction -> UnauthorizedAccount in switch sentCode { - case let .sentCode(_, type, phoneCodeHash, nextType, timeout, termsOfService): + case let .sentCode(_, type, phoneCodeHash, nextType, timeout): var parsedNextType: AuthorizationCodeNextType? if let nextType = nextType { parsedNextType = AuthorizationCodeNextType(apiType: nextType) } - var explicitTerms = false - if let termsOfService = termsOfService { - switch termsOfService { - case let .termsOfService(value): - if (value.flags & (1 << 0)) != 0 { - explicitTerms = true - } - } - } - - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: phoneNumber, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, termsOfService: termsOfService.flatMap(UnauthorizedAccountTermsOfService.init(apiTermsOfService:)).flatMap({ ($0, explicitTerms) }), syncContacts: syncContacts))) + transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: phoneNumber, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, syncContacts: syncContacts))) } return account } @@ -112,47 +102,35 @@ public func resendAuthorizationCode(account: UnauthorizedAccount) -> Signal Signal in if let state = transaction.getState() as? UnauthorizedAccountState { switch state.contents { - case let .confirmationCodeEntry(number, _, hash, _, nextType, _, syncContacts): + case let .confirmationCodeEntry(number, _, hash, _, nextType, syncContacts): if nextType != nil { return account.network.request(Api.functions.auth.resendCode(phoneNumber: number, phoneCodeHash: hash), automaticFloodWait: false) - |> mapError { error -> AuthorizationCodeRequestError in - if error.errorDescription.hasPrefix("FLOOD_WAIT") { - return .limitExceeded - } else if error.errorDescription == "PHONE_NUMBER_INVALID" { - return .invalidPhoneNumber - } else if error.errorDescription == "PHONE_NUMBER_FLOOD" { - return .phoneLimitExceeded - } else if error.errorDescription == "PHONE_NUMBER_BANNED" { - return .phoneBanned - } else { - return .generic(info: (Int(error.errorCode), error.errorDescription)) + |> mapError { error -> AuthorizationCodeRequestError in + if error.errorDescription.hasPrefix("FLOOD_WAIT") { + return .limitExceeded + } else if error.errorDescription == "PHONE_NUMBER_INVALID" { + return .invalidPhoneNumber + } else if error.errorDescription == "PHONE_NUMBER_FLOOD" { + return .phoneLimitExceeded + } else if error.errorDescription == "PHONE_NUMBER_BANNED" { + return .phoneBanned + } else { + return .generic(info: (Int(error.errorCode), error.errorDescription)) + } + } + |> mapToSignal { sentCode -> Signal in + return account.postbox.transaction { transaction -> Void in + switch sentCode { + case let .sentCode(_, type, phoneCodeHash, nextType, timeout): + var parsedNextType: AuthorizationCodeNextType? + if let nextType = nextType { + parsedNextType = AuthorizationCodeNextType(apiType: nextType) + } + transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: number, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, syncContacts: syncContacts))) + } - } - |> mapToSignal { sentCode -> Signal in - return account.postbox.transaction { transaction -> Void in - switch sentCode { - case let .sentCode(_, type, phoneCodeHash, nextType, timeout, termsOfService): - - var parsedNextType: AuthorizationCodeNextType? - if let nextType = nextType { - parsedNextType = AuthorizationCodeNextType(apiType: nextType) - } - - var explicitTerms = false - if let termsOfService = termsOfService { - switch termsOfService { - case let .termsOfService(value): - if (value.flags & (1 << 0)) != 0 { - explicitTerms = true - } - } - } - - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .confirmationCodeEntry(number: number, type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType, termsOfService: termsOfService.flatMap(UnauthorizedAccountTermsOfService.init(apiTermsOfService:)).flatMap({ ($0, explicitTerms) }), syncContacts: syncContacts))) - - } - } |> mapError { _ -> AuthorizationCodeRequestError in return .generic(info: nil) } - } + } |> mapError { _ -> AuthorizationCodeRequestError in return .generic(info: nil) } + } } else { return .fail(.generic(info: nil)) } @@ -195,11 +173,11 @@ public enum AuthorizeWithCodeResult { case loggedIn } -public func authorizeWithCode(accountManager: AccountManager, account: UnauthorizedAccount, code: String, termsOfService: UnauthorizedAccountTermsOfService?) -> Signal { +public func authorizeWithCode(accountManager: AccountManager, account: UnauthorizedAccount, code: String) -> Signal { return account.postbox.transaction { transaction -> Signal in if let state = transaction.getState() as? UnauthorizedAccountState { switch state.contents { - case let .confirmationCodeEntry(number, _, hash, _, _, _, syncContacts): + case let .confirmationCodeEntry(number, _, hash, _, _, syncContacts): return account.network.request(Api.functions.auth.signIn(phoneNumber: number, phoneCodeHash: hash, phoneCode: code), automaticFloodWait: false) |> map { authorization in return .authorization(authorization) @@ -239,7 +217,7 @@ public func authorizeWithCode(accountManager: AccountManager, account: Unauthori return account.postbox.transaction { transaction -> Signal in switch result { case .signUp: - return .single(.signUp(AuthorizationSignUpData(number: number, codeHash: hash, code: code, termsOfService: termsOfService, syncContacts: syncContacts))) + return .single(.signUp(AuthorizationSignUpData(number: number, codeHash: hash, code: code, termsOfService: nil, syncContacts: syncContacts))) case let .password(hint): transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code, suggestReset: false, syncContacts: syncContacts))) return .single(.loggedIn) @@ -250,6 +228,17 @@ public func authorizeWithCode(accountManager: AccountManager, account: Unauthori let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil) initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts) transaction.setState(state) + case let .authorizationSignUpRequired(flags, termsOfService): + var explicitTerms = false + if let termsOfService = termsOfService { + switch termsOfService { + case let .termsOfService(value): + if (value.flags & (1 << 0)) != 0 { + explicitTerms = true + } + } + } + return .single(.signUp(AuthorizationSignUpData(number: number, codeHash: hash, code: code, termsOfService: termsOfService.flatMap(UnauthorizedAccountTermsOfService.init(apiTermsOfService:)), syncContacts: syncContacts))) } return accountManager.transaction { transaction -> AuthorizeWithCodeResult in switchToAuthorizedAccount(transaction: transaction, account: account) @@ -277,7 +266,7 @@ public func authorizeWithCode(accountManager: AccountManager, account: Unauthori public func beginSignUp(account: UnauthorizedAccount, data: AuthorizationSignUpData) -> Signal { return account.postbox.transaction { transaction -> Void in - transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .signUp(number: data.number, codeHash: data.codeHash, code: data.code, firstName: "", lastName: "", termsOfService: data.termsOfService, syncContacts: data.syncContacts))) + transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .signUp(number: data.number, codeHash: data.codeHash, firstName: "", lastName: "", termsOfService: data.termsOfService, syncContacts: data.syncContacts))) } |> ignoreValues } @@ -314,7 +303,9 @@ public func authorizeWithPassword(accountManager: AccountManager, account: Unaut return accountManager.transaction { transaction -> Void in switchToAuthorizedAccount(transaction: transaction, account: account) } - } + case .authorizationSignUpRequired: + return .never() + } } |> switchToLatest |> mapError { _ -> AuthorizationPasswordVerificationError in @@ -380,14 +371,13 @@ public func performPasswordRecovery(accountManager: AccountManager, account: Una case let .authorization(_, _, user): let user = TelegramUser(user: user) let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil) - /*transaction.updatePeersInternal([user], update: { current, peer -> Peer? in - return peer - })*/ initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts) transaction.setState(state) return accountManager.transaction { transaction -> Void in switchToAuthorizedAccount(transaction: transaction, account: account) } + case .authorizationSignUpRequired: + return .never() } } |> switchToLatest @@ -454,8 +444,8 @@ public enum SignUpError { public func signUpWithName(accountManager: AccountManager, account: UnauthorizedAccount, firstName: String, lastName: String, avatarData: Data?) -> Signal { return account.postbox.transaction { transaction -> Signal in - if let state = transaction.getState() as? UnauthorizedAccountState, case let .signUp(number, codeHash, code, _, _, _, syncContacts) = state.contents { - return account.network.request(Api.functions.auth.signUp(phoneNumber: number, phoneCodeHash: codeHash, phoneCode: code, firstName: firstName, lastName: lastName)) + if let state = transaction.getState() as? UnauthorizedAccountState, case let .signUp(number, codeHash, _, _, _, syncContacts) = state.contents { + return account.network.request(Api.functions.auth.signUp(phoneNumber: number, phoneCodeHash: codeHash, firstName: firstName, lastName: lastName)) |> mapError { error -> SignUpError in if error.errorDescription.hasPrefix("FLOOD_WAIT") { return .limitExceeded @@ -510,6 +500,8 @@ public func signUpWithName(accountManager: AccountManager, account: Unauthorized return appliedState |> then(switchedAccounts) } + case .authorizationSignUpRequired: + return .fail(.generic) } } } else { diff --git a/submodules/TelegramCore/TelegramCore/BotPaymentForm.swift b/submodules/TelegramCore/TelegramCore/BotPaymentForm.swift index c65afa122f..42b74c0c63 100644 --- a/submodules/TelegramCore/TelegramCore/BotPaymentForm.swift +++ b/submodules/TelegramCore/TelegramCore/BotPaymentForm.swift @@ -372,7 +372,7 @@ public func sendBotPaymentForm(account: Account, messageId: MessageId, validated case let .paymentResult(updates): account.stateManager.addUpdates(updates) return .done - case let .paymentVerficationNeeded(url): + case let .paymentVerificationNeeded(url): return .externalVerificationRequired(url: url) } } diff --git a/submodules/TelegramCore/TelegramCore/CachedChannelParticipants.swift b/submodules/TelegramCore/TelegramCore/CachedChannelParticipants.swift index 1a1d855829..6a8e4d1f44 100644 --- a/submodules/TelegramCore/TelegramCore/CachedChannelParticipants.swift +++ b/submodules/TelegramCore/TelegramCore/CachedChannelParticipants.swift @@ -75,22 +75,31 @@ public struct ChannelParticipantBannedInfo: PostboxCoding, Equatable { } public enum ChannelParticipant: PostboxCoding, Equatable { - case creator(id: PeerId) - case member(id: PeerId, invitedAt: Int32, adminInfo: ChannelParticipantAdminInfo?, banInfo: ChannelParticipantBannedInfo?) + case creator(id: PeerId, rank: String?) + case member(id: PeerId, invitedAt: Int32, adminInfo: ChannelParticipantAdminInfo?, banInfo: ChannelParticipantBannedInfo?, rank: String?) public var peerId: PeerId { switch self { - case let .creator(id): + case let .creator(id, _): return id - case let .member(id, _, _, _): + case let .member(id, _, _, _, _): return id } } + public var rank: String? { + switch self { + case let .creator(_, rank): + return rank + case let .member(_, _, _, _, rank): + return rank + } + } + public static func ==(lhs: ChannelParticipant, rhs: ChannelParticipant) -> Bool { switch lhs { - case let .member(lhsId, lhsInvitedAt, lhsAdminInfo, lhsBanInfo): - if case let .member(rhsId, rhsInvitedAt, rhsAdminInfo, rhsBanInfo) = rhs { + case let .member(lhsId, lhsInvitedAt, lhsAdminInfo, lhsBanInfo, lhsRank): + if case let .member(rhsId, rhsInvitedAt, rhsAdminInfo, rhsBanInfo, rhsRank) = rhs { if lhsId != rhsId { return false } @@ -103,12 +112,15 @@ public enum ChannelParticipant: PostboxCoding, Equatable { if lhsBanInfo != rhsBanInfo { return false } + if lhsRank != rhsRank { + return false + } return true } else { return false } - case let .creator(id): - if case .creator(id) = rhs { + case let .creator(id, rank): + if case .creator(id, rank) = rhs { return true } else { return false @@ -119,17 +131,17 @@ public enum ChannelParticipant: PostboxCoding, Equatable { public init(decoder: PostboxDecoder) { switch decoder.decodeInt32ForKey("r", orElse: 0) { case ChannelParticipantValue.member.rawValue: - self = .member(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0), adminInfo: decoder.decodeObjectForKey("ai", decoder: { ChannelParticipantAdminInfo(decoder: $0) }) as? ChannelParticipantAdminInfo, banInfo: decoder.decodeObjectForKey("bi", decoder: { ChannelParticipantBannedInfo(decoder: $0) }) as? ChannelParticipantBannedInfo) + self = .member(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0), adminInfo: decoder.decodeObjectForKey("ai", decoder: { ChannelParticipantAdminInfo(decoder: $0) }) as? ChannelParticipantAdminInfo, banInfo: decoder.decodeObjectForKey("bi", decoder: { ChannelParticipantBannedInfo(decoder: $0) }) as? ChannelParticipantBannedInfo, rank: decoder.decodeOptionalStringForKey("rank")) case ChannelParticipantValue.creator.rawValue: - self = .creator(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0))) + self = .creator(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), rank: decoder.decodeOptionalStringForKey("rank")) default: - self = .member(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0), adminInfo: nil, banInfo: nil) + self = .member(id: PeerId(decoder.decodeInt64ForKey("i", orElse: 0)), invitedAt: decoder.decodeInt32ForKey("t", orElse: 0), adminInfo: nil, banInfo: nil, rank: nil) } } public func encode(_ encoder: PostboxEncoder) { switch self { - case let .member(id, invitedAt, adminInfo, banInfo): + case let .member(id, invitedAt, adminInfo, banInfo, rank): encoder.encodeInt32(ChannelParticipantValue.member.rawValue, forKey: "r") encoder.encodeInt64(id.toInt64(), forKey: "i") encoder.encodeInt32(invitedAt, forKey: "t") @@ -143,9 +155,19 @@ public enum ChannelParticipant: PostboxCoding, Equatable { } else { encoder.encodeNil(forKey: "bi") } - case let .creator(id): + if let rank = rank { + encoder.encodeString(rank, forKey: "rank") + } else { + encoder.encodeNil(forKey: "rank") + } + case let .creator(id, rank): encoder.encodeInt32(ChannelParticipantValue.creator.rawValue, forKey: "r") encoder.encodeInt64(id.toInt64(), forKey: "i") + if let rank = rank { + encoder.encodeString(rank, forKey: "rank") + } else { + encoder.encodeNil(forKey: "rank") + } } } } @@ -175,17 +197,17 @@ extension ChannelParticipant { init(apiParticipant: Api.ChannelParticipant) { switch apiParticipant { case let .channelParticipant(userId, date): - self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: nil, banInfo: nil) - case let .channelParticipantCreator(userId): - self = .creator(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId)) + self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil) + case let .channelParticipantCreator(_, userId, rank): + self = .creator(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), rank: rank) case let .channelParticipantBanned(flags, userId, restrictedBy, date, bannedRights): let hasLeft = (flags & (1 << 0)) != 0 let banInfo = ChannelParticipantBannedInfo(rights: TelegramChatBannedRights(apiBannedRights: bannedRights), restrictedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: restrictedBy), timestamp: date, isMember: !hasLeft) - self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: nil, banInfo: banInfo) - case let .channelParticipantAdmin(flags, userId, _, promotedBy, date, adminRights): - self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: promotedBy), canBeEditedByAccountPeer: (flags & (1 << 0)) != 0), banInfo: nil) + self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: nil, banInfo: banInfo, rank: nil) + case let .channelParticipantAdmin(flags, userId, _, promotedBy, date, adminRights, rank: rank): + self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(apiAdminRights: adminRights), promotedBy: PeerId(namespace: Namespaces.Peer.CloudUser, id: promotedBy), canBeEditedByAccountPeer: (flags & (1 << 0)) != 0), banInfo: nil, rank: rank) case let .channelParticipantSelf(userId, _, date): - self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: nil, banInfo: nil) + self = .member(id: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId), invitedAt: date, adminInfo: nil, banInfo: nil, rank: nil) } } } diff --git a/submodules/TelegramCore/TelegramCore/CancelAccountReset.swift b/submodules/TelegramCore/TelegramCore/CancelAccountReset.swift index b467f434e1..4f1f717116 100644 --- a/submodules/TelegramCore/TelegramCore/CancelAccountReset.swift +++ b/submodules/TelegramCore/TelegramCore/CancelAccountReset.swift @@ -38,7 +38,7 @@ public func requestCancelAccountResetData(network: Network, hash: String) -> Sig } |> map { sentCode -> CancelAccountResetData in switch sentCode { - case let .sentCode(_, type, phoneCodeHash, nextType, timeout, _): + case let .sentCode(_, type, phoneCodeHash, nextType, timeout): var parsedNextType: AuthorizationCodeNextType? if let nextType = nextType { parsedNextType = AuthorizationCodeNextType(apiType: nextType) @@ -59,7 +59,7 @@ public func requestNextCancelAccountResetOption(network: Network, phoneNumber: S } |> map { sentCode -> CancelAccountResetData in switch sentCode { - case let .sentCode(_, type, phoneCodeHash, nextType, timeout, _): + case let .sentCode(_, type, phoneCodeHash, nextType, timeout): var parsedNextType: AuthorizationCodeNextType? if let nextType = nextType { parsedNextType = AuthorizationCodeNextType(apiType: nextType) diff --git a/submodules/TelegramCore/TelegramCore/ChangeAccountPhoneNumber.swift b/submodules/TelegramCore/TelegramCore/ChangeAccountPhoneNumber.swift index 87ae6c73e1..46fca165d0 100644 --- a/submodules/TelegramCore/TelegramCore/ChangeAccountPhoneNumber.swift +++ b/submodules/TelegramCore/TelegramCore/ChangeAccountPhoneNumber.swift @@ -60,7 +60,7 @@ public func requestChangeAccountPhoneNumberVerification(account: Account, phoneN } |> map { sentCode -> ChangeAccountPhoneNumberData in switch sentCode { - case let .sentCode(_, type, phoneCodeHash, nextType, timeout, _): + case let .sentCode(_, type, phoneCodeHash, nextType, timeout): var parsedNextType: AuthorizationCodeNextType? if let nextType = nextType { parsedNextType = AuthorizationCodeNextType(apiType: nextType) @@ -85,7 +85,7 @@ public func requestNextChangeAccountPhoneNumberVerification(account: Account, ph } |> map { sentCode -> ChangeAccountPhoneNumberData in switch sentCode { - case let .sentCode(_, type, phoneCodeHash, nextType, timeout, _): + case let .sentCode(_, type, phoneCodeHash, nextType, timeout): var parsedNextType: AuthorizationCodeNextType? if let nextType = nextType { parsedNextType = AuthorizationCodeNextType(apiType: nextType) diff --git a/submodules/TelegramCore/TelegramCore/ChannelAdmins.swift b/submodules/TelegramCore/TelegramCore/ChannelAdmins.swift index 016ad4d7ca..db7ce8ed64 100644 --- a/submodules/TelegramCore/TelegramCore/ChannelAdmins.swift +++ b/submodules/TelegramCore/TelegramCore/ChannelAdmins.swift @@ -72,9 +72,9 @@ public func channelAdminIds(postbox: Postbox, network: Network, peerId: PeerId, let users = users.filter({ user in return participants.contains(where: { participant in switch participant { - case let .channelParticipantAdmin(_, userId, _, _, _, _): + case let .channelParticipantAdmin(_, userId, _, _, _, _, _): return user.peerId.id == userId - case let .channelParticipantCreator(userId): + case let .channelParticipantCreator(_, userId, _): return user.peerId.id == userId default: return false diff --git a/submodules/TelegramCore/TelegramCore/ChannelBlacklist.swift b/submodules/TelegramCore/TelegramCore/ChannelBlacklist.swift index 9a7ec28554..d050e0374c 100644 --- a/submodules/TelegramCore/TelegramCore/ChannelBlacklist.swift +++ b/submodules/TelegramCore/TelegramCore/ChannelBlacklist.swift @@ -101,7 +101,7 @@ public struct ChannelBlacklist { var updatedRestricted = updated.restricted var updatedBanned = updated.banned - if case .member(_, _, _, let maybeBanInfo) = participant.participant, let banInfo = maybeBanInfo { + if case let .member(_, _, _, maybeBanInfo, _) = participant.participant, let banInfo = maybeBanInfo { if banInfo.rights.flags.contains(.banReadMessages) { updatedBanned.insert(participant, at: 0) } else { @@ -144,14 +144,14 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me return account.postbox.transaction { transaction -> Signal<(ChannelParticipant?, RenderedChannelParticipant?, Bool), NoError> in if let peer = transaction.getPeer(peerId), let inputChannel = apiInputChannel(peer), let _ = transaction.getPeer(account.peerId), let memberPeer = transaction.getPeer(memberId), let inputUser = apiInputUser(memberPeer) { let updatedParticipant: ChannelParticipant - if let currentParticipant = currentParticipant, case let .member(_, invitedAt, _, currentBanInfo) = currentParticipant { + if let currentParticipant = currentParticipant, case let .member(_, invitedAt, _, currentBanInfo, _) = currentParticipant { let banInfo: ChannelParticipantBannedInfo? if let rights = rights, !rights.flags.isEmpty { banInfo = ChannelParticipantBannedInfo(rights: rights, restrictedBy: currentBanInfo?.restrictedBy ?? account.peerId, timestamp: currentBanInfo?.timestamp ?? Int32(Date().timeIntervalSince1970), isMember: currentBanInfo?.isMember ?? true) } else { banInfo = nil } - updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: invitedAt, adminInfo: nil, banInfo: banInfo) + updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: invitedAt, adminInfo: nil, banInfo: banInfo, rank: nil) } else { let banInfo: ChannelParticipantBannedInfo? if let rights = rights, !rights.flags.isEmpty { @@ -159,7 +159,7 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me } else { banInfo = nil } - updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: nil, banInfo: banInfo) + updatedParticipant = ChannelParticipant.member(id: memberId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: nil, banInfo: banInfo, rank: nil) } return account.network.request(Api.functions.channels.editBanned(channel: inputChannel, userId: inputUser, bannedRights: rights?.apiBannedRights ?? Api.ChatBannedRights.chatBannedRights(flags: 0, untilDate: 0))) @@ -175,7 +175,7 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me switch currentParticipant { case .creator: break - case let .member(_, _, adminInfo, banInfo): + case let .member(_, _, adminInfo, banInfo, _): if let _ = adminInfo { wasAdmin = true } @@ -243,7 +243,7 @@ public func updateChannelMemberBannedRights(account: Account, peerId: PeerId, me if let presence = transaction.getPeerPresence(peerId: memberPeer.id) { presences[memberPeer.id] = presence } - if case let .member(_, _, _, maybeBanInfo) = updatedParticipant, let banInfo = maybeBanInfo { + if case let .member(_, _, _, maybeBanInfo, _) = updatedParticipant, let banInfo = maybeBanInfo { if let peer = transaction.getPeer(banInfo.restrictedBy) { peers[peer.id] = peer } diff --git a/submodules/TelegramCore/TelegramCore/ChannelOwnershipTransfer.swift b/submodules/TelegramCore/TelegramCore/ChannelOwnershipTransfer.swift index f942cf3d56..24a07b3992 100644 --- a/submodules/TelegramCore/TelegramCore/ChannelOwnershipTransfer.swift +++ b/submodules/TelegramCore/TelegramCore/ChannelOwnershipTransfer.swift @@ -96,9 +96,9 @@ public func updateChannelOwnership(account: Account, accountStateManager: Accoun } else { flags = TelegramChatAdminRightsFlags.groupSpecific } - - let updatedParticipant = ChannelParticipant.creator(id: user.id) - let updatedPreviousCreator = ChannelParticipant.member(id: accountUser.id, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: flags), promotedBy: accountUser.id, canBeEditedByAccountPeer: false), banInfo: nil) + + let updatedParticipant = ChannelParticipant.creator(id: user.id, rank: currentParticipant?.rank) + let updatedPreviousCreator = ChannelParticipant.member(id: accountUser.id, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: flags), promotedBy: accountUser.id, canBeEditedByAccountPeer: false), banInfo: nil, rank: currentCreator?.rank) let checkPassword = twoStepAuthData(account.network) |> mapError { error -> ChannelOwnershipTransferError in @@ -164,7 +164,7 @@ public func updateChannelOwnership(account: Account, accountStateManager: Accoun switch currentParticipant { case .creator: wasAdmin = true - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if let adminInfo = adminInfo, !adminInfo.rights.isEmpty { wasAdmin = true } diff --git a/submodules/TelegramCore/TelegramCore/JoinChannel.swift b/submodules/TelegramCore/TelegramCore/JoinChannel.swift index 04d010de19..a1117e818d 100644 --- a/submodules/TelegramCore/TelegramCore/JoinChannel.swift +++ b/submodules/TelegramCore/TelegramCore/JoinChannel.swift @@ -55,7 +55,7 @@ public func joinChannel(account: Account, peerId: PeerId) -> Signal switchToLatest } -public func updateChannelAdminRights(account: Account, peerId: PeerId, adminId: PeerId, rights: TelegramChatAdminRights) -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdateChannelAdminRightsError> { +public func updateChannelAdminRights(account: Account, peerId: PeerId, adminId: PeerId, rights: TelegramChatAdminRights, rank: String?) -> Signal<(ChannelParticipant?, RenderedChannelParticipant), UpdateChannelAdminRightsError> { return fetchChannelParticipant(account: account, peerId: peerId, participantId: adminId) |> mapError { error -> UpdateChannelAdminRightsError in return .generic @@ -207,14 +207,14 @@ public func updateChannelAdminRights(account: Account, peerId: PeerId, adminId: if let peer = transaction.getPeer(peerId), let adminPeer = transaction.getPeer(adminId), let inputUser = apiInputUser(adminPeer) { if let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) { let updatedParticipant: ChannelParticipant - if let currentParticipant = currentParticipant, case let .member(_, invitedAt, currentAdminInfo, _) = currentParticipant { + if let currentParticipant = currentParticipant, case let .member(_, invitedAt, currentAdminInfo, _, _) = currentParticipant { let adminInfo: ChannelParticipantAdminInfo? if !rights.flags.isEmpty { adminInfo = ChannelParticipantAdminInfo(rights: rights, promotedBy: currentAdminInfo?.promotedBy ?? account.peerId, canBeEditedByAccountPeer: true) } else { adminInfo = nil } - updatedParticipant = ChannelParticipant.member(id: adminId, invitedAt: invitedAt, adminInfo: adminInfo, banInfo: nil) + updatedParticipant = ChannelParticipant.member(id: adminId, invitedAt: invitedAt, adminInfo: adminInfo, banInfo: nil, rank: rank) } else { let adminInfo: ChannelParticipantAdminInfo? if !rights.flags.isEmpty { @@ -222,9 +222,9 @@ public func updateChannelAdminRights(account: Account, peerId: PeerId, adminId: } else { adminInfo = nil } - updatedParticipant = ChannelParticipant.member(id: adminId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: adminInfo, banInfo: nil) + updatedParticipant = ChannelParticipant.member(id: adminId, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: adminInfo, banInfo: nil, rank: rank) } - return account.network.request(Api.functions.channels.editAdmin(channel: inputChannel, userId: inputUser, adminRights: rights.apiAdminRights)) + return account.network.request(Api.functions.channels.editAdmin(channel: inputChannel, userId: inputUser, adminRights: rights.apiAdminRights, rank: rank ?? "")) |> map { [$0] } |> `catch` { error -> Signal<[Api.Updates], UpdateChannelAdminRightsError> in if error.errorDescription == "USER_NOT_PARTICIPANT" { @@ -235,10 +235,10 @@ public func updateChannelAdminRights(account: Account, peerId: PeerId, adminId: |> mapError { error -> UpdateChannelAdminRightsError in return .addMemberError(error) } - |> then(account.network.request(Api.functions.channels.editAdmin(channel: inputChannel, userId: inputUser, adminRights: rights.apiAdminRights)) - |> mapError { error -> UpdateChannelAdminRightsError in - return .generic - } + |> then(account.network.request(Api.functions.channels.editAdmin(channel: inputChannel, userId: inputUser, adminRights: rights.apiAdminRights, rank: rank ?? "")) + |> mapError { error -> UpdateChannelAdminRightsError in + return .generic + } |> map { [$0] }) } else if error.errorDescription == "USER_PRIVACY_RESTRICTED" { return .fail(.addMemberError(.restricted)) @@ -258,7 +258,7 @@ public func updateChannelAdminRights(account: Account, peerId: PeerId, adminId: switch currentParticipant { case .creator: wasAdmin = true - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if let adminInfo = adminInfo, !adminInfo.rights.isEmpty { wasAdmin = true } @@ -281,7 +281,7 @@ public func updateChannelAdminRights(account: Account, peerId: PeerId, adminId: if let presence = transaction.getPeerPresence(peerId: adminPeer.id) { presences[adminPeer.id] = presence } - if case let .member(_, _, maybeAdminInfo, _) = updatedParticipant, let adminInfo = maybeAdminInfo { + if case let .member(_, _, maybeAdminInfo, _, _) = updatedParticipant, let adminInfo = maybeAdminInfo { if let peer = transaction.getPeer(adminInfo.promotedBy) { peers[peer.id] = peer } diff --git a/submodules/TelegramCore/TelegramCore/TelegramGroup.swift b/submodules/TelegramCore/TelegramCore/TelegramGroup.swift index 16c1899da3..49d932e60e 100644 --- a/submodules/TelegramCore/TelegramCore/TelegramGroup.swift +++ b/submodules/TelegramCore/TelegramCore/TelegramGroup.swift @@ -6,16 +6,16 @@ import Foundation #endif public enum TelegramGroupRole: Equatable, PostboxCoding { - case creator - case admin(TelegramChatAdminRights) + case creator(rank: String?) + case admin(TelegramChatAdminRights, rank: String?) case member public init(decoder: PostboxDecoder) { switch decoder.decodeInt32ForKey("_v", orElse: 0) { case 0: - self = .creator + self = .creator(rank: decoder.decodeOptionalStringForKey("rank")) case 1: - self = .admin(decoder.decodeObjectForKey("r", decoder: { TelegramChatAdminRights(decoder: $0) }) as! TelegramChatAdminRights) + self = .admin(decoder.decodeObjectForKey("r", decoder: { TelegramChatAdminRights(decoder: $0) }) as! TelegramChatAdminRights, rank: decoder.decodeOptionalStringForKey("rank")) case 2: self = .member default: @@ -26,11 +26,21 @@ public enum TelegramGroupRole: Equatable, PostboxCoding { public func encode(_ encoder: PostboxEncoder) { switch self { - case .creator: + case let .creator(rank): encoder.encodeInt32(0, forKey: "_v") - case let .admin(rights): + if let rank = rank { + encoder.encodeString(rank, forKey: "rank") + } else { + encoder.encodeNil(forKey: "rank") + } + case let .admin(rights, rank): encoder.encodeInt32(1, forKey: "_v") encoder.encodeObject(rights, forKey: "r") + if let rank = rank { + encoder.encodeString(rank, forKey: "rank") + } else { + encoder.encodeNil(forKey: "rank") + } case .member: encoder.encodeInt32(2, forKey: "_v") } @@ -108,7 +118,7 @@ public final class TelegramGroup: Peer { if let role = decoder.decodeObjectForKey("rv", decoder: { TelegramGroupRole(decoder: $0) }) as? TelegramGroupRole { self.role = role } else if let roleValue = decoder.decodeOptionalInt32ForKey("r"), roleValue == 0 { - self.role = .creator + self.role = .creator(rank: nil) } else { self.role = .member } diff --git a/submodules/TelegramCore/TelegramCore/VerifySecureIdValue.swift b/submodules/TelegramCore/TelegramCore/VerifySecureIdValue.swift index f7d9a98ddb..79cb21e5a6 100644 --- a/submodules/TelegramCore/TelegramCore/VerifySecureIdValue.swift +++ b/submodules/TelegramCore/TelegramCore/VerifySecureIdValue.swift @@ -38,7 +38,7 @@ public func secureIdPreparePhoneVerification(network: Network, value: SecureIdPh } |> map { sentCode -> SecureIdPreparePhoneVerificationPayload in switch sentCode { - case let .sentCode(_, type, phoneCodeHash, nextType, timeout, _): + case let .sentCode(_, type, phoneCodeHash, nextType, timeout): return SecureIdPreparePhoneVerificationPayload(type: SentAuthorizationCodeType(apiType: type), nextType: nextType.flatMap(AuthorizationCodeNextType.init), timeout: timeout, phone: value.phone, phoneCodeHash: phoneCodeHash) } } diff --git a/submodules/TelegramPresentationData/Sources/PresentationData.swift b/submodules/TelegramPresentationData/Sources/PresentationData.swift index efca79ad2e..abb4963d98 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationData.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationData.swift @@ -253,7 +253,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager) - let parameters = AutomaticThemeSwitchParameters(settings: themeSettings.automaticThemeSwitchSetting) if automaticThemeShouldSwitchNow(parameters, currentTheme: themeSettings.theme) { - effectiveTheme = .builtin(themeSettings.automaticThemeSwitchSetting.theme) + effectiveTheme = themeSettings.themeTintColors ? .builtin(.nightAccent) : .builtin(.night) } else { effectiveTheme = themeSettings.theme } @@ -525,7 +525,7 @@ public func updatedPresentationData(accountManager: AccountManager, applicationI var effectiveChatWallpaper: TelegramWallpaper = currentWallpaper if shouldSwitch { - let automaticTheme = PresentationThemeReference.builtin(themeSettings.automaticThemeSwitchSetting.theme) + let automaticTheme: PresentationThemeReference = themeSettings.themeTintColors ? .builtin(.nightAccent) : .builtin(.night) if let themeSpecificWallpaper = themeSettings.themeSpecificChatWallpapers[automaticTheme.index] { effectiveChatWallpaper = themeSpecificWallpaper } diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceController.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceController.swift index d6e9fcf4b8..0643e7ea41 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequenceController.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequenceController.swift @@ -261,7 +261,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail if let strongSelf = self { controller?.inProgress = true - strongSelf.actionDisposable.set((authorizeWithCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, code: code, termsOfService: termsOfService?.0) + strongSelf.actionDisposable.set((authorizeWithCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, code: code) |> deliverOnMainQueue).start(next: { result in guard let strongSelf = self else { return @@ -721,13 +721,13 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } controllers.append(self.phoneEntryController(countryCode: countryCode, number: number)) self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty) - case let .confirmationCodeEntry(number, type, _, timeout, nextType, termsOfService, syncContacts): + case let .confirmationCodeEntry(number, type, _, timeout, nextType, syncContacts): var controllers: [ViewController] = [] if !self.otherAccountPhoneNumbers.1.isEmpty { controllers.append(self.splashController()) } controllers.append(self.phoneEntryController(countryCode: defaultCountryCode(), number: "")) - controllers.append(self.codeEntryController(number: number, type: type, nextType: nextType, timeout: timeout, termsOfService: termsOfService)) + controllers.append(self.codeEntryController(number: number, type: type, nextType: nextType, timeout: timeout, termsOfService: nil)) self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty) case let .passwordEntry(hint, _, _, suggestReset, syncContacts): var controllers: [ViewController] = [] @@ -750,7 +750,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } controllers.append(self.awaitingAccountResetController(protectedUntil: protectedUntil, number: number)) self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty) - case let .signUp(_, _, _, firstName, lastName, termsOfService, _): + case let .signUp(_, _, firstName, lastName, termsOfService, _): var controllers: [ViewController] = [] var displayCancel = false if !self.otherAccountPhoneNumbers.1.isEmpty { diff --git a/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift b/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift index c2063fc5e3..f11f281cae 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelAdminController.swift @@ -368,7 +368,7 @@ private func canEditAdminRights(accountPeerId: PeerId, channelView: PeerView, in switch initialParticipant { case .creator: return false - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if let adminInfo = adminInfo { return adminInfo.canBeEditedByAccountPeer || adminInfo.promotedBy == accountPeerId } else { @@ -447,7 +447,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s let currentRightsFlags: TelegramChatAdminRightsFlags if let updatedFlags = state.updatedFlags { currentRightsFlags = updatedFlags - } else if let initialParticipant = initialParticipant, case let .member(_, _, maybeAdminRights, _) = initialParticipant, let adminRights = maybeAdminRights { + } else if let initialParticipant = initialParticipant, case let .member(_, _, maybeAdminRights, _, _) = initialParticipant, let adminRights = maybeAdminRights { currentRightsFlags = adminRights.rights.flags } else { currentRightsFlags = accountUserRightsFlags.subtracting(.canAddAdmins) @@ -477,7 +477,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s switch initialParticipant { case .creator: break - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if let adminInfo = adminInfo { if adminInfo.promotedBy == accountPeerId || adminInfo.canBeEditedByAccountPeer { canDismiss = true @@ -489,7 +489,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s entries.append(.dismiss(presentationData.theme, presentationData.strings.Channel_Moderator_AccessLevelRevoke)) } } - } else if let initialParticipant = initialParticipant, case let .member(_, _, maybeAdminInfo, _) = initialParticipant, let adminInfo = maybeAdminInfo { + } else if let initialParticipant = initialParticipant, case let .member(_, _, maybeAdminInfo, _, _) = initialParticipant, let adminInfo = maybeAdminInfo { var index = 0 for right in rightsOrder { entries.append(.rightItem(presentationData.theme, index, stringForRight(strings: presentationData.strings, right: right, isGroup: isGroup, defaultBannedRights: channel.defaultBannedRights), right, adminInfo.rights.flags, adminInfo.rights.flags.contains(right), false)) @@ -517,7 +517,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s let currentRightsFlags: TelegramChatAdminRightsFlags if let updatedFlags = state.updatedFlags { currentRightsFlags = updatedFlags - } else if let initialParticipant = initialParticipant, case let .member(_, _, maybeAdminRights, _) = initialParticipant, let adminRights = maybeAdminRights { + } else if let initialParticipant = initialParticipant, case let .member(_, _, maybeAdminRights, _, _) = initialParticipant, let adminRights = maybeAdminRights { currentRightsFlags = adminRights.rights.flags.subtracting(.canAddAdmins) } else { currentRightsFlags = accountUserRightsFlags.subtracting(.canAddAdmins) @@ -535,7 +535,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s entries.append(.addAdminsInfo(presentationData.theme, currentRightsFlags.contains(.canAddAdmins) ? presentationData.strings.Channel_EditAdmin_PermissinAddAdminOn : presentationData.strings.Channel_EditAdmin_PermissinAddAdminOff)) } - if let admin = admin as? TelegramUser, admin.botInfo == nil && !admin.isDeleted && group.role == .creator && areAllAdminRightsEnabled(currentRightsFlags, group: true) { + if let admin = admin as? TelegramUser, case .creator = group.role, admin.botInfo == nil && !admin.isDeleted && areAllAdminRightsEnabled(currentRightsFlags, group: true) { entries.append(.transfer(presentationData.theme, presentationData.strings.Group_EditAdmin_TransferOwnership)) } @@ -624,7 +624,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi dismissImpl?() })) } else { - updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: [])) |> deliverOnMainQueue).start(error: { _ in + updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: []), rank: nil) |> deliverOnMainQueue).start(error: { _ in }, completed: { updated(TelegramChatAdminRights(flags: [])) @@ -706,7 +706,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi updateState { current in return current.withUpdatedUpdating(true) } - updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: updateFlags)) |> deliverOnMainQueue).start(error: { _ in + updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: updateFlags), rank: "") |> deliverOnMainQueue).start(error: { _ in }, completed: { updated(TelegramChatAdminRights(flags: updateFlags)) @@ -744,7 +744,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi updateState { current in return current.withUpdatedUpdating(true) } - updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: updateFlags)) |> deliverOnMainQueue).start(error: { error in + updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: updateFlags), rank: "") |> deliverOnMainQueue).start(error: { error in if case let .addMemberError(error) = error, case .restricted = error, let admin = adminView.peers[adminView.peerId] { var text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).0 if case .group = channel.info { @@ -798,7 +798,7 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi guard let upgradedPeerId = upgradedPeerId else { return .fail(.generic) } - return context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: upgradedPeerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: updateFlags)) + return context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: upgradedPeerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: updateFlags), rank: "") |> mapToSignal { _ -> Signal in return .complete() } diff --git a/submodules/TelegramUI/TelegramUI/ChannelAdminsController.swift b/submodules/TelegramUI/TelegramUI/ChannelAdminsController.swift index f64bf7025f..b833cec4e7 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelAdminsController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelAdminsController.swift @@ -203,7 +203,7 @@ private enum ChannelAdminsEntry: ItemListNodeEntry { case .creator: peerText = strings.Channel_Management_LabelOwner action = nil - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if let adminInfo = adminInfo { if let peer = participant.peers[adminInfo.promotedBy] { if peer.id == participant.peer.id { @@ -352,14 +352,14 @@ private func channelAdminsControllerEntries(presentationData: PresentationData, switch lhs.participant { case .creator: lhsInvitedAt = Int32.min - case let .member(_, invitedAt, _, _): + case let .member(_, invitedAt, _, _, _): lhsInvitedAt = invitedAt } let rhsInvitedAt: Int32 switch rhs.participant { case .creator: rhsInvitedAt = Int32.min - case let .member(_, invitedAt, _, _): + case let .member(_, invitedAt, _, _, _): rhsInvitedAt = invitedAt } return lhsInvitedAt < rhsInvitedAt @@ -369,7 +369,7 @@ private func channelAdminsControllerEntries(presentationData: PresentationData, switch participant.participant { case .creator: editable = false - case let .member(id, _, adminInfo, _): + case let .member(id, _, adminInfo, _, _): if id == accountPeerId { editable = false } else if let adminInfo = adminInfo { @@ -421,14 +421,14 @@ private func channelAdminsControllerEntries(presentationData: PresentationData, switch lhs.participant { case .creator: lhsInvitedAt = Int32.min - case let .member(_, invitedAt, _, _): + case let .member(_, invitedAt, _, _, _): lhsInvitedAt = invitedAt } let rhsInvitedAt: Int32 switch rhs.participant { case .creator: rhsInvitedAt = Int32.min - case let .member(_, invitedAt, _, _): + case let .member(_, invitedAt, _, _, _): rhsInvitedAt = invitedAt } return lhsInvitedAt < rhsInvitedAt @@ -438,11 +438,13 @@ private func channelAdminsControllerEntries(presentationData: PresentationData, switch participant.participant { case .creator: editable = false - case let .member(id, _, adminInfo, _): + case let .member(id, _, adminInfo, _, _): if id == accountPeerId { editable = false } else if let adminInfo = adminInfo { - if peer.role == .creator || adminInfo.promotedBy == accountPeerId { + if case .creator = peer.role { + editable = true + } else if adminInfo.promotedBy == accountPeerId { editable = true } else { editable = false @@ -540,7 +542,7 @@ public func channelAdminsController(context: AccountContext, peerId: PeerId, loa } })) } else { - removeAdminDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: [])) + removeAdminDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(flags: []), rank: nil) |> deliverOnMainQueue).start(completed: { updateState { return $0.withUpdatedRemovingPeerId(nil) @@ -563,7 +565,7 @@ public func channelAdminsController(context: AccountContext, peerId: PeerId, loa switch participant.participant { case .creator: return - case let .member(_, _, _, banInfo): + case let .member(_, _, _, banInfo, _): if let banInfo = banInfo { var canUnban = false if banInfo.restrictedBy != context.account.peerId { @@ -637,12 +639,12 @@ public func channelAdminsController(context: AccountContext, peerId: PeerId, loa if let peer = peerView.peers[participant.peerId] { switch participant { case .creator: - result.append(RenderedChannelParticipant(participant: .creator(id: peer.id), peer: peer)) + result.append(RenderedChannelParticipant(participant: .creator(id: peer.id, rank: nil), peer: peer)) case .admin: var peers: [PeerId: Peer] = [:] peers[creator.id] = creator peers[peer.id] = peer - result.append(RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: .groupSpecific), promotedBy: creator.id, canBeEditedByAccountPeer: creator.id == context.account.peerId), banInfo: nil), peer: peer, peers: peers)) + result.append(RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: .groupSpecific), promotedBy: creator.id, canBeEditedByAccountPeer: creator.id == context.account.peerId), banInfo: nil, rank: nil), peer: peer, peers: peers)) case .member: break } diff --git a/submodules/TelegramUI/TelegramUI/ChannelBannedMemberController.swift b/submodules/TelegramUI/TelegramUI/ChannelBannedMemberController.swift index b128affe53..2a0da2efda 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelBannedMemberController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelBannedMemberController.swift @@ -278,7 +278,7 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation let currentRightsFlags: TelegramChatBannedRightsFlags if let updatedFlags = state.updatedFlags { currentRightsFlags = updatedFlags - } else if let initialParticipant = initialParticipant, case let .member(_, _, _, maybeBanInfo) = initialParticipant, let banInfo = maybeBanInfo { + } else if let initialParticipant = initialParticipant, case let .member(_, _, _, maybeBanInfo, _) = initialParticipant, let banInfo = maybeBanInfo { currentRightsFlags = banInfo.rights.flags } else { currentRightsFlags = defaultBannedRights.flags @@ -287,7 +287,7 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation let currentTimeout: Int32 if let updatedTimeout = state.updatedTimeout { currentTimeout = updatedTimeout - } else if let initialParticipant = initialParticipant, case let .member(_, _, _, maybeBanInfo) = initialParticipant, let banInfo = maybeBanInfo { + } else if let initialParticipant = initialParticipant, case let .member(_, _, _, maybeBanInfo, _) = initialParticipant, let banInfo = maybeBanInfo { currentTimeout = banInfo.rights.untilDate } else { currentTimeout = Int32.max @@ -324,7 +324,7 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation let currentRightsFlags: TelegramChatBannedRightsFlags if let updatedFlags = state.updatedFlags { currentRightsFlags = updatedFlags - } else if let initialParticipant = initialParticipant, case let .member(_, _, _, maybeBanInfo) = initialParticipant, let banInfo = maybeBanInfo { + } else if let initialParticipant = initialParticipant, case let .member(_, _, _, maybeBanInfo, _) = initialParticipant, let banInfo = maybeBanInfo { currentRightsFlags = banInfo.rights.flags } else { currentRightsFlags = defaultBannedRightsFlags @@ -333,7 +333,7 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation let currentTimeout: Int32 if let updatedTimeout = state.updatedTimeout { currentTimeout = updatedTimeout - } else if let initialParticipant = initialParticipant, case let .member(_, _, _, maybeBanInfo) = initialParticipant, let banInfo = maybeBanInfo { + } else if let initialParticipant = initialParticipant, case let .member(_, _, _, maybeBanInfo, _) = initialParticipant, let banInfo = maybeBanInfo { currentTimeout = banInfo.rights.untilDate } else { currentTimeout = Int32.max @@ -552,7 +552,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI } if updateFlags == nil && updateTimeout == nil { - if case let .member(_, _, _, maybeBanInfo) = initialParticipant { + if case let .member(_, _, _, maybeBanInfo, _) = initialParticipant { if maybeBanInfo == nil { updateFlags = defaultBannedRightsFlags updateTimeout = Int32.max @@ -564,7 +564,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI let currentRightsFlags: TelegramChatBannedRightsFlags if let updatedFlags = updateFlags { currentRightsFlags = updatedFlags - } else if case let .member(_, _, _, maybeBanInfo) = initialParticipant, let banInfo = maybeBanInfo { + } else if case let .member(_, _, _, maybeBanInfo, _) = initialParticipant, let banInfo = maybeBanInfo { currentRightsFlags = banInfo.rights.flags } else { currentRightsFlags = defaultBannedRightsFlags @@ -573,7 +573,7 @@ public func channelBannedMemberController(context: AccountContext, peerId: PeerI let currentTimeout: Int32 if let updateTimeout = updateTimeout { currentTimeout = updateTimeout - } else if case let .member(_, _, _, maybeBanInfo) = initialParticipant, let banInfo = maybeBanInfo { + } else if case let .member(_, _, _, maybeBanInfo, _) = initialParticipant, let banInfo = maybeBanInfo { currentTimeout = banInfo.rights.untilDate } else { currentTimeout = Int32.max diff --git a/submodules/TelegramUI/TelegramUI/ChannelBlacklistController.swift b/submodules/TelegramUI/TelegramUI/ChannelBlacklistController.swift index eb835efcdf..01b1660f7c 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelBlacklistController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelBlacklistController.swift @@ -153,7 +153,7 @@ private enum ChannelBlacklistEntry: ItemListNodeEntry { case let .peerItem(theme, strings, dateTimeFormat, nameDisplayOrder, _, participant, editing, enabled): var text: ItemListPeerItemText = .none switch participant.participant { - case let .member(_, _, _, banInfo): + case let .member(_, _, _, banInfo, _): if let banInfo = banInfo, let peer = participant.peers[banInfo.restrictedBy] { text = .text(strings.Channel_Management_RemovedBy(peer.displayTitle).0) } @@ -297,7 +297,7 @@ public func channelBlacklistController(context: AccountContext, peerId: PeerId) switch participant.participant { case .creator: return - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if let adminInfo = adminInfo, adminInfo.promotedBy != context.account.peerId { presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Channel_Members_AddBannedErrorAdmin, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) return diff --git a/submodules/TelegramUI/TelegramUI/ChannelMemberCategoryListContext.swift b/submodules/TelegramUI/TelegramUI/ChannelMemberCategoryListContext.swift index caf8d372f6..c0f5393793 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelMemberCategoryListContext.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelMemberCategoryListContext.swift @@ -18,7 +18,7 @@ extension ChannelParticipant { switch self { case .creator: return nil - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): return adminInfo } } @@ -27,10 +27,24 @@ extension ChannelParticipant { switch self { case .creator: return nil - case let .member(_, _, _, banInfo): + case let .member(_, _, _, banInfo, _): return banInfo } } + + func canBeBannedBy(peerId: PeerId) -> Bool { + switch self { + case .creator: + return false + case let .member(_, _, adminInfo, _, _): + if let adminInfo = adminInfo { + if adminInfo.promotedBy != peerId { + return false + } + } + } + return true + } } struct ChannelMemberListState { @@ -295,7 +309,7 @@ private final class ChannelMemberSingleCategoryListContext: ChannelMemberCategor switch self.category { case let .admins(query): if let updated = updated, (query == nil || updated.peer.indexName.matchesByTokens(query!)) { - if case let .member(_, _, adminInfo, _) = updated.participant, adminInfo == nil { + if case let .member(_, _, adminInfo, _, _) = updated.participant, adminInfo == nil { } else { var found = false loop: for i in 0 ..< list.count { diff --git a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchContainerNode.swift b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchContainerNode.swift index a8536d341f..94f4a13a21 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchContainerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchContainerNode.swift @@ -366,7 +366,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod if peerId.namespace == Namespaces.Peer.CloudChannel { if case .searchAdmins = mode { - return context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: memberId, adminRights: TelegramChatAdminRights(flags: [])) + return context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(account: context.account, peerId: peerId, memberId: memberId, adminRights: TelegramChatAdminRights(flags: []), rank: nil) |> `catch` { _ -> Signal in return .complete() } @@ -442,7 +442,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod case .creator: canPromote = false canRestrict = false - case let .member(_, _, adminRights, bannedRights): + case let .member(_, _, adminRights, bannedRights, _): if channel.hasPermission(.addAdmins) { canPromote = true } else { @@ -649,7 +649,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod case .creator: canPromote = false canRestrict = false - case let .member(_, _, adminRights, bannedRights): + case let .member(_, _, adminRights, bannedRights, _): if channel.hasPermission(.addAdmins) { canPromote = true } else { @@ -718,7 +718,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod switch participant.participant { case .creator: label = themeAndStrings.1.Channel_Management_LabelOwner - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if let adminInfo = adminInfo { if let peer = participant.peers[adminInfo.promotedBy] { if peer.id == participant.peer.id { @@ -731,7 +731,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod } case .searchBanned: switch participant.participant { - case let .member(_, _, _, banInfo): + case let .member(_, _, _, banInfo, _): if let banInfo = banInfo { var exceptionsString = "" for rights in allGroupPermissionList { @@ -749,7 +749,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod } case .searchKicked: switch participant.participant { - case let .member(_, _, _, banInfo): + case let .member(_, _, _, banInfo, _): if let banInfo = banInfo, let peer = participant.peers[banInfo.restrictedBy] { label = themeAndStrings.1.Channel_Management_RemovedBy(peer.displayTitle).0 } @@ -853,18 +853,18 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod let renderedParticipant: RenderedChannelParticipant switch participant { case .creator: - renderedParticipant = RenderedChannelParticipant(participant: .creator(id: peer.id), peer: peer) + renderedParticipant = RenderedChannelParticipant(participant: .creator(id: peer.id, rank: nil), peer: peer) case .admin: var peers: [PeerId: Peer] = [:] if let creator = creatorPeer { peers[creator.id] = creator } peers[peer.id] = peer - renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: .groupSpecific), promotedBy: creatorPeer?.id ?? context.account.peerId, canBeEditedByAccountPeer: creatorPeer?.id == context.account.peerId), banInfo: nil), peer: peer, peers: peers) + renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: .groupSpecific), promotedBy: creatorPeer?.id ?? context.account.peerId, canBeEditedByAccountPeer: creatorPeer?.id == context.account.peerId), banInfo: nil, rank: nil), peer: peer, peers: peers) case .member: var peers: [PeerId: Peer] = [:] peers[peer.id] = peer - renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: nil, banInfo: nil), peer: peer, peers: peers) + renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil), peer: peer, peers: peers) } matchingMembers.append(renderedParticipant) } @@ -998,7 +998,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod switch participant.participant { case .creator: label = themeAndStrings.1.Channel_Management_LabelOwner - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if let adminInfo = adminInfo { if let peer = participant.peers[adminInfo.promotedBy] { if peer.id == participant.peer.id { @@ -1011,7 +1011,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod } case .searchBanned: switch participant.participant { - case let .member(_, _, _, banInfo): + case let .member(_, _, _, banInfo, _): if let banInfo = banInfo { var exceptionsString = "" for rights in allGroupPermissionList { @@ -1029,7 +1029,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod } case .searchKicked: switch participant.participant { - case let .member(_, _, _, banInfo): + case let .member(_, _, _, banInfo, _): if let banInfo = banInfo, let peer = participant.peers[banInfo.restrictedBy] { label = themeAndStrings.1.Channel_Management_RemovedBy(peer.displayTitle).0 } diff --git a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchControllerNode.swift index 78858a6262..def0095055 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelMembersSearchControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelMembersSearchControllerNode.swift @@ -204,16 +204,16 @@ class ChannelMembersSearchControllerNode: ASDisplayNode { let renderedParticipant: RenderedChannelParticipant switch participant { case .creator: - renderedParticipant = RenderedChannelParticipant(participant: .creator(id: peer.id), peer: peer) + renderedParticipant = RenderedChannelParticipant(participant: .creator(id: peer.id, rank: nil), peer: peer) case .admin: var peers: [PeerId: Peer] = [:] peers[creator.id] = creator peers[peer.id] = peer - renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: .groupSpecific), promotedBy: creator.id, canBeEditedByAccountPeer: creator.id == context.account.peerId), banInfo: nil), peer: peer, peers: peers) + renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: .groupSpecific), promotedBy: creator.id, canBeEditedByAccountPeer: creator.id == context.account.peerId), banInfo: nil, rank: nil), peer: peer, peers: peers) case .member: var peers: [PeerId: Peer] = [:] peers[peer.id] = peer - renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: nil, banInfo: nil), peer: peer, peers: peers) + renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil), peer: peer, peers: peers) } entries.append(.peer(index, renderedParticipant, ContactsPeerItemEditing(editable: false, editing: false, revealed: false), label, enabled)) diff --git a/submodules/TelegramUI/TelegramUI/ChannelPermissionsController.swift b/submodules/TelegramUI/TelegramUI/ChannelPermissionsController.swift index 47582a5102..6166c33690 100644 --- a/submodules/TelegramUI/TelegramUI/ChannelPermissionsController.swift +++ b/submodules/TelegramUI/TelegramUI/ChannelPermissionsController.swift @@ -198,7 +198,7 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry { case let .peerItem(theme, strings, dateTimeFormat, nameDisplayOrder, _, participant, editing, enabled, canOpen, defaultBannedRights): var text: ItemListPeerItemText = .none switch participant.participant { - case let .member(_, _, _, banInfo): + case let .member(_, _, _, banInfo, _): var exceptionsString = "" if let banInfo = banInfo { for rights in allGroupPermissionList { @@ -524,7 +524,7 @@ public func channelPermissionsController(context: AccountContext, peerId: PeerId switch participant.participant { case .creator: return - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if let adminInfo = adminInfo, adminInfo.promotedBy != context.account.peerId { presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Channel_Members_AddBannedErrorAdmin, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) return diff --git a/submodules/TelegramUI/TelegramUI/ChatController.swift b/submodules/TelegramUI/TelegramUI/ChatController.swift index 5fbedb19f0..3ee9b2ea96 100644 --- a/submodules/TelegramUI/TelegramUI/ChatController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatController.swift @@ -6517,19 +6517,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget, self.navigationActionDisposable.set((fetchChannelParticipant(account: self.context.account, peerId: peerId, participantId: author.id) |> deliverOnMainQueue).start(next: { [weak self] participant in if let strongSelf = self { - var canBan = true - if let participant = participant { - switch participant { - case .creator: - canBan = false - case let .member(_, _, adminInfo, _): - if let adminInfo = adminInfo, !adminInfo.rights.flags.isEmpty { - if adminInfo.promotedBy != accountPeerId { - canBan = false - } - } - } - } + var canBan = participant?.canBeBannedBy(peerId: accountPeerId) ?? true let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme) var items: [ActionSheetItem] = [] diff --git a/submodules/TelegramUI/TelegramUI/ChatMessageActionSheetControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatMessageActionSheetControllerNode.swift index 7fdb64af4e..2129e36e14 100644 --- a/submodules/TelegramUI/TelegramUI/ChatMessageActionSheetControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatMessageActionSheetControllerNode.swift @@ -163,13 +163,13 @@ final class ChatMessageActionSheetControllerNode: ViewControllerTracingNode { self.validLayout = layout var height: CGFloat = max(14.0, layout.intrinsicInsets.bottom) + let inputHeight = layout.inputHeight ?? 0.0 var horizontalOffset: CGFloat = horizontalOrigin if !horizontalOffset.isZero { - horizontalOffset += UIScreenPixel // temporary fix for master-detail separator dimming + horizontalOffset += UIScreenPixel } - let inputHeight = layout.inputHeight ?? 0.0 transition.updateFrame(node: self.sideDimNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: max(0.0, horizontalOffset), height: max(0.0, layout.size.height - inputHeight)))) transition.updateFrame(node: self.sideInputDimNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - inputHeight), size: CGSize(width: max(0.0, horizontalOrigin), height: max(0.0, inputHeight)))) transition.updateFrame(node: self.inputDimNode, frame: CGRect(origin: CGPoint(x: horizontalOrigin, y: layout.size.height - inputHeight), size: CGSize(width: layout.size.width, height: inputHeight))) @@ -185,12 +185,12 @@ final class ChatMessageActionSheetControllerNode: ViewControllerTracingNode { itemsHeight += actionNode.bounds.height } - let containerFrame = CGRect(origin: CGPoint(x: horizontalOrigin + floor((layout.size.width - containerWidth) / 2.0), y: layout.size.height - height - itemsHeight), size: CGSize(width: containerWidth, height: itemsHeight)) + let containerFrame = CGRect(origin: CGPoint(x: horizontalOrigin + floor((layout.size.width - containerWidth) / 2.0), y: layout.size.height - height - itemsHeight - inputHeight), size: CGSize(width: containerWidth, height: itemsHeight)) transition.updateFrame(node: self.itemsContainerNode, frame: containerFrame) transition.updateFrame(node: self.itemsShadowNode, frame: containerFrame.insetBy(dx: -shadowInset, dy: -shadowInset)) height += itemsHeight - + height += inputHeight height += 6.0 return height diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift index 1edb702d3c..72b5064c20 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsControllerNode.swift @@ -697,16 +697,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { } for member in adminsState.list { if member.peer.id == author.id { - switch member.participant { - case .creator: - canBan = false - case let .member(_, _, adminInfo, _): - if let adminInfo = adminInfo { - if adminInfo.promotedBy != self.context.account.peerId { - canBan = false - } - } - } + canBan = member.participant.canBeBannedBy(peerId: self.context.account.peerId) } } diff --git a/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift b/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift index f55490ae2a..4e3f0d28fa 100644 --- a/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift +++ b/submodules/TelegramUI/TelegramUI/ChatRecentActionsHistoryTransition.swift @@ -513,8 +513,8 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { isBroadcast = false } - if case let .member(_, _, _, prevBanInfo) = prev.participant { - if case let .member(_, _, _, newBanInfo) = new.participant { + if case let .member(_, _, _, prevBanInfo, _) = prev.participant { + if case let .member(_, _, _, newBanInfo, _) = new.participant { let newFlags = newBanInfo?.rights.flags ?? [] var addedRights = newBanInfo?.rights.flags ?? [] @@ -653,8 +653,8 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { }, to: &text, entities: &entities) text += "\n" - if case let .member(_, _, prevAdminRights, _) = prev.participant { - if case let .member(_, _, newAdminRights, _) = new.participant { + if case let .member(_, _, prevAdminRights, _, _) = prev.participant { + if case let .member(_, _, newAdminRights, _, _) = new.participant { let prevFlags = prevAdminRights?.rights.flags ?? [] let newFlags = newAdminRights?.rights.flags ?? [] diff --git a/submodules/TelegramUI/TelegramUI/CreateChannelController.swift b/submodules/TelegramUI/TelegramUI/CreateChannelController.swift index 3aca3a705c..3d79003f1f 100644 --- a/submodules/TelegramUI/TelegramUI/CreateChannelController.swift +++ b/submodules/TelegramUI/TelegramUI/CreateChannelController.swift @@ -175,7 +175,7 @@ private func CreateChannelEntries(presentationData: PresentationData, state: Cre let groupInfoState = ItemListAvatarAndNameInfoItemState(editingName: state.editingName, updatingName: nil) - let peer = TelegramGroup(id: PeerId(namespace: -1, id: 0), title: state.editingName.composedTitle, photo: [], participantCount: 0, role: .creator, membership: .Member, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) + let peer = TelegramGroup(id: PeerId(namespace: -1, id: 0), title: state.editingName.composedTitle, photo: [], participantCount: 0, role: .creator(rank: nil), membership: .Member, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) entries.append(.channelInfo(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, groupInfoState, state.avatar)) entries.append(.setProfilePhoto(presentationData.theme, presentationData.strings.Channel_UpdatePhotoItem)) diff --git a/submodules/TelegramUI/TelegramUI/CreateGroupController.swift b/submodules/TelegramUI/TelegramUI/CreateGroupController.swift index 967f710c82..0076fd36cd 100644 --- a/submodules/TelegramUI/TelegramUI/CreateGroupController.swift +++ b/submodules/TelegramUI/TelegramUI/CreateGroupController.swift @@ -241,7 +241,7 @@ private func createGroupEntries(presentationData: PresentationData, state: Creat let groupInfoState = ItemListAvatarAndNameInfoItemState(editingName: state.editingName, updatingName: nil) - let peer = TelegramGroup(id: PeerId(namespace: -1, id: 0), title: state.editingName.composedTitle, photo: [], participantCount: 0, role: .creator, membership: .Member, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) + let peer = TelegramGroup(id: PeerId(namespace: -1, id: 0), title: state.editingName.composedTitle, photo: [], participantCount: 0, role: .creator(rank: nil), membership: .Member, flags: [], defaultBannedRights: nil, migrationReference: nil, creationDate: 0, version: 0) entries.append(.groupInfo(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, groupInfoState, state.avatar)) entries.append(.setProfilePhoto(presentationData.theme, presentationData.strings.GroupInfo_SetGroupPhoto)) diff --git a/submodules/TelegramUI/TelegramUI/GroupInfoController.swift b/submodules/TelegramUI/TelegramUI/GroupInfoController.swift index 0dee989c88..b2fc1efc25 100644 --- a/submodules/TelegramUI/TelegramUI/GroupInfoController.swift +++ b/submodules/TelegramUI/TelegramUI/GroupInfoController.swift @@ -91,10 +91,10 @@ private enum GroupInfoEntryTag { case location } -private enum GroupInfoMemberStatus { +private enum GroupInfoMemberStatus: Equatable { case member - case admin - case owner + case admin(String?) + case owner(String?) } private enum GroupEntryStableId: Hashable, Equatable { @@ -718,7 +718,7 @@ private func canRemoveParticipant(account: Account, channel: TelegramChannel, pa switch participant { case .creator: return false - case let .member(_, _, adminInfo, _): + case let .member(_, _, adminInfo, _, _): if channel.hasPermission(.banMembers) { if let adminInfo = adminInfo { return adminInfo.promotedBy == account.peerId @@ -1013,13 +1013,13 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa let participant: ChannelParticipant switch sortedParticipants[i] { case .creator: - participant = .creator(id: sortedParticipants[i].peerId) - memberStatus = .admin + participant = .creator(id: sortedParticipants[i].peerId, rank: nil) + memberStatus = .owner(nil) case .admin: - participant = .member(id: sortedParticipants[i].peerId, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: .groupSpecific), promotedBy: account.peerId, canBeEditedByAccountPeer: true), banInfo: nil) - memberStatus = .admin + participant = .member(id: sortedParticipants[i].peerId, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(flags: .groupSpecific), promotedBy: account.peerId, canBeEditedByAccountPeer: true), banInfo: nil, rank: nil) + memberStatus = .admin(nil) case .member: - participant = .member(id: sortedParticipants[i].peerId, invitedAt: 0, adminInfo: nil, banInfo: nil) + participant = .member(id: sortedParticipants[i].peerId, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil) memberStatus = .member } @@ -1080,7 +1080,7 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa if !state.temporaryParticipants.isEmpty { for participant in state.temporaryParticipants { if !existingParticipantIds.contains(participant.peer.id) { - updatedParticipants.append(RenderedChannelParticipant(participant: ChannelParticipant.member(id: participant.peer.id, invitedAt: participant.timestamp, adminInfo: nil, banInfo: nil), peer: participant.peer)) + updatedParticipants.append(RenderedChannelParticipant(participant: ChannelParticipant.member(id: participant.peer.id, invitedAt: participant.timestamp, adminInfo: nil, banInfo: nil, rank: nil), peer: participant.peer)) if let presence = participant.presence, peerPresences[participant.peer.id] == nil { peerPresences[participant.peer.id] = presence } @@ -1112,11 +1112,11 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa switch lhs.participant { case .creator: return false - case let .member(lhsId, lhsInvitedAt, _, _): + case let .member(lhsId, lhsInvitedAt, _, _, _): switch rhs.participant { case .creator: return true - case let .member(rhsId, rhsInvitedAt, _, _): + case let .member(rhsId, rhsInvitedAt, _, _, _): if lhsInvitedAt == rhsInvitedAt { return lhsId.id < rhsId.id } @@ -1132,11 +1132,11 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa let participant = sortedParticipants[i] let memberStatus: GroupInfoMemberStatus switch participant.participant { - case .creator: - memberStatus = .owner - case let .member(_, _, adminInfo, _): + case let .creator(_, rank): + memberStatus = .owner(rank) + case let .member(_, _, adminInfo, _, rank): if adminInfo != nil { - memberStatus = .admin + memberStatus = .admin(rank) } else { memberStatus = .member } @@ -1152,7 +1152,7 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa case .creator: canPromote = false canRestrict = false - case let .member(_, _, adminRights, bannedRights): + case let .member(_, _, adminRights, bannedRights, _): if channel.hasPermission(.addAdmins) { canPromote = true } else { diff --git a/submodules/TelegramUI/TelegramUI/LogoutOptionsController.swift b/submodules/TelegramUI/TelegramUI/LogoutOptionsController.swift index 8f0db26e94..f3a53cbcb9 100644 --- a/submodules/TelegramUI/TelegramUI/LogoutOptionsController.swift +++ b/submodules/TelegramUI/TelegramUI/LogoutOptionsController.swift @@ -151,7 +151,7 @@ func logoutOptionsController(context: AccountContext, navigationController: Navi supportPeer.set(supportPeerId(account: context.account)) let presentationData = context.sharedContext.currentPresentationData.with { $0 } - var faqUrl = context.sharedContext.currentPresentationData.with { $0 }.strings.Settings_FAQ_URL + var faqUrl = presentationData.strings.Settings_FAQ_URL if faqUrl == "Settings.FAQ_URL" || faqUrl.isEmpty { faqUrl = "https://telegram.org/faq#general" } diff --git a/submodules/TelegramUI/TelegramUI/PeerChannelMemberCategoriesContextsManager.swift b/submodules/TelegramUI/TelegramUI/PeerChannelMemberCategoriesContextsManager.swift index 0e02c1f831..6b25b53bda 100644 --- a/submodules/TelegramUI/TelegramUI/PeerChannelMemberCategoriesContextsManager.swift +++ b/submodules/TelegramUI/TelegramUI/PeerChannelMemberCategoriesContextsManager.swift @@ -163,7 +163,7 @@ final class PeerChannelMemberCategoriesContextsManager { self.impl.with { impl in for (contextPeerId, context) in impl.contexts { if contextPeerId == peerId { - context.replayUpdates([(.member(id: memberId, invitedAt: 0, adminInfo: nil, banInfo: nil), nil, nil)]) + context.replayUpdates([(.member(id: memberId, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil), nil, nil)]) } } } @@ -224,8 +224,8 @@ final class PeerChannelMemberCategoriesContextsManager { } } - func updateMemberAdminRights(account: Account, peerId: PeerId, memberId: PeerId, adminRights: TelegramChatAdminRights) -> Signal { - return updateChannelAdminRights(account: account, peerId: peerId, adminId: memberId, rights: adminRights) + func updateMemberAdminRights(account: Account, peerId: PeerId, memberId: PeerId, adminRights: TelegramChatAdminRights, rank: String?) -> Signal { + return updateChannelAdminRights(account: account, peerId: peerId, adminId: memberId, rights: adminRights, rank: rank) |> map(Optional.init) |> deliverOnMainQueue |> beforeNext { [weak self] result in diff --git a/submodules/TelegramUI/TelegramUI/ThemeAutoNightSettingsController.swift b/submodules/TelegramUI/TelegramUI/ThemeAutoNightSettingsController.swift index b6b753817f..a4f3740141 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeAutoNightSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeAutoNightSettingsController.swift @@ -288,21 +288,12 @@ private func themeAutoNightSettingsControllerEntries(theme: PresentationTheme, s entries.append(.settingInfo(theme, strings.AutoNightTheme_AutomaticHelp("\(Int(threshold * 100.0))").0.replacingOccurrences(of: "%%", with: "%"))) } - switch switchSetting.trigger { - case .none: - break - case .timeBased, .brightness: - entries.append(.themeHeader(theme, strings.AutoNightTheme_PreferredTheme)) - entries.append(.themeNightBlue(theme, strings.Appearance_ThemeNightBlue, switchSetting.theme == .nightAccent)) - entries.append(.themeNight(theme, strings.Appearance_ThemeNight, switchSetting.theme == .night)) - } - return entries } private func roundTimeToDay(_ timestamp: Int32) -> Int32 { let calendar = Calendar.current - let offset = 0//TimeZone.current.secondsFromGMT(for: Date()) + let offset = 0 let components = calendar.dateComponents([.hour, .minute, .second], from: Date(timeIntervalSince1970: Double(timestamp + Int32(offset)))) return Int32(components.hour! * 60 * 60 + components.minute! * 60 + components.second!) } diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsColorSliderNode.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsColorSliderNode.swift index 5588149356..7cb291d85a 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsColorSliderNode.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsColorSliderNode.swift @@ -4,6 +4,7 @@ import AsyncDisplayKit import SwiftSignalKit import Display import TelegramPresentationData +import TelegramUIPreferences private let shadowImage: UIImage = { return generateImage(CGSize(width: 54.0, height: 54.0), opaque: false, scale: nil, rotatedContext: { size, context in @@ -17,23 +18,25 @@ private let shadowImage: UIImage = { })! }() -private final class HSVParameter: NSObject { - let hue: CGFloat - let saturation: CGFloat +private final class ColorsParameter: NSObject { + let leftColor: UIColor + let baseColor: UIColor + let rightColor: UIColor let value: CGFloat - init(hue: CGFloat, saturation: CGFloat, value: CGFloat) { - self.hue = hue - self.saturation = saturation + init(leftColor: UIColor, baseColor: UIColor, rightColor: UIColor, value: CGFloat) { + self.leftColor = leftColor + self.baseColor = baseColor + self.rightColor = rightColor self.value = value super.init() } } private final class ThemeSettingsColorKnobNode: ASDisplayNode { - var hsv: (CGFloat, CGFloat, CGFloat) = (0.0, 0.0, 1.0) { + var values: (UIColor, UIColor, UIColor, CGFloat) = (.clear, .clear, .clear, 0.5) { didSet { - if self.hsv != oldValue { + if self.values != oldValue { self.setNeedsDisplay() } } @@ -48,11 +51,11 @@ private final class ThemeSettingsColorKnobNode: ASDisplayNode { } override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? { - return HSVParameter(hue: self.hsv.0, saturation: self.hsv.1, value: self.hsv.2) + return ColorsParameter(leftColor: self.values.0, baseColor: self.values.1, rightColor: self.values.2, value: self.values.3) } @objc override class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled: () -> Bool, isRasterizing: Bool) { - guard let parameters = parameters as? HSVParameter else { + guard let parameters = parameters as? ColorsParameter else { return } let context = UIGraphicsGetCurrentContext()! @@ -69,7 +72,15 @@ private final class ThemeSettingsColorKnobNode: ASDisplayNode { context.setFillColor(UIColor.white.cgColor) context.fillEllipse(in: bounds.insetBy(dx: 3.0, dy: 3.0)) - let color = UIColor(hue: parameters.hue, saturation: parameters.saturation, brightness: parameters.value, alpha: 1.0) + let color: UIColor + if parameters.value < 0.5 { + color = parameters.baseColor.interpolateTo(parameters.leftColor, fraction: 0.5 - parameters.value)! + } else if parameters.value > 0.5 { + color = parameters.baseColor.interpolateTo(parameters.rightColor, fraction: parameters.value - 0.5)! + } else { + color = parameters.baseColor + } + context.setFillColor(color.cgColor) let borderWidth: CGFloat = bounds.width > 30.0 ? 5.0 : 5.0 @@ -78,7 +89,7 @@ private final class ThemeSettingsColorKnobNode: ASDisplayNode { } private final class ThemeSettingsColorBrightnessNode: ASDisplayNode { - var hsv: (CGFloat, CGFloat, CGFloat) = (0.0, 1.0, 1.0) { + var values: (UIColor, UIColor, UIColor, CGFloat) = (.clear, .clear, .clear, 0.5) { didSet { self.setNeedsDisplay() } @@ -92,11 +103,11 @@ private final class ThemeSettingsColorBrightnessNode: ASDisplayNode { } override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? { - return HSVParameter(hue: self.hsv.0, saturation: self.hsv.1, value: self.hsv.2) + return ColorsParameter(leftColor: self.values.0, baseColor: self.values.1, rightColor: self.values.2, value: self.values.3) } @objc override class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled: () -> Bool, isRasterizing: Bool) { - guard let parameters = parameters as? HSVParameter else { + guard let parameters = parameters as? ColorsParameter else { return } let context = UIGraphicsGetCurrentContext()! @@ -108,11 +119,8 @@ private final class ThemeSettingsColorBrightnessNode: ASDisplayNode { context.addPath(innerPath.cgPath) context.clip() - let leftColor = UIColor(hue: parameters.hue, saturation: parameters.saturation, brightness: parameters.value - 0.4, alpha: 1.0) - let rightColor = UIColor(hue: parameters.hue, saturation: parameters.saturation, brightness: parameters.value + 0.4, alpha: 1.0) - - let colors = [leftColor.cgColor, rightColor.cgColor] - var locations: [CGFloat] = [0.0, 1.0] + let colors = [parameters.leftColor.cgColor, parameters.baseColor.cgColor, parameters.rightColor.cgColor] + var locations: [CGFloat] = [0.0, 0.5, 1.0] let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)! context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: bounds.width, y: 0.0), options: CGGradientDrawingOptions()) } @@ -126,18 +134,10 @@ final class ThemeSettingsColorSliderNode: ASDisplayNode { var valueChanged: ((CGFloat) -> Void)? - var baseColor: UIColor = .white { + var baseColor: PresentationThemeBaseColor = .white { didSet { - var hue: CGFloat = 0.0 - var saturation: CGFloat = 0.0 - var value: CGFloat = 0.0 - - var newHSV: (CGFloat, CGFloat, CGFloat) = (0.0, 0.0, 0.0) - if self.baseColor.getHue(&hue, saturation: &saturation, brightness: &value, alpha: nil) { - newHSV = (hue, saturation, value) - } - - self.brightnessNode.hsv = newHSV + let colors = self.baseColor.edgeColors + self.brightnessNode.values = (colors.0, self.baseColor.color, colors.1, 0.5) self.update() } } @@ -179,17 +179,8 @@ final class ThemeSettingsColorSliderNode: ASDisplayNode { } private func update() { - var hue: CGFloat = 0.0 - var saturation: CGFloat = 0.0 - var value: CGFloat = 0.0 - - let delta = (-0.5 + self.value) * 0.8 - - var newHSV: (CGFloat, CGFloat, CGFloat) = (0.0, 0.0, 0.0) - if self.baseColor.getHue(&hue, saturation: &saturation, brightness: &value, alpha: nil) { - newHSV = (hue, saturation, value + delta) - } - self.brightnessKnobNode.hsv = newHSV + let colors = self.baseColor.edgeColors + self.brightnessKnobNode.values = (colors.0, self.baseColor.color, colors.1, self.value) } func updateKnobLayout(size: CGSize, transition: ContainedViewLayoutTransition) { diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift index 3bb9970dfe..f98be2fb4e 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsController.swift @@ -307,16 +307,23 @@ private struct ThemeSettingsState: Equatable { } } -private func themeSettingsControllerEntries(presentationData: PresentationData, theme: PresentationTheme, themeReference: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], autoNightSettings: AutomaticThemeSwitchSetting, strings: PresentationStrings, wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, dateTimeFormat: PresentationDateTimeFormat, largeEmoji: Bool, disableAnimations: Bool, availableAppIcons: [PresentationAppIcon], currentAppIconName: String?, displayColorSlider: Bool) -> [ThemeSettingsControllerEntry] { +private func themeSettingsControllerEntries(presentationData: PresentationData, theme: PresentationTheme, themeReference: PresentationThemeReference, themeSpecificAccentColors: [Int64: PresentationThemeAccentColor], autoNightSettings: AutomaticThemeSwitchSetting, strings: PresentationStrings, wallpaper: TelegramWallpaper, fontSize: PresentationFontSize, dateTimeFormat: PresentationDateTimeFormat, largeEmoji: Bool, disableAnimations: Bool, availableAppIcons: [PresentationAppIcon], currentAppIconName: String?, displayColorSlider: Bool, tintAllColors: Bool) -> [ThemeSettingsControllerEntry] { var entries: [ThemeSettingsControllerEntry] = [] entries.append(.themeListHeader(presentationData.theme, strings.Appearance_ColorTheme.uppercased())) entries.append(.chatPreview(presentationData.theme, theme, wallpaper, fontSize, presentationData.strings, dateTimeFormat, presentationData.nameDisplayOrder)) - if case .builtin = themeReference { - entries.append(.themeItem(presentationData.theme, presentationData.strings, [.builtin(.dayClassic), .builtin(.day), .builtin(.nightAccent), .builtin(.night)], themeReference, themeSpecificAccentColors, themeSpecificAccentColors[themeReference.index], displayColorSlider)) + + var availableThemes: [PresentationThemeReference] = [.builtin(.dayClassic), .builtin(.day)] + if tintAllColors { + availableThemes.append(.builtin(.nightAccent)) + } else { + availableThemes.append(.builtin(.night)) } + + entries.append(.themeItem(presentationData.theme, presentationData.strings, availableThemes, themeReference, themeSpecificAccentColors, themeSpecificAccentColors[themeReference.index], displayColorSlider)) + if theme.name == .builtin(.nightAccent) || theme.name == .builtin(.night) { - entries.append(.themeTint(presentationData.theme, strings.Appearance_TintAllColors, false)) + entries.append(.themeTint(presentationData.theme, strings.Appearance_TintAllColors, tintAllColors)) } if theme.name != .builtin(.dayClassic) { entries.append(.accentColor(presentationData.theme, strings.Appearance_AccentColor, themeSpecificAccentColors[themeReference.index])) @@ -392,7 +399,7 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The chatWallpaper = themeSpecificWallpaper } else { let accentColor = current.themeSpecificAccentColors[theme.index]?.color ?? defaultDayAccentColor - let theme = makePresentationTheme(themeReference: current.theme, accentColor: accentColor, serviceBackgroundColor: defaultServiceBackgroundColor) + let theme = makePresentationTheme(themeReference: theme, accentColor: accentColor, serviceBackgroundColor: defaultServiceBackgroundColor) chatWallpaper = theme.chat.defaultWallpaper } @@ -464,9 +471,14 @@ public func themeSettingsController(context: AccountContext, focusOnItemTag: The } else { wallpaper = settings.chatWallpaper } + + var tintAllColors = settings.themeTintColors + if !tintAllColors, case let .builtin(theme) = settings.theme, case .nightAccent = theme { + tintAllColors = true + } let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Appearance_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back)) - let listState = ItemListNodeState(entries: themeSettingsControllerEntries(presentationData: presentationData, theme: theme, themeReference: settings.theme, themeSpecificAccentColors: settings.themeSpecificAccentColors, autoNightSettings: settings.automaticThemeSwitchSetting, strings: presentationData.strings, wallpaper: wallpaper, fontSize: fontSize, dateTimeFormat: dateTimeFormat, largeEmoji: largeEmoji, disableAnimations: disableAnimations, availableAppIcons: availableAppIcons, currentAppIconName: currentAppIconName, displayColorSlider: state.displayColorSlider), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false) + let listState = ItemListNodeState(entries: themeSettingsControllerEntries(presentationData: presentationData, theme: theme, themeReference: settings.theme, themeSpecificAccentColors: settings.themeSpecificAccentColors, autoNightSettings: settings.automaticThemeSwitchSetting, strings: presentationData.strings, wallpaper: wallpaper, fontSize: fontSize, dateTimeFormat: dateTimeFormat, largeEmoji: largeEmoji, disableAnimations: disableAnimations, availableAppIcons: availableAppIcons, currentAppIconName: currentAppIconName, displayColorSlider: state.displayColorSlider, tintAllColors: tintAllColors), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false) return (controllerState, (listState, arguments)) } diff --git a/submodules/TelegramUI/TelegramUI/ThemeSettingsThemeItem.swift b/submodules/TelegramUI/TelegramUI/ThemeSettingsThemeItem.swift index 8e692ee042..d080c1d16e 100644 --- a/submodules/TelegramUI/TelegramUI/ThemeSettingsThemeItem.swift +++ b/submodules/TelegramUI/TelegramUI/ThemeSettingsThemeItem.swift @@ -46,13 +46,11 @@ private func generateThemeIconImage(theme: PresentationThemeReference, accentCol let background: UIColor let incomingFill: UIColor - var incomingStrokeColor: UIColor? let outgoingFill: UIColor switch theme { case .dayClassic: background = UIColor(rgb: 0xd6e2ee) incomingFill = UIColor(rgb: 0xffffff) - incomingStrokeColor = UIColor(rgb: 0xc9d6e2) outgoingFill = UIColor(rgb: 0xe1ffc7) case .day: background = .white @@ -403,8 +401,8 @@ class ThemeSettingsThemeItemNode: ListViewItemNode, ItemListItemNode { } let previousBaseColor = strongSelf.colorSlider.baseColor - let newBaseColor = item.currentColor?.baseColor.color - strongSelf.colorSlider.baseColor = newBaseColor ?? .black + let newBaseColor = item.currentColor?.baseColor ?? .blue + strongSelf.colorSlider.baseColor = newBaseColor if previousBaseColor != newBaseColor { strongSelf.colorSlider.value = item.currentColor?.value ?? 0.5 } diff --git a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift index 7b90851be5..1bfc720441 100644 --- a/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/PresentationThemeSettings.swift @@ -206,6 +206,35 @@ public enum PresentationThemeBaseColor: Int32, CaseIterable { } return UIColor(rgb: value) } + + public var edgeColors: (UIColor, UIColor) { + let values: (UIColor, UIColor) + switch self { + case .blue: + values = (UIColor(rgb: 0x003d80), UIColor(rgb: 0x66afff)) + case .cyan: + values = (UIColor(rgb: 0x00c2ed), UIColor(rgb: 0x00c2ed)) + case .green: + values = (UIColor(rgb: 0x29b327), UIColor(rgb: 0x29b327)) + case .pink: + values = (UIColor(rgb: 0xeb6ca4), UIColor(rgb: 0xeb6ca4)) + case .orange: + values = (UIColor(rgb: 0xf08200), UIColor(rgb: 0xf08200)) + case .purple: + values = (UIColor(rgb: 0x9472ee), UIColor(rgb: 0x9472ee)) + case .red: + values = (UIColor(rgb: 0xd33213), UIColor(rgb: 0xd33213)) + case .yellow: + values = (UIColor(rgb: 0xedb400), UIColor(rgb: 0xedb400)) + case .gray: + values = (UIColor(rgb: 0x6d839e), UIColor(rgb: 0x6d839e)) + case .black: + values = (UIColor(rgb: 0x000000), UIColor(rgb: 0x000000)) + case .white: + values = (UIColor(rgb: 0xffffff), UIColor(rgb: 0xffffff)) + } + return values + } } public struct PresentationThemeAccentColor: PostboxCoding, Equatable { @@ -228,17 +257,15 @@ public struct PresentationThemeAccentColor: PostboxCoding, Equatable { } public var color: UIColor { - var hue: CGFloat = 0.0 - var saturation: CGFloat = 0.0 - var value: CGFloat = 0.0 - - let color = self.baseColor.color - let delta = (-0.5 + self.value) * 0.8 - if color.getHue(&hue, saturation: &saturation, brightness: &value, alpha: nil) { - return UIColor(hue: hue, saturation: saturation, brightness: min(1.0, max(0.0, value + delta)), alpha: 1.0) + let color: UIColor + if self.value < 0.5 { + color = self.baseColor.color.interpolateTo(self.baseColor.edgeColors.0, fraction: 0.5 - self.value)! + } else if self.value > 0.5 { + color = self.baseColor.color.interpolateTo(self.baseColor.edgeColors.1, fraction: self.value - 0.5)! } else { - return color + color = self.baseColor.color } + return color } }