diff --git a/Telegram/NotificationService/Sources/NotificationService.swift b/Telegram/NotificationService/Sources/NotificationService.swift index 91ad35039d..94437a779e 100644 --- a/Telegram/NotificationService/Sources/NotificationService.swift +++ b/Telegram/NotificationService/Sources/NotificationService.swift @@ -273,7 +273,7 @@ private extension CGSize { private func convertLottieImage(data: Data) -> UIImage? { let decompressedData = TGGUnzipData(data, 512 * 1024) ?? data - guard let animation = LottieInstance(data: decompressedData, fitzModifier: .none, cacheKey: "") else { + guard let animation = LottieInstance(data: decompressedData, fitzModifier: .none, colorReplacements: nil, cacheKey: "") else { return nil } let size = animation.dimensions.fitted(CGSize(width: 200.0, height: 200.0)) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index c9f421bd91..6ab4e9500e 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -7503,4 +7503,20 @@ Sorry for the inconvenience."; "PeerInfo.DeleteChannelText" = "Are you sure you want to delete the channel **%@** and all of its messages for all subscribers of the channel?"; "Chat.SaveForNotifications" = "Save for Notifications"; + +"Group.Setup.WhoCanSendMessages.Title" = "WHO CAN SEND MESSAGES?"; +"Group.Setup.WhoCanSendMessages.Everyone" = "Everyone"; +"Group.Setup.WhoCanSendMessages.OnlyMembers" = "Only Members"; + +"Group.Setup.ApproveNewMembers" = "Approve New Members"; +"Group.Setup.ApproveNewMembersInfo" = "Turn this on if you want users to be able to send messages only after they are approved by an admin."; + "Gallery.GifSaved" = "GIF Saved"; + +"Group.JoinGroup" = "Join Group"; +"Group.ApplyToJoin" = "Apply to Join Group"; + +"Group.RequestToJoinSent" = "Request to join sent"; +"Group.RequestToJoinSentDescriptionGroup" = "You will be able to send messages once the admins approve your request."; + +"Channel.AdminLog.JoinedViaPublicRequest" = "%1$@ joined via public request, approved by %2$@"; diff --git a/submodules/AnimatedStickerNode/Sources/AnimatedStickerFrameSource.swift b/submodules/AnimatedStickerNode/Sources/AnimatedStickerFrameSource.swift index 6fb54ca3e6..f512243712 100644 --- a/submodules/AnimatedStickerNode/Sources/AnimatedStickerFrameSource.swift +++ b/submodules/AnimatedStickerNode/Sources/AnimatedStickerFrameSource.swift @@ -587,7 +587,7 @@ final class AnimatedStickerDirectFrameSource: AnimatedStickerFrameSource { self.currentFrame = 0 let decompressedData = TGGUnzipData(data, 8 * 1024 * 1024) ?? data - guard let animation = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, cacheKey: "") else { + guard let animation = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, colorReplacements: nil, cacheKey: "") else { return nil } self.animation = animation diff --git a/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift b/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift index c2f5d82e4b..c73184dcfb 100644 --- a/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift +++ b/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift @@ -1143,7 +1143,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS text = current.inputText.attributedSubstring(from: NSMakeRange(current.selectionRange.lowerBound, current.selectionRange.count)).string return (current, inputMode) } - let _ = speakText(text) + let _ = speakText(context: self.context, text: text) if #available(iOS 13.0, *) { UIMenuController.shared.hideMenu() diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index 43bcfe1c5e..953e70b704 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -181,19 +181,19 @@ public class ChatListItem: ListViewItem, ChatListSearchItemNeighbour { } } -private let pinIcon = ItemListRevealOptionIcon.animation(animation: "anim_pin", scale: 0.33333, offset: 0.0, keysToColor: nil, flip: false) -private let unpinIcon = ItemListRevealOptionIcon.animation(animation: "anim_unpin", scale: 0.33333, offset: 0.0, keysToColor: ["un Outlines.Group 1.Stroke 1"], flip: false) -private let muteIcon = ItemListRevealOptionIcon.animation(animation: "anim_mute", scale: 0.33333, offset: 0.0, keysToColor: ["un Outlines.Group 1.Stroke 1"], flip: false) -private let unmuteIcon = ItemListRevealOptionIcon.animation(animation: "anim_unmute", scale: 0.33333, offset: 0.0, keysToColor: nil, flip: false) -private let deleteIcon = ItemListRevealOptionIcon.animation(animation: "anim_delete", scale: 0.33333, offset: 0.0, keysToColor: nil, flip: false) -private let groupIcon = ItemListRevealOptionIcon.animation(animation: "anim_group", scale: 0.33333, offset: 0.0, keysToColor: nil, flip: false) -private let ungroupIcon = ItemListRevealOptionIcon.animation(animation: "anim_ungroup", scale: 0.33333, offset: 0.0, keysToColor: nil, flip: false) -private let readIcon = ItemListRevealOptionIcon.animation(animation: "anim_read", scale: 0.33333, offset: 0.0, keysToColor: nil, flip: false) -private let unreadIcon = ItemListRevealOptionIcon.animation(animation: "anim_unread", scale: 0.33333, offset: 0.0, keysToColor: ["Oval.Oval.Stroke 1"], flip: false) -private let archiveIcon = ItemListRevealOptionIcon.animation(animation: "anim_archive", scale: 0.33333, offset: 2.0, keysToColor: ["box2.box2.Fill 1"], flip: false) -private let unarchiveIcon = ItemListRevealOptionIcon.animation(animation: "anim_unarchive", scale: 0.16214, offset: -9.0, keysToColor: ["box2.box2.Fill 1"], flip: false) -private let hideIcon = ItemListRevealOptionIcon.animation(animation: "anim_hide", scale: 0.33333, offset: 2.0, keysToColor: ["Path 2.Path 2.Fill 1"], flip: false) -private let unhideIcon = ItemListRevealOptionIcon.animation(animation: "anim_hide", scale: 0.33333, offset: -20.0, keysToColor: ["Path 2.Path 2.Fill 1"], flip: true) +private let pinIcon = ItemListRevealOptionIcon.animation(animation: "anim_pin", scale: 1.0, offset: 0.0, replaceColors: nil, flip: false) +private let unpinIcon = ItemListRevealOptionIcon.animation(animation: "anim_unpin", scale: 1.0, offset: 0.0, replaceColors: [0x1993fa], flip: false) +private let muteIcon = ItemListRevealOptionIcon.animation(animation: "anim_mute", scale: 1.0, offset: 0.0, replaceColors: [0xff9500], flip: false) +private let unmuteIcon = ItemListRevealOptionIcon.animation(animation: "anim_unmute", scale: 1.0, offset: 0.0, replaceColors: nil, flip: false) +private let deleteIcon = ItemListRevealOptionIcon.animation(animation: "anim_delete", scale: 1.0, offset: 0.0, replaceColors: nil, flip: false) +private let groupIcon = ItemListRevealOptionIcon.animation(animation: "anim_group", scale: 1.0, offset: 0.0, replaceColors: nil, flip: false) +private let ungroupIcon = ItemListRevealOptionIcon.animation(animation: "anim_ungroup", scale: 1.0, offset: 0.0, replaceColors: nil, flip: false) +private let readIcon = ItemListRevealOptionIcon.animation(animation: "anim_read", scale: 1.0, offset: 0.0, replaceColors: nil, flip: false) +private let unreadIcon = ItemListRevealOptionIcon.animation(animation: "anim_unread", scale: 1.0, offset: 0.0, replaceColors: [0x2194fa], flip: false) +private let archiveIcon = ItemListRevealOptionIcon.animation(animation: "anim_archive", scale: 1.0, offset: 2.0, replaceColors: [0xa9a9ad], flip: false) +private let unarchiveIcon = ItemListRevealOptionIcon.animation(animation: "anim_unarchive", scale: 0.486, offset: -9.0, replaceColors: [0xa9a9ad], flip: false) +private let hideIcon = ItemListRevealOptionIcon.animation(animation: "anim_hide", scale: 1.0, offset: 2.0, replaceColors: [0xbdbdc2], flip: false) +private let unhideIcon = ItemListRevealOptionIcon.animation(animation: "anim_hide", scale: 1.0, offset: -20.0, replaceColors: [0xbdbdc2], flip: true) private enum RevealOptionKey: Int32 { case pin diff --git a/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift b/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift index 9e243dfc6f..ee53100d74 100644 --- a/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift +++ b/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift @@ -26,7 +26,7 @@ public func reactionStaticImage(context: AccountContext, animation: TelegramMedi guard let unpackedData = TGGUnzipData(data, 5 * 1024 * 1024) else { return } - guard let instance = LottieInstance(data: unpackedData, fitzModifier: .none, cacheKey: "") else { + guard let instance = LottieInstance(data: unpackedData, fitzModifier: .none, colorReplacements: nil, cacheKey: "") else { return } diff --git a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift index 05a27ec5d9..1a54b7c61d 100644 --- a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift @@ -352,7 +352,7 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { window.rootViewController?.present(controller, animated: true) } case .speak: - let _ = speakText(string) + let _ = speakText(context: strongSelf.context, text: string) case .translate: if let parentController = strongSelf.baseNavigationController()?.topViewController as? ViewController { let controller = TranslateScreen(context: strongSelf.context, text: string, fromLanguage: nil) diff --git a/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift b/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift index 1569b45fa3..5179d173f9 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkEditController.swift @@ -432,15 +432,15 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio let actionsDisposable = DisposableSet() let initialState: InviteLinkEditControllerState - if let invite = invite { - var usageLimit = invite.usageLimit - if let limit = usageLimit, let count = invite.count, count > 0 { + if let invite = invite, case let .link(_, title, _, requestApproval, _, _, _, _, expireDate, usageLimit, count, _) = invite { + var usageLimit = usageLimit + if let limit = usageLimit, let count = count, count > 0 { usageLimit = limit - count } let timeLimit: InviteLinkTimeLimit let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) - if let expireDate = invite.expireDate { + if let expireDate = expireDate { if currentTime >= expireDate { timeLimit = .day } else { @@ -450,7 +450,7 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio timeLimit = .unlimited } - initialState = InviteLinkEditControllerState(title: invite.title ?? "", usage: InviteLinkUsageLimit(value: usageLimit), time: timeLimit, requestApproval: invite.requestApproval, pickingTimeLimit: false, pickingUsageLimit: false) + initialState = InviteLinkEditControllerState(title: title ?? "", usage: InviteLinkUsageLimit(value: usageLimit), time: timeLimit, requestApproval: requestApproval, pickingTimeLimit: false, pickingUsageLimit: false) } else { initialState = InviteLinkEditControllerState(title: "", usage: .unlimited, time: .unlimited, requestApproval: false, pickingTimeLimit: false, pickingUsageLimit: false) } @@ -472,7 +472,7 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio }, dismissInput: { dismissInputImpl?() }, revoke: { - guard let invite = invite else { + guard let inviteLink = invite?.link else { return } let _ = (context.account.postbox.loadedPeerWithId(peerId) @@ -495,7 +495,7 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio dismissAction() dismissImpl?() - let _ = (context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: invite.link) + let _ = (context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: inviteLink) |> timeout(10, queue: Queue.mainQueue(), alternate: .fail(.generic)) |> deliverOnMainQueue).start(next: { invite in switch invite { @@ -578,13 +578,13 @@ public func inviteLinkEditController(context: AccountContext, updatedPresentatio } presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil) }) - } else if let initialInvite = invite { - if initialInvite.expireDate == expireDate && initialInvite.usageLimit == usageLimit && initialInvite.requestApproval == requestNeeded { + } else if let initialInvite = invite, case let .link(link, _, _, initialRequestApproval, _, _, _, _, initialExpireDate, initialUsageLimit, _, _) = initialInvite { + if initialExpireDate == expireDate && initialUsageLimit == usageLimit && initialRequestApproval == requestNeeded { completion?(initialInvite) dismissImpl?() return } - let _ = (context.engine.peers.editPeerExportedInvitation(peerId: peerId, link: initialInvite.link, title: title, expireDate: expireDate, usageLimit: requestNeeded ? 0 : usageLimit, requestNeeded: requestNeeded) + let _ = (context.engine.peers.editPeerExportedInvitation(peerId: peerId, link: link, title: title, expireDate: expireDate, usageLimit: requestNeeded ? 0 : usageLimit, requestNeeded: requestNeeded) |> timeout(10, queue: Queue.mainQueue(), alternate: .fail(.generic)) |> deliverOnMainQueue).start(next: { invite in completion?(invite) diff --git a/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift b/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift index 5b11e4bfd1..ce90640e7a 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkInviteController.swift @@ -401,8 +401,8 @@ public final class InviteLinkInviteController: ViewController { ActionSheetButtonItem(title: presentationData.strings.GroupInfo_InviteLink_RevokeLink, color: .destructive, action: { dismissAction() - if let invite = invite { - let _ = (context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: invite.link) |> deliverOnMainQueue).start(next: { result in + if let inviteLink = invite?.link { + let _ = (context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: inviteLink) |> deliverOnMainQueue).start(next: { result in if let result = result, case let .replace(_, invite) = result { mainInvitePromise.set(invite) } @@ -429,11 +429,11 @@ public final class InviteLinkInviteController: ViewController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root)) }, shareLink: { [weak self] invite in - guard let strongSelf = self else { + guard let strongSelf = self, let inviteLink = invite.link else { return } let updatedPresentationData = (strongSelf.presentationData, strongSelf.presentationDataPromise.get()) - let shareController = ShareController(context: context, subject: .url(invite.link), updatedPresentationData: updatedPresentationData) + let shareController = ShareController(context: context, subject: .url(inviteLink), updatedPresentationData: updatedPresentationData) shareController.completed = { [weak self] peerIds in if let strongSelf = self { let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in diff --git a/submodules/InviteLinksUI/Sources/InviteLinkListController.swift b/submodules/InviteLinksUI/Sources/InviteLinkListController.swift index 847d16924b..89cb79f36e 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkListController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkListController.swift @@ -285,7 +285,7 @@ private func inviteLinkListControllerEntries(presentationData: PresentationData, let mainInvite: ExportedInvitation? var isPublic = false if let peer = peer, let address = peer.addressName, !address.isEmpty && admin == nil { - mainInvite = ExportedInvitation(link: "t.me/\(address)", title: nil, isPermanent: true, requestApproval: false, isRevoked: false, adminId: EnginePeer.Id(0), date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil, requestedCount: nil) + mainInvite = .link(link: "t.me/\(address)", title: nil, isPermanent: true, requestApproval: false, isRevoked: false, adminId: EnginePeer.Id(0), date: 0, startDate: nil, expireDate: nil, usageLimit: nil, count: nil, requestedCount: nil) isPublic = true } else if let invites = invites, let invite = invites.first(where: { $0.isPermanent && !$0.isRevoked }) { mainInvite = invite @@ -300,7 +300,7 @@ private func inviteLinkListControllerEntries(presentationData: PresentationData, let importersCount: Int32 if let count = importers?.count { importersCount = count - } else if let count = mainInvite?.count { + } else if let mainInvite = mainInvite, case let .link(_, _, _, _, _, _, _, _, _, _, count, _) = mainInvite, let count = count { importersCount = count } else { importersCount = 0 @@ -339,8 +339,10 @@ private func inviteLinkListControllerEntries(presentationData: PresentationData, if let additionalInvites = additionalInvites { var index: Int32 = 0 for invite in additionalInvites { - entries.append(.link(index, presentationData.theme, invite, canEditLinks, invite.expireDate != nil ? tick : nil)) - index += 1 + if case let .link(_, _, _, _, _, _, _, _, expireDate, _, _, _) = invite { + entries.append(.link(index, presentationData.theme, invite, canEditLinks, expireDate != nil ? tick : nil)) + index += 1 + } } } else if let admin = admin, admin.count > 1 { var index: Int32 = 0 @@ -427,7 +429,10 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio } let arguments = InviteLinkListControllerArguments(context: context, shareMainLink: { invite in - let shareController = ShareController(context: context, subject: .url(invite.link), updatedPresentationData: updatedPresentationData) + guard let inviteLink = invite.link else { + return + } + let shareController = ShareController(context: context, subject: .url(inviteLink), updatedPresentationData: updatedPresentationData) shareController.completed = { peerIds in let _ = (context.account.postbox.transaction { transaction -> [Peer] in var peers: [Peer] = [] @@ -516,7 +521,7 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio }) }))) - if invite.adminId.toInt64() != 0 { + if case let .link(_, _, _, _, _, adminId, _, _, _, _, _, _) = invite, adminId.toInt64() != 0 { items.append(.action(ContextMenuActionItem(text: presentationData.strings.InviteLink_ContextRevoke, textColor: .destructive, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor) }, action: { _, f in @@ -552,8 +557,8 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio return state } } - if revoke { - revokeLinkDisposable.set((context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: invite.link) |> deliverOnMainQueue).start(next: { result in + if revoke, let inviteLink = invite.link { + revokeLinkDisposable.set((context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: inviteLink) |> deliverOnMainQueue).start(next: { result in updateState { state in var updatedState = state updatedState.revokingPrivateLink = false @@ -626,8 +631,12 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor) }, action: { _, f in f(.default) + + guard let inviteLink = invite.link else { + return + } - let shareController = ShareController(context: context, subject: .url(invite.link), updatedPresentationData: updatedPresentationData) + let shareController = ShareController(context: context, subject: .url(inviteLink), updatedPresentationData: updatedPresentationData) shareController.completed = { peerIds in let _ = (context.account.postbox.transaction { transaction -> [Peer] in var peers: [Peer] = [] @@ -729,8 +738,9 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio ActionSheetButtonItem(title: presentationData.strings.InviteLink_DeleteLinkAlert_Action, color: .destructive, action: { dismissAction() - revokeLinkDisposable.set((context.engine.peers.deletePeerExportedInvitation(peerId: peerId, link: invite.link) |> deliverOnMainQueue).start(completed: { - })) + if let inviteLink = invite.link { + revokeLinkDisposable.set((context.engine.peers.deletePeerExportedInvitation(peerId: peerId, link: inviteLink) |> deliverOnMainQueue).start()) + } revokedInvitesContext.remove(invite) }) @@ -763,11 +773,13 @@ public func inviteLinkListController(context: AccountContext, updatedPresentatio ActionSheetButtonItem(title: presentationData.strings.GroupInfo_InviteLink_RevokeLink, color: .destructive, action: { dismissAction() - revokeLinkDisposable.set((context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: invite.link) |> deliverOnMainQueue).start(next: { result in - if case let .replace(_, newInvite) = result { - invitesContext.add(newInvite) - } - })) + if let inviteLink = invite.link { + revokeLinkDisposable.set((context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: inviteLink) |> deliverOnMainQueue).start(next: { result in + if case let .replace(_, newInvite) = result { + invitesContext.add(newInvite) + } + })) + } invitesContext.remove(invite) revokedInvitesContext.add(invite.withUpdated(isRevoked: true)) diff --git a/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift b/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift index 4db8bcf841..d9b22aecdc 100644 --- a/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift +++ b/submodules/InviteLinksUI/Sources/InviteLinkViewController.swift @@ -416,7 +416,7 @@ public final class InviteLinkViewController: ViewController { self.controller = controller self.importersContext = importersContext ?? context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .invite(invite: invite, requested: false)) - if invite.requestApproval { + if case let .link(_, _, _, requestApproval, _, _, _, _, _, _, _, _) = invite, requestApproval { self.requestsContext = context.engine.peers.peerInvitationImporters(peerId: peerId, subject: .invite(invite: invite, requested: true)) } else { self.requestsContext = nil @@ -483,7 +483,10 @@ public final class InviteLinkViewController: ViewController { let presentationData = context.sharedContext.currentPresentationData.with { $0 } self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root)) }, shareLink: { [weak self] invite in - let shareController = ShareController(context: context, subject: .url(invite.link)) + guard let inviteLink = invite.link else { + return + } + let shareController = ShareController(context: context, subject: .url(inviteLink)) shareController.completed = { [weak self] peerIds in if let strongSelf = self { let _ = (strongSelf.context.account.postbox.transaction { transaction -> [Peer] in @@ -569,8 +572,9 @@ public final class InviteLinkViewController: ViewController { dismissAction() self?.controller?.dismiss() - let _ = (context.engine.peers.deletePeerExportedInvitation(peerId: peerId, link: invite.link) |> deliverOnMainQueue).start(completed: { - }) + if let inviteLink = invite.link { + let _ = (context.engine.peers.deletePeerExportedInvitation(peerId: peerId, link: inviteLink) |> deliverOnMainQueue).start() + } self?.controller?.revokedInvitationsContext?.remove(invite) }) @@ -626,11 +630,13 @@ public final class InviteLinkViewController: ViewController { dismissAction() self?.controller?.dismiss() - let _ = (context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: invite.link) |> deliverOnMainQueue).start(next: { result in - if case let .replace(_, newInvite) = result { - self?.controller?.invitationsContext?.add(newInvite) - } - }) + if let inviteLink = invite.link { + let _ = (context.engine.peers.revokePeerExportedInvitation(peerId: peerId, link: inviteLink) |> deliverOnMainQueue).start(next: { result in + if case let .replace(_, newInvite) = result { + self?.controller?.invitationsContext?.add(newInvite) + } + }) + } self?.controller?.invitationsContext?.remove(invite) let revokedInvite = invite.withUpdated(isRevoked: true) @@ -662,93 +668,98 @@ public final class InviteLinkViewController: ViewController { requestsState = .single(PeerInvitationImportersState.Empty) } - let creatorPeer = context.account.postbox.loadedPeerWithId(invite.adminId) - self.disposable = (combineLatest(self.presentationDataPromise.get(), self.importersContext.state, requestsState, creatorPeer) - |> deliverOnMainQueue).start(next: { [weak self] presentationData, state, requestsState, creatorPeer in - if let strongSelf = self { - var entries: [InviteLinkViewEntry] = [] - - entries.append(.link(presentationData.theme, invite)) - entries.append(.creatorHeader(presentationData.theme, presentationData.strings.InviteLink_CreatedBy.uppercased())) - entries.append(.creator(presentationData.theme, presentationData.dateTimeFormat, EnginePeer(creatorPeer), invite.date)) - - if !requestsState.importers.isEmpty || (state.isLoadingMore && requestsState.count > 0) { - entries.append(.requestHeader(presentationData.theme, presentationData.strings.MemberRequests_PeopleRequested(Int32(requestsState.count)).uppercased(), "", false)) - } - - var count: Int32 - var loading: Bool - var index: Int32 = 0 - if requestsState.importers.isEmpty && requestsState.isLoadingMore { - count = min(4, state.count) - loading = true - let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) - for i in 0 ..< count { - entries.append(.request(Int32(i), presentationData.theme, presentationData.dateTimeFormat, EnginePeer.user(fakeUser), 0, true)) + if case let .link(_, _, _, _, _, adminId, date, _, _, usageLimit, _, _) = invite { + self.disposable = (combineLatest( + self.presentationDataPromise.get(), + self.importersContext.state, + requestsState, + context.account.postbox.loadedPeerWithId(adminId) + ) |> deliverOnMainQueue).start(next: { [weak self] presentationData, state, requestsState, creatorPeer in + if let strongSelf = self { + var entries: [InviteLinkViewEntry] = [] + + entries.append(.link(presentationData.theme, invite)) + entries.append(.creatorHeader(presentationData.theme, presentationData.strings.InviteLink_CreatedBy.uppercased())) + entries.append(.creator(presentationData.theme, presentationData.dateTimeFormat, EnginePeer(creatorPeer), date)) + + if !requestsState.importers.isEmpty || (state.isLoadingMore && requestsState.count > 0) { + entries.append(.requestHeader(presentationData.theme, presentationData.strings.MemberRequests_PeopleRequested(Int32(requestsState.count)).uppercased(), "", false)) } - } else { - count = min(4, Int32(requestsState.importers.count)) - loading = false - for importer in requestsState.importers { - if let peer = importer.peer.peer { - entries.append(.request(index, presentationData.theme, presentationData.dateTimeFormat, EnginePeer(peer), importer.date, false)) + + var count: Int32 + var loading: Bool + var index: Int32 = 0 + if requestsState.importers.isEmpty && requestsState.isLoadingMore { + count = min(4, state.count) + loading = true + let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) + for i in 0 ..< count { + entries.append(.request(Int32(i), presentationData.theme, presentationData.dateTimeFormat, EnginePeer.user(fakeUser), 0, true)) } - index += 1 - } - } - - if !state.importers.isEmpty || (state.isLoadingMore && state.count > 0) { - let subtitle: String - let subtitleExpired: Bool - if let usageLimit = invite.usageLimit { - let remaining = max(0, usageLimit - state.count) - subtitle = presentationData.strings.InviteLink_PeopleRemaining(remaining).uppercased() - subtitleExpired = remaining <= 0 } else { - subtitle = "" - subtitleExpired = false - } - - entries.append(.importerHeader(presentationData.theme, presentationData.strings.InviteLink_PeopleJoined(Int32(state.count)).uppercased(), subtitle, subtitleExpired)) - } - - index = 0 - if state.importers.isEmpty && state.isLoadingMore { - count = min(4, state.count) - loading = true - let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) - for i in 0 ..< count { - entries.append(.importer(Int32(i), presentationData.theme, presentationData.dateTimeFormat, EnginePeer.user(fakeUser), 0, true)) - } - } else { - count = min(4, Int32(state.importers.count)) - loading = false - for importer in state.importers { - if let peer = importer.peer.peer { - entries.append(.importer(index, presentationData.theme, presentationData.dateTimeFormat, EnginePeer(peer), importer.date, false)) + count = min(4, Int32(requestsState.importers.count)) + loading = false + for importer in requestsState.importers { + if let peer = importer.peer.peer { + entries.append(.request(index, presentationData.theme, presentationData.dateTimeFormat, EnginePeer(peer), importer.date, false)) + } + index += 1 } - index += 1 } - } - - let previousCount = previousCount.swap(count) - let previousLoading = previousLoading.swap(loading) - - var animated = false - var crossfade = false - if let previousCount = previousCount, let previousLoading = previousLoading { - if (previousCount == count || previousCount >= 4) && previousLoading && !loading { - crossfade = true - } else if previousCount < 4 && previousCount != count && !loading { - animated = true + + if !state.importers.isEmpty || (state.isLoadingMore && state.count > 0) { + let subtitle: String + let subtitleExpired: Bool + if let usageLimit = usageLimit { + let remaining = max(0, usageLimit - state.count) + subtitle = presentationData.strings.InviteLink_PeopleRemaining(remaining).uppercased() + subtitleExpired = remaining <= 0 + } else { + subtitle = "" + subtitleExpired = false + } + + entries.append(.importerHeader(presentationData.theme, presentationData.strings.InviteLink_PeopleJoined(Int32(state.count)).uppercased(), subtitle, subtitleExpired)) } + + index = 0 + if state.importers.isEmpty && state.isLoadingMore { + count = min(4, state.count) + loading = true + let fakeUser = TelegramUser(id: EnginePeer.Id(namespace: .max, id: EnginePeer.Id.Id._internalFromInt64Value(0)), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: []) + for i in 0 ..< count { + entries.append(.importer(Int32(i), presentationData.theme, presentationData.dateTimeFormat, EnginePeer.user(fakeUser), 0, true)) + } + } else { + count = min(4, Int32(state.importers.count)) + loading = false + for importer in state.importers { + if let peer = importer.peer.peer { + entries.append(.importer(index, presentationData.theme, presentationData.dateTimeFormat, EnginePeer(peer), importer.date, false)) + } + index += 1 + } + } + + let previousCount = previousCount.swap(count) + let previousLoading = previousLoading.swap(loading) + + var animated = false + var crossfade = false + if let previousCount = previousCount, let previousLoading = previousLoading { + if (previousCount == count || previousCount >= 4) && previousLoading && !loading { + crossfade = true + } else if previousCount < 4 && previousCount != count && !loading { + animated = true + } + } + let previousEntries = previousEntries.swap(entries) + + let transition = preparedTransition(from: previousEntries ?? [], to: entries, isLoading: false, animated: animated, crossfade: crossfade, account: context.account, presentationData: presentationData, interaction: strongSelf.interaction!) + strongSelf.enqueueTransition(transition) } - let previousEntries = previousEntries.swap(entries) - - let transition = preparedTransition(from: previousEntries ?? [], to: entries, isLoading: false, animated: animated, crossfade: crossfade, account: context.account, presentationData: presentationData, interaction: strongSelf.interaction!) - strongSelf.enqueueTransition(transition) - } - }) + }) + } self.listNode.preloadPages = true self.listNode.stackFromBottom = true @@ -940,43 +951,45 @@ public final class InviteLinkViewController: ViewController { transition.updateFrame(node: self.headerBackgroundNode, frame: CGRect(x: 0.0, y: 0.0, width: layout.size.width, height: 68.0)) var titleText = self.presentationData.strings.InviteLink_InviteLink - var subtitleText = "" var subtitleColor = self.presentationData.theme.list.itemSecondaryTextColor - if self.invite.isRevoked { - subtitleText = self.presentationData.strings.InviteLink_Revoked - } else if let usageLimit = self.invite.usageLimit, let count = self.invite.count, count >= usageLimit { - subtitleText = self.presentationData.strings.InviteLink_UsageLimitReached - subtitleColor = self.presentationData.theme.list.itemDestructiveColor - } else if let expireDate = self.invite.expireDate { - let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) - if currentTime >= expireDate { - titleText = self.presentationData.strings.InviteLink_ExpiredLink - subtitleText = self.presentationData.strings.InviteLink_ExpiredLinkStatus + + if case let .link(_, title, _, _, isRevoked, _, _, _, expireDate, usageLimit, count, _) = self.invite { + if isRevoked { + subtitleText = self.presentationData.strings.InviteLink_Revoked + } else if let usageLimit = usageLimit, let count = count, count >= usageLimit { + subtitleText = self.presentationData.strings.InviteLink_UsageLimitReached subtitleColor = self.presentationData.theme.list.itemDestructiveColor - self.countdownTimer?.invalidate() - self.countdownTimer = nil - } else { - let elapsedTime = expireDate - currentTime - if elapsedTime >= 86400 { - subtitleText = self.presentationData.strings.InviteLink_ExpiresIn(scheduledTimeIntervalString(strings: self.presentationData.strings, value: elapsedTime)).string + } else if let expireDate = expireDate { + let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) + if currentTime >= expireDate { + titleText = self.presentationData.strings.InviteLink_ExpiredLink + subtitleText = self.presentationData.strings.InviteLink_ExpiredLinkStatus + subtitleColor = self.presentationData.theme.list.itemDestructiveColor + self.countdownTimer?.invalidate() + self.countdownTimer = nil } else { - subtitleText = self.presentationData.strings.InviteLink_ExpiresIn(textForTimeout(value: elapsedTime)).string - if self.countdownTimer == nil { - let countdownTimer = SwiftSignalKit.Timer(timeout: 1.0, repeat: true, completion: { [weak self] in - if let strongSelf = self, let layout = strongSelf.validLayout { - strongSelf.containerLayoutUpdated(layout, transition: .immediate) - } - }, queue: Queue.mainQueue()) - self.countdownTimer = countdownTimer - countdownTimer.start() + let elapsedTime = expireDate - currentTime + if elapsedTime >= 86400 { + subtitleText = self.presentationData.strings.InviteLink_ExpiresIn(scheduledTimeIntervalString(strings: self.presentationData.strings, value: elapsedTime)).string + } else { + subtitleText = self.presentationData.strings.InviteLink_ExpiresIn(textForTimeout(value: elapsedTime)).string + if self.countdownTimer == nil { + let countdownTimer = SwiftSignalKit.Timer(timeout: 1.0, repeat: true, completion: { [weak self] in + if let strongSelf = self, let layout = strongSelf.validLayout { + strongSelf.containerLayoutUpdated(layout, transition: .immediate) + } + }, queue: Queue.mainQueue()) + self.countdownTimer = countdownTimer + countdownTimer.start() + } } } } - } - if let title = self.invite.title, !title.isEmpty { - titleText = title + if let title = title, !title.isEmpty { + titleText = title + } } self.titleNode.attributedText = NSAttributedString(string: titleText, font: Font.bold(17.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor) diff --git a/submodules/InviteLinksUI/Sources/ItemListInviteLinkItem.swift b/submodules/InviteLinksUI/Sources/ItemListInviteLinkItem.swift index 2379ca45f5..9d72e3b33f 100644 --- a/submodules/InviteLinksUI/Sources/ItemListInviteLinkItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListInviteLinkItem.swift @@ -9,21 +9,25 @@ import ShimmerEffect import TelegramCore func invitationAvailability(_ invite: ExportedInvitation) -> CGFloat { - if invite.isRevoked { - return 0.0 + if case let .link(_, _, _, _, isRevoked, _, date, startDate, expireDate, usageLimit, count, _) = invite { + if isRevoked { + return 0.0 + } + let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) + var availability: CGFloat = 1.0 + if let expireDate = expireDate { + let startDate = startDate ?? date + let fraction = CGFloat(expireDate - currentTime) / CGFloat(expireDate - startDate) + availability = min(fraction, availability) + } + if let usageLimit = usageLimit, let count = count { + let fraction = 1.0 - (CGFloat(count) / CGFloat(usageLimit)) + availability = min(fraction, availability) + } + return max(0.0, min(1.0, availability)) + } else { + return 1.0 } - let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) - var availability: CGFloat = 1.0 - if let expireDate = invite.expireDate { - let startDate = invite.startDate ?? invite.date - let fraction = CGFloat(expireDate - currentTime) / CGFloat(expireDate - startDate) - availability = min(fraction, availability) - } - if let usageLimit = invite.usageLimit, let count = invite.count { - let fraction = 1.0 - (CGFloat(count) / CGFloat(usageLimit)) - availability = min(fraction, availability) - } - return max(0.0, min(1.0, availability)) } private enum ItemBackgroundColor: Equatable { @@ -295,12 +299,12 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode { let color: ItemBackgroundColor let nextColor: ItemBackgroundColor let transitionFraction: CGFloat - if let invite = item.invite { - if invite.isRevoked { + if let invite = item.invite, case let .link(_, _, _, _, isRevoked, _, _, _, expireDate, usageLimit, _, _) = invite { + if isRevoked { color = .gray nextColor = .gray transitionFraction = 0.0 - } else if invite.expireDate == nil && invite.usageLimit == nil { + } else if expireDate == nil && usageLimit == nil { color = .blue nextColor = .blue transitionFraction = 0.0 @@ -336,22 +340,24 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode { iconColor = item.presentationData.theme.list.mediaPlaceholderColor } - let inviteLink = item.invite?.link.replacingOccurrences(of: "https://", with: "") ?? "" + let inviteLink = item.invite?.link?.replacingOccurrences(of: "https://", with: "") ?? "" var titleText = inviteLink - if let title = item.invite?.title, !title.isEmpty { - titleText = title - } - var subtitleText: String = "" var timerValue: TimerNode.Value? - if let invite = item.invite { - let count = invite.count ?? 0 - let requestedCount = invite.requestedCount ?? 0 + + + if let invite = item.invite, case let .link(_, title, _, _, _, _, date, startDate, expireDate, usageLimit, count, requestedCount) = invite { + if let title = title, !title.isEmpty { + titleText = title + } + + let count = count ?? 0 + let requestedCount = requestedCount ?? 0 if count > 0 { subtitleText = item.presentationData.strings.InviteLink_PeopleJoinedShort(count) } else { - if let usageLimit = invite.usageLimit, count == 0 && !availability.isZero { + if let usageLimit = usageLimit, count == 0 && !availability.isZero { subtitleText = item.presentationData.strings.InviteLink_PeopleCanJoin(usageLimit) } else { if availability.isZero { @@ -376,12 +382,12 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode { subtitleText += item.presentationData.strings.InviteLink_Revoked } else { var isExpired = false - if let expireDate = invite.expireDate, currentTime >= expireDate { + if let expireDate = expireDate, currentTime >= expireDate { isExpired = true } var isFull = false - if let usageLimit = invite.usageLimit { + if let usageLimit = usageLimit { if !isExpired { let remaining = usageLimit - count if remaining > 0 && remaining != usageLimit { @@ -401,7 +407,7 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode { } } } - if let expireDate = invite.expireDate, !isFull { + if let expireDate = expireDate, !isFull { if !isExpired { if !subtitleText.isEmpty { subtitleText += " • " @@ -413,7 +419,7 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode { subtitleText += item.presentationData.strings.InviteLink_ExpiresIn(textForTimeout(value: elapsedTime)).string } if timerValue == nil { - timerValue = .timestamp(creation: invite.startDate ?? invite.date, deadline: expireDate) + timerValue = .timestamp(creation: startDate ?? date, deadline: expireDate) } } else { if !subtitleText.isEmpty { diff --git a/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift b/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift index 298879444e..f02f7dbf8d 100644 --- a/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift +++ b/submodules/InviteLinksUI/Sources/ItemListPermanentInviteLinkItem.swift @@ -300,14 +300,14 @@ public class ItemListPermanentInviteLinkItemNode: ListViewItemNode, ItemListItem let titleColor: UIColor titleColor = item.presentationData.theme.list.itemInputField.primaryColor - let alignCentrally = !(item.invite?.link.contains("joinchat") ?? true) + let alignCentrally = !(item.invite?.link?.contains("joinchat") ?? true) let addressFont = Font.regular(!alignCentrally && params.width == 320 ? floor(item.presentationData.fontSize.itemListBaseFontSize * 15.0 / 17.0) : item.presentationData.fontSize.itemListBaseFontSize) let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseFontSize) let constrainedWidth = alignCentrally ? params.width - leftInset - rightInset - 90.0 : params.width - leftInset - rightInset - 60.0 - let (addressLayout, addressApply) = makeAddressLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.invite.flatMap({ $0.link.replacingOccurrences(of: "https://", with: "") }) ?? "", font: addressFont, textColor: titleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .middle, constrainedSize: CGSize(width: constrainedWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (addressLayout, addressApply) = makeAddressLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.invite.flatMap({ $0.link?.replacingOccurrences(of: "https://", with: "") }) ?? "", font: addressFont, textColor: titleColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .middle, constrainedSize: CGSize(width: constrainedWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) let subtitle: String let subtitleColor: UIColor diff --git a/submodules/ItemListUI/BUILD b/submodules/ItemListUI/BUILD index af5616e0d6..e2a17f9755 100644 --- a/submodules/ItemListUI/BUILD +++ b/submodules/ItemListUI/BUILD @@ -26,6 +26,7 @@ swift_library( "//submodules/AccountContext:AccountContext", "//submodules/AnimationUI:AnimationUI", "//submodules/ShimmerEffect:ShimmerEffect", + "//submodules/ManagedAnimationNode:ManagedAnimationNode", ], visibility = [ "//visibility:public", diff --git a/submodules/ItemListUI/Sources/ItemListRevealOptionsNode.swift b/submodules/ItemListUI/Sources/ItemListRevealOptionsNode.swift index f426a1a418..0a0ae7e0b8 100644 --- a/submodules/ItemListUI/Sources/ItemListRevealOptionsNode.swift +++ b/submodules/ItemListUI/Sources/ItemListRevealOptionsNode.swift @@ -2,12 +2,12 @@ import Foundation import UIKit import AsyncDisplayKit import Display -import AnimationUI +import ManagedAnimationNode public enum ItemListRevealOptionIcon: Equatable { case none case image(image: UIImage) - case animation(animation: String, scale: CGFloat, offset: CGFloat, keysToColor: [String]?, flip: Bool) + case animation(animation: String, scale: CGFloat, offset: CGFloat, replaceColors: [UInt32]?, flip: Bool) public static func ==(lhs: ItemListRevealOptionIcon, rhs: ItemListRevealOptionIcon) -> Bool { switch lhs { @@ -81,7 +81,8 @@ private final class ItemListRevealOptionNode: ASDisplayNode { private let highlightNode: ASDisplayNode private let titleNode: ASTextNode private let iconNode: ASImageNode? - private let animationNode: AnimationNode? + private let animationNode: SimpleAnimationNode? + private var animationNodeOffset: CGFloat = 0.0 private var animationNodeFlip = false var alignment: ItemListRevealOptionAlignment? @@ -101,15 +102,15 @@ private final class ItemListRevealOptionNode: ASDisplayNode { self.iconNode = iconNode self.animationNode = nil - case let .animation(animation, scale, offset, keysToColor, flip): + case let .animation(animation, _, offset, replaceColors, flip): self.iconNode = nil - var colors: [String: UIColor] = [:] - if let keysToColor = keysToColor { - for key in keysToColor { - colors[key] = color + var colors: [UInt32: UInt32] = [:] + if let replaceColors = replaceColors { + for colorToReplace in replaceColors { + colors[colorToReplace] = color.rgb } } - self.animationNode = AnimationNode(animation: animation, colors: colors, scale: scale) + self.animationNode = SimpleAnimationNode(animationName: animation, replaceColors: colors, size: CGSize(width: 79.0, height: 79.0), playOnce: true) if flip { self.animationNode!.transform = CATransform3DMakeScale(1.0, -1.0, 1.0) } @@ -192,7 +193,8 @@ private final class ItemListRevealOptionNode: ASDisplayNode { contentRect.origin.x = extendedWidth - contentRect.width } - if let animationNode = self.animationNode, let imageSize = animationNode.preferredSize() { + if let animationNode = self.animationNode { + let imageSize = animationNode.size let iconOffset: CGFloat = -2.0 + self.animationNodeOffset let titleIconSpacing: CGFloat = 11.0 let iconFrame = CGRect(origin: CGPoint(x: contentRect.minX + floor((baseSize.width - imageSize.width + sideInset) / 2.0), y: contentRect.midY - imageSize.height / 2.0 + iconOffset), size: imageSize) diff --git a/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift b/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift index 73fd720359..1ac340666c 100644 --- a/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift +++ b/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift @@ -46,7 +46,7 @@ public final class ManagedAnimationState { } else if let unpackedData = TGGUnzipData(data, 5 * 1024 * 1024) { data = unpackedData } - guard let instance = LottieInstance(data: data, fitzModifier: .none, cacheKey: item.source.cacheKey) else { + guard let instance = LottieInstance(data: data, fitzModifier: .none, colorReplacements: item.replaceColors, cacheKey: item.source.cacheKey) else { return nil } resolvedInstance = instance @@ -123,13 +123,15 @@ public enum ManagedAnimationSource: Equatable { public struct ManagedAnimationItem { public let source: ManagedAnimationSource + public let replaceColors: [UInt32: UInt32]? public var frames: ManagedAnimationFrameRange? public var duration: Double? public var loop: Bool var callbacks: [(Int, () -> Void)] - public init(source: ManagedAnimationSource, frames: ManagedAnimationFrameRange? = nil, duration: Double? = nil, loop: Bool = false, callbacks: [(Int, () -> Void)] = []) { + public init(source: ManagedAnimationSource, replaceColors: [UInt32: UInt32]? = nil, frames: ManagedAnimationFrameRange? = nil, duration: Double? = nil, loop: Bool = false, callbacks: [(Int, () -> Void)] = []) { self.source = source + self.replaceColors = replaceColors self.frames = frames self.duration = duration self.loop = loop @@ -316,3 +318,35 @@ open class ManagedAnimationNode: ASDisplayNode { self.imageNode.position = CGPoint(x: self.bounds.width / 2.0, y: self.bounds.height / 2.0) } } + +public final class SimpleAnimationNode: ManagedAnimationNode { + private let stillItem: ManagedAnimationItem + private let animationItem: ManagedAnimationItem + + public let size: CGSize + private let playOnce: Bool + public private(set) var didPlay = false + + public init(animationName: String, replaceColors: [UInt32: UInt32]? = nil, size: CGSize, playOnce: Bool = false) { + self.size = size + self.playOnce = playOnce + self.stillItem = ManagedAnimationItem(source: .local(animationName), replaceColors: replaceColors, frames: .range(startFrame: 0, endFrame: 0), duration: 0.01) + self.animationItem = ManagedAnimationItem(source: .local(animationName), replaceColors: replaceColors) + + super.init(size: size) + + self.trackTo(item: self.stillItem) + } + + public func play() { + if !self.playOnce || !self.didPlay { + self.didPlay = true + self.trackTo(item: self.animationItem) + } + } + + public func reset() { + self.didPlay = false + self.trackTo(item: self.stillItem) + } +} diff --git a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift index 2e89f127f4..6bc2c4de59 100644 --- a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift @@ -36,8 +36,10 @@ private final class ChannelVisibilityControllerArguments { let manageInviteLinks: () -> Void let openLink: (ExportedInvitation) -> Void let toggleForwarding: (Bool) -> Void + let updateJoinToSend: (CurrentChannelJoinToSend) -> Void + let toggleApproveMembers: (Bool) -> Void - init(context: AccountContext, updateCurrentType: @escaping (CurrentChannelType) -> Void, updatePublicLinkText: @escaping (String?, String) -> Void, scrollToPublicLinkText: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, revokePeerId: @escaping (PeerId) -> Void, copyLink: @escaping (ExportedInvitation) -> Void, shareLink: @escaping (ExportedInvitation) -> Void, linkContextAction: @escaping (ASDisplayNode, ContextGesture?) -> Void, manageInviteLinks: @escaping () -> Void, openLink: @escaping (ExportedInvitation) -> Void, toggleForwarding: @escaping (Bool) -> Void) { + init(context: AccountContext, updateCurrentType: @escaping (CurrentChannelType) -> Void, updatePublicLinkText: @escaping (String?, String) -> Void, scrollToPublicLinkText: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, revokePeerId: @escaping (PeerId) -> Void, copyLink: @escaping (ExportedInvitation) -> Void, shareLink: @escaping (ExportedInvitation) -> Void, linkContextAction: @escaping (ASDisplayNode, ContextGesture?) -> Void, manageInviteLinks: @escaping () -> Void, openLink: @escaping (ExportedInvitation) -> Void, toggleForwarding: @escaping (Bool) -> Void, updateJoinToSend: @escaping (CurrentChannelJoinToSend) -> Void, toggleApproveMembers: @escaping (Bool) -> Void) { self.context = context self.updateCurrentType = updateCurrentType self.updatePublicLinkText = updatePublicLinkText @@ -50,6 +52,8 @@ private final class ChannelVisibilityControllerArguments { self.manageInviteLinks = manageInviteLinks self.openLink = openLink self.toggleForwarding = toggleForwarding + self.updateJoinToSend = updateJoinToSend + self.toggleApproveMembers = toggleApproveMembers } } @@ -57,6 +61,8 @@ private enum ChannelVisibilitySection: Int32 { case type case link case linkActions + case joinToSend + case approveMembers case forwarding } @@ -94,6 +100,13 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry { case existingLinksInfo(PresentationTheme, String) case existingLinkPeerItem(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, Peer, ItemListPeerItemEditing, Bool) + case joinToSendHeader(PresentationTheme, String) + case joinToSendEveryone(PresentationTheme, String, Bool) + case joinToSendMembers(PresentationTheme, String, Bool) + + case approveMembers(PresentationTheme, String, Bool) + case approveMembersInfo(PresentationTheme, String) + case forwardingHeader(PresentationTheme, String) case forwardingDisabled(PresentationTheme, String, Bool) case forwardingInfo(PresentationTheme, String) @@ -108,6 +121,10 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry { return ChannelVisibilitySection.linkActions.rawValue case .existingLinksInfo, .existingLinkPeerItem: return ChannelVisibilitySection.link.rawValue + case .joinToSendHeader, .joinToSendEveryone, .joinToSendMembers: + return ChannelVisibilitySection.joinToSend.rawValue + case .approveMembers, .approveMembersInfo: + return ChannelVisibilitySection.approveMembers.rawValue case .forwardingHeader, .forwardingDisabled, .forwardingInfo: return ChannelVisibilitySection.forwarding.rawValue } @@ -147,12 +164,22 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry { return 1000 case .privateLinkManageInfo: return 1001 - case .forwardingHeader: + case .joinToSendHeader: return 1002 - case .forwardingDisabled: + case .joinToSendEveryone: return 1003 - case .forwardingInfo: + case .joinToSendMembers: return 1004 + case .approveMembers: + return 1005 + case .approveMembersInfo: + return 1006 + case .forwardingHeader: + return 1007 + case .forwardingDisabled: + return 1008 + case .forwardingInfo: + return 1009 } } @@ -278,6 +305,36 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry { } else { return false } + case let .joinToSendHeader(lhsTheme, lhsText): + if case let .joinToSendHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { + return true + } else { + return false + } + case let .joinToSendEveryone(lhsTheme, lhsText, lhsValue): + if case let .joinToSendEveryone(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { + return true + } else { + return false + } + case let .joinToSendMembers(lhsTheme, lhsText, lhsValue): + if case let .joinToSendMembers(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { + return true + } else { + return false + } + case let .approveMembers(lhsTheme, lhsText, lhsValue): + if case let .approveMembers(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { + return true + } else { + return false + } + case let .approveMembersInfo(lhsTheme, lhsText): + if case let .approveMembersInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { + return true + } else { + return false + } case let .forwardingHeader(lhsTheme, lhsText): if case let .forwardingHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { return true @@ -393,6 +450,22 @@ private enum ChannelVisibilityEntry: ItemListNodeEntry { }, removePeer: { peerId in arguments.revokePeerId(peerId) }) + case let .joinToSendHeader(_, title): + return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section) + case let .joinToSendEveryone(_, text, selected): + return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: { + arguments.updateJoinToSend(.everyone) + }) + case let .joinToSendMembers(_, text, selected): + return ItemListCheckboxItem(presentationData: presentationData, title: text, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: { + arguments.updateJoinToSend(.members) + }) + case let .approveMembers(_, text, selected): + return ItemListSwitchItem(presentationData: presentationData, title: text, value: selected, sectionId: self.section, style: .blocks, updated: { value in + arguments.toggleApproveMembers(value) + }) + case let .approveMembersInfo(_, text): + return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section) case let .forwardingHeader(_, title): return ItemListSectionHeaderItem(presentationData: presentationData, text: title, sectionId: self.section) case let .forwardingDisabled(_, text, selected): @@ -415,6 +488,11 @@ private enum CurrentChannelLocation: Equatable { case location(PeerGeoLocation) } +private enum CurrentChannelJoinToSend { + case everyone + case members +} + private struct ChannelVisibilityControllerState: Equatable { let selectedType: CurrentChannelType? let editingPublicLinkText: String? @@ -424,6 +502,8 @@ private struct ChannelVisibilityControllerState: Equatable { let revokingPeerId: PeerId? let revokingPrivateLink: Bool let forwardingEnabled: Bool? + let joinToSend: CurrentChannelJoinToSend? + let approveMembers: Bool? init() { self.selectedType = nil @@ -434,9 +514,11 @@ private struct ChannelVisibilityControllerState: Equatable { self.revokingPeerId = nil self.revokingPrivateLink = false self.forwardingEnabled = nil + self.joinToSend = nil + self.approveMembers = nil } - init(selectedType: CurrentChannelType?, editingPublicLinkText: String?, addressNameValidationStatus: AddressNameValidationStatus?, updatingAddressName: Bool, revealedRevokePeerId: PeerId?, revokingPeerId: PeerId?, revokingPrivateLink: Bool, forwardingEnabled: Bool?) { + init(selectedType: CurrentChannelType?, editingPublicLinkText: String?, addressNameValidationStatus: AddressNameValidationStatus?, updatingAddressName: Bool, revealedRevokePeerId: PeerId?, revokingPeerId: PeerId?, revokingPrivateLink: Bool, forwardingEnabled: Bool?, joinToSend: CurrentChannelJoinToSend?, approveMembers: Bool?) { self.selectedType = selectedType self.editingPublicLinkText = editingPublicLinkText self.addressNameValidationStatus = addressNameValidationStatus @@ -445,6 +527,8 @@ private struct ChannelVisibilityControllerState: Equatable { self.revokingPeerId = revokingPeerId self.revokingPrivateLink = revokingPrivateLink self.forwardingEnabled = forwardingEnabled + self.joinToSend = joinToSend + self.approveMembers = approveMembers } static func ==(lhs: ChannelVisibilityControllerState, rhs: ChannelVisibilityControllerState) -> Bool { @@ -472,39 +556,53 @@ private struct ChannelVisibilityControllerState: Equatable { if lhs.forwardingEnabled != rhs.forwardingEnabled { return false } + if lhs.joinToSend != rhs.joinToSend { + return false + } + if lhs.approveMembers != rhs.approveMembers { + return false + } return true } func withUpdatedSelectedType(_ selectedType: CurrentChannelType?) -> ChannelVisibilityControllerState { - return ChannelVisibilityControllerState(selectedType: selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: self.updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled) + return ChannelVisibilityControllerState(selectedType: selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: self.updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled, joinToSend: self.joinToSend, approveMembers: self.approveMembers) } func withUpdatedEditingPublicLinkText(_ editingPublicLinkText: String?) -> ChannelVisibilityControllerState { - return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: self.updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled) + return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: self.updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled, joinToSend: self.joinToSend, approveMembers: self.approveMembers) } func withUpdatedAddressNameValidationStatus(_ addressNameValidationStatus: AddressNameValidationStatus?) -> ChannelVisibilityControllerState { - return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: addressNameValidationStatus, updatingAddressName: self.updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled) + return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: addressNameValidationStatus, updatingAddressName: self.updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled, joinToSend: self.joinToSend, approveMembers: self.approveMembers) } func withUpdatedUpdatingAddressName(_ updatingAddressName: Bool) -> ChannelVisibilityControllerState { - return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled) + return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled, joinToSend: self.joinToSend, approveMembers: self.approveMembers) } func withUpdatedRevealedRevokePeerId(_ revealedRevokePeerId: PeerId?) -> ChannelVisibilityControllerState { - return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled) + return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled, joinToSend: self.joinToSend, approveMembers: self.approveMembers) } func withUpdatedRevokingPeerId(_ revokingPeerId: PeerId?) -> ChannelVisibilityControllerState { - return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled) + return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled, joinToSend: self.joinToSend, approveMembers: self.approveMembers) } func withUpdatedRevokingPrivateLink(_ revokingPrivateLink: Bool) -> ChannelVisibilityControllerState { - return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: revokingPrivateLink, forwardingEnabled: self.forwardingEnabled) + return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: revokingPrivateLink, forwardingEnabled: self.forwardingEnabled, joinToSend: self.joinToSend, approveMembers: self.approveMembers) } func withUpdatedForwardingEnabled(_ forwardingEnabled: Bool) -> ChannelVisibilityControllerState { - return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: forwardingEnabled) + return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: forwardingEnabled, joinToSend: self.joinToSend, approveMembers: self.approveMembers) + } + + func withUpdatedJoinToSend(_ joinToSend: CurrentChannelJoinToSend?) -> ChannelVisibilityControllerState { + return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled, joinToSend: joinToSend, approveMembers: self.approveMembers) + } + + func withUpdatedApproveMembers(_ approveMembers: Bool) -> ChannelVisibilityControllerState { + return ChannelVisibilityControllerState(selectedType: self.selectedType, editingPublicLinkText: self.editingPublicLinkText, addressNameValidationStatus: self.addressNameValidationStatus, updatingAddressName: updatingAddressName, revealedRevokePeerId: self.revealedRevokePeerId, revokingPeerId: self.revokingPeerId, revokingPrivateLink: self.revokingPrivateLink, forwardingEnabled: self.forwardingEnabled, joinToSend: self.joinToSend, approveMembers: approveMembers) } } @@ -536,6 +634,28 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa } } + let joinToSend: CurrentChannelJoinToSend + if let current = state.joinToSend { + joinToSend = current + } else { + if peer.flags.contains(.joinToSend) { + joinToSend = .members + } else { + joinToSend = .everyone + } + } + + let approveMembers: Bool + if let enabled = state.approveMembers { + approveMembers = enabled + } else { + if peer.flags.contains(.requestToJoin) { + approveMembers = true + } else { + approveMembers = false + } + } + let forwardingEnabled: Bool if let enabled = state.forwardingEnabled { forwardingEnabled = enabled @@ -696,11 +816,17 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa entries.append(.privateLinkManageInfo(presentationData.theme, presentationData.strings.InviteLink_CreateInfo)) } } + + entries.append(.joinToSendHeader(presentationData.theme, presentationData.strings.Group_Setup_WhoCanSendMessages_Title.uppercased())) + entries.append(.joinToSendEveryone(presentationData.theme, presentationData.strings.Group_Setup_WhoCanSendMessages_Everyone, joinToSend == .everyone)) + entries.append(.joinToSendMembers(presentationData.theme, presentationData.strings.Group_Setup_WhoCanSendMessages_OnlyMembers, joinToSend == .members)) + + entries.append(.approveMembers(presentationData.theme, presentationData.strings.Group_Setup_ApproveNewMembers, approveMembers)) + entries.append(.approveMembersInfo(presentationData.theme, presentationData.strings.Group_Setup_ApproveNewMembersInfo)) entries.append(.forwardingHeader(presentationData.theme, isGroup ? presentationData.strings.Group_Setup_ForwardingGroupTitle.uppercased() : presentationData.strings.Group_Setup_ForwardingChannelTitle.uppercased())) entries.append(.forwardingDisabled(presentationData.theme, presentationData.strings.Group_Setup_ForwardingDisabled, !forwardingEnabled)) entries.append(.forwardingInfo(presentationData.theme, forwardingEnabled ? (isGroup ? presentationData.strings.Group_Setup_ForwardingGroupInfo : presentationData.strings.Group_Setup_ForwardingChannelInfo) : (isGroup ? presentationData.strings.Group_Setup_ForwardingGroupInfoDisabled : presentationData.strings.Group_Setup_ForwardingChannelInfoDisabled))) - } else if let peer = view.peers[view.peerId] as? TelegramGroup { switch mode { case .privateLink: @@ -816,7 +942,7 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa } } } - + let forwardingEnabled: Bool if let enabled = state.forwardingEnabled { forwardingEnabled = enabled @@ -1009,7 +1135,10 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta let presentationData = context.sharedContext.currentPresentationData.with { $0 } presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil) }, shareLink: { invite in - let shareController = ShareController(context: context, subject: .url(invite.link), updatedPresentationData: updatedPresentationData) + guard let inviteLink = invite.link else { + return + } + let shareController = ShareController(context: context, subject: .url(inviteLink), updatedPresentationData: updatedPresentationData) shareController.actionCompleted = { let presentationData = context.sharedContext.currentPresentationData.with { $0 } presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.InviteLink_InviteLinkCopiedText), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil) @@ -1151,6 +1280,14 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta updateState { state in return state.withUpdatedForwardingEnabled(value) } + }, updateJoinToSend: { value in + updateState { state in + return state.withUpdatedJoinToSend(value) + } + }, toggleApproveMembers: { value in + updateState { state in + return state.withUpdatedApproveMembers(value) + } }) let peerView = context.account.viewTracker.peerView(peerId) @@ -1220,6 +1357,14 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta toggleCopyProtectionDisposable.set(context.engine.peers.toggleMessageCopyProtection(peerId: peerId, enabled: !updatedCopyProtection).start()) } + if let updatedJoinToSend = state.joinToSend { + toggleCopyProtectionDisposable.set(context.engine.peers.toggleChannelJoinToSend(peerId: peerId, enabled: updatedJoinToSend == .members).start()) + } + + if let updatedApproveMembers = state.approveMembers { + toggleCopyProtectionDisposable.set(context.engine.peers.toggleChannelJoinRequest(peerId: peerId, enabled: updatedApproveMembers).start()) + } + if let updatedAddressNameValue = updatedAddressNameValue { let invokeAction: () -> Void = { updateState { state in diff --git a/submodules/QrCodeUI/Sources/QrCodeScreen.swift b/submodules/QrCodeUI/Sources/QrCodeScreen.swift index 707dc8d2f2..be0fe9a132 100644 --- a/submodules/QrCodeUI/Sources/QrCodeScreen.swift +++ b/submodules/QrCodeUI/Sources/QrCodeScreen.swift @@ -44,7 +44,7 @@ public final class QrCodeScreen: ViewController { case let .peer(peer): return "https://t.me/\(peer.addressName ?? "")" case let .invite(invite, _): - return invite.link + return invite.link ?? "" } } diff --git a/submodules/ShareController/Sources/ShareController.swift b/submodules/ShareController/Sources/ShareController.swift index 1c924a1733..3d27df31d4 100644 --- a/submodules/ShareController/Sources/ShareController.swift +++ b/submodules/ShareController/Sources/ShareController.swift @@ -475,6 +475,12 @@ public final class ShareController: ViewController { }) self.switchToAccount(account: currentAccount, animateIn: false) + + if self.fromForeignApp { + if let application = UIApplication.value(forKeyPath: #keyPath(UIApplication.shared)) as? UIApplication { + application.isIdleTimerDisabled = true + } + } } required public init(coder aDecoder: NSCoder) { @@ -485,6 +491,12 @@ public final class ShareController: ViewController { self.peersDisposable.dispose() self.readyDisposable.dispose() self.accountActiveDisposable.dispose() + + if self.fromForeignApp { + if let application = UIApplication.value(forKeyPath: #keyPath(UIApplication.shared)) as? UIApplication { + application.isIdleTimerDisabled = false + } + } } override public func loadDisplayNode() { diff --git a/submodules/Speak/BUILD b/submodules/Speak/BUILD index face717fdb..0906356fd7 100644 --- a/submodules/Speak/BUILD +++ b/submodules/Speak/BUILD @@ -11,6 +11,7 @@ swift_library( ], deps = [ "//submodules/Display:Display", + "//submodules/AccountContext:AccountContext", ], visibility = [ "//visibility:public", diff --git a/submodules/Speak/Sources/Speak.swift b/submodules/Speak/Sources/Speak.swift index dc48f6f469..845550e67b 100644 --- a/submodules/Speak/Sources/Speak.swift +++ b/submodules/Speak/Sources/Speak.swift @@ -1,5 +1,6 @@ import Foundation import AVFoundation +import AccountContext // Incuding at least one Objective-C class in a swift file ensures that it doesn't get stripped by the linker private final class LinkHelperClass: NSObject { @@ -38,10 +39,11 @@ public func supportedSpeakLanguages() -> Set { return Set(languages) } -public func speakText(_ text: String) -> SpeechSynthesizerHolder? { +public func speakText(context: AccountContext, text: String) -> SpeechSynthesizerHolder? { guard !text.isEmpty else { return nil } + let speechSynthesizer = AVSpeechSynthesizer() let utterance = AVSpeechUtterance(string: text) if #available(iOS 11.0, *), let language = NSLinguisticTagger.dominantLanguage(for: text) { diff --git a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift index 1951721889..11a62ea8da 100644 --- a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift +++ b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift @@ -30,7 +30,7 @@ public func fetchCompressedLottieFirstFrameAJpeg(data: Data, size: CGSize, fitzM let decompressedData = TGGUnzipData(data, 8 * 1024 * 1024) if let decompressedData = decompressedData { - if let player = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, cacheKey: cacheKey) { + if let player = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, colorReplacements: nil, cacheKey: cacheKey) { if cancelled.with({ $0 }) { return } @@ -128,7 +128,7 @@ public func cacheAnimatedStickerFrames(data: Data, size: CGSize, fitzModifier: E let decompressedData = TGGUnzipData(data, 8 * 1024 * 1024) if let decompressedData = decompressedData { - if let player = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, cacheKey: cacheKey) { + if let player = LottieInstance(data: decompressedData, fitzModifier: fitzModifier?.lottieFitzModifier ?? .none, colorReplacements: nil, cacheKey: cacheKey) { let endFrame = Int(player.frameCount) if cancelled.with({ $0 }) { diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index 564dda0752..e5a4a4123e 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -4,7 +4,6 @@ public enum Api { public enum auth {} public enum channels {} public enum contacts {} - public enum feed {} public enum help {} public enum messages {} public enum payments {} @@ -22,7 +21,6 @@ public enum Api { public enum bots {} public enum channels {} public enum contacts {} - public enum feed {} public enum folders {} public enum help {} public enum langpack {} @@ -70,7 +68,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1071145937] = { return Api.BotCommandScope.parse_botCommandScopePeerAdmins($0) } dict[169026035] = { return Api.BotCommandScope.parse_botCommandScopePeerUser($0) } dict[1011811544] = { return Api.BotCommandScope.parse_botCommandScopeUsers($0) } - dict[-468280483] = { return Api.BotInfo.parse_botInfo($0) } + dict[-863263529] = { return Api.BotInfo.parse_botInfo($0) } dict[1984755728] = { return Api.BotInlineMessage.parse_botInlineMessageMediaAuto($0) } dict[416402882] = { return Api.BotInlineMessage.parse_botInlineMessageMediaContact($0) } dict[85477117] = { return Api.BotInlineMessage.parse_botInlineMessageMediaGeo($0) } @@ -200,8 +198,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-317144808] = { return Api.EncryptedMessage.parse_encryptedMessage($0) } dict[594758406] = { return Api.EncryptedMessage.parse_encryptedMessageService($0) } dict[179611673] = { return Api.ExportedChatInvite.parse_chatInviteExported($0) } + dict[-317687113] = { return Api.ExportedChatInvite.parse_chatInvitePublicJoinRequests($0) } dict[1571494644] = { return Api.ExportedMessageLink.parse_exportedMessageLink($0) } - dict[1348066419] = { return Api.FeedPosition.parse_feedPosition($0) } dict[1648543603] = { return Api.FileHash.parse_fileHash($0) } dict[-11252123] = { return Api.Folder.parse_folder($0) } dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) } @@ -791,7 +789,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[-1842450928] = { return Api.Update.parse_updateReadChannelInbox($0) } dict[-1218471511] = { return Api.Update.parse_updateReadChannelOutbox($0) } dict[1461528386] = { return Api.Update.parse_updateReadFeaturedStickers($0) } - dict[1951948721] = { return Api.Update.parse_updateReadFeed($0) } dict[-1667805217] = { return Api.Update.parse_updateReadHistoryInbox($0) } dict[791617983] = { return Api.Update.parse_updateReadHistoryOutbox($0) } dict[1757493555] = { return Api.Update.parse_updateReadMessagesContents($0) } @@ -900,8 +897,6 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[1891070632] = { return Api.contacts.TopPeers.parse_topPeers($0) } dict[-1255369827] = { return Api.contacts.TopPeers.parse_topPeersDisabled($0) } dict[-567906571] = { return Api.contacts.TopPeers.parse_topPeersNotModified($0) } - dict[-587770695] = { return Api.feed.FeedMessages.parse_feedMessages($0) } - dict[-619039485] = { return Api.feed.FeedMessages.parse_feedMessagesNotModified($0) } dict[-860107216] = { return Api.help.AppUpdate.parse_appUpdate($0) } dict[-1000708810] = { return Api.help.AppUpdate.parse_noAppUpdate($0) } dict[-2016381538] = { return Api.help.CountriesList.parse_countriesList($0) } @@ -1210,8 +1205,6 @@ public extension Api { _1.serialize(buffer, boxed) case let _1 as Api.ExportedMessageLink: _1.serialize(buffer, boxed) - case let _1 as Api.FeedPosition: - _1.serialize(buffer, boxed) case let _1 as Api.FileHash: _1.serialize(buffer, boxed) case let _1 as Api.Folder: @@ -1624,8 +1617,6 @@ public extension Api { _1.serialize(buffer, boxed) case let _1 as Api.contacts.TopPeers: _1.serialize(buffer, boxed) - case let _1 as Api.feed.FeedMessages: - _1.serialize(buffer, boxed) case let _1 as Api.help.AppUpdate: _1.serialize(buffer, boxed) case let _1 as Api.help.CountriesList: diff --git a/submodules/TelegramApi/Sources/Api1.swift b/submodules/TelegramApi/Sources/Api1.swift index a0cab703c5..a50e19438e 100644 --- a/submodules/TelegramApi/Sources/Api1.swift +++ b/submodules/TelegramApi/Sources/Api1.swift @@ -856,52 +856,62 @@ public extension Api { } public extension Api { enum BotInfo: TypeConstructorDescription { - case botInfo(userId: Int64, description: String, commands: [Api.BotCommand], menuButton: Api.BotMenuButton) + case botInfo(flags: Int32, userId: Int64?, description: String?, descriptionPhoto: Api.Photo?, commands: [Api.BotCommand]?, menuButton: Api.BotMenuButton?) public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { - case .botInfo(let userId, let description, let commands, let menuButton): + case .botInfo(let flags, let userId, let description, let descriptionPhoto, let commands, let menuButton): if boxed { - buffer.appendInt32(-468280483) + buffer.appendInt32(-863263529) } - serializeInt64(userId, buffer: buffer, boxed: false) - serializeString(description, buffer: buffer, boxed: false) - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(commands.count)) - for item in commands { + serializeInt32(flags, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {serializeInt64(userId!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 1) != 0 {serializeString(description!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 4) != 0 {descriptionPhoto!.serialize(buffer, true)} + if Int(flags) & Int(1 << 2) != 0 {buffer.appendInt32(481674261) + buffer.appendInt32(Int32(commands!.count)) + for item in commands! { item.serialize(buffer, true) - } - menuButton.serialize(buffer, true) + }} + if Int(flags) & Int(1 << 3) != 0 {menuButton!.serialize(buffer, true)} break } } public func descriptionFields() -> (String, [(String, Any)]) { switch self { - case .botInfo(let userId, let description, let commands, let menuButton): - return ("botInfo", [("userId", String(describing: userId)), ("description", String(describing: description)), ("commands", String(describing: commands)), ("menuButton", String(describing: menuButton))]) + case .botInfo(let flags, let userId, let description, let descriptionPhoto, let commands, let menuButton): + return ("botInfo", [("flags", String(describing: flags)), ("userId", String(describing: userId)), ("description", String(describing: description)), ("descriptionPhoto", String(describing: descriptionPhoto)), ("commands", String(describing: commands)), ("menuButton", String(describing: menuButton))]) } } public static func parse_botInfo(_ reader: BufferReader) -> BotInfo? { - var _1: Int64? - _1 = reader.readInt64() - var _2: String? - _2 = parseString(reader) - var _3: [Api.BotCommand]? - if let _ = reader.readInt32() { - _3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.BotCommand.self) - } - var _4: Api.BotMenuButton? - if let signature = reader.readInt32() { - _4 = Api.parse(reader, signature: signature) as? Api.BotMenuButton - } + var _1: Int32? + _1 = reader.readInt32() + var _2: Int64? + if Int(_1!) & Int(1 << 0) != 0 {_2 = reader.readInt64() } + var _3: String? + if Int(_1!) & Int(1 << 1) != 0 {_3 = parseString(reader) } + var _4: Api.Photo? + if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() { + _4 = Api.parse(reader, signature: signature) as? Api.Photo + } } + var _5: [Api.BotCommand]? + if Int(_1!) & Int(1 << 2) != 0 {if let _ = reader.readInt32() { + _5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.BotCommand.self) + } } + var _6: Api.BotMenuButton? + if Int(_1!) & Int(1 << 3) != 0 {if let signature = reader.readInt32() { + _6 = Api.parse(reader, signature: signature) as? Api.BotMenuButton + } } let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = _4 != nil - if _c1 && _c2 && _c3 && _c4 { - return Api.BotInfo.botInfo(userId: _1!, description: _2!, commands: _3!, menuButton: _4!) + let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil + let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil + let _c4 = (Int(_1!) & Int(1 << 4) == 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.BotInfo.botInfo(flags: _1!, userId: _2, description: _3, descriptionPhoto: _4, commands: _5, menuButton: _6) } else { return nil diff --git a/submodules/TelegramApi/Sources/Api19.swift b/submodules/TelegramApi/Sources/Api19.swift index 71f348fea8..75f69500fb 100644 --- a/submodules/TelegramApi/Sources/Api19.swift +++ b/submodules/TelegramApi/Sources/Api19.swift @@ -589,7 +589,6 @@ public extension Api { case updateReadChannelInbox(flags: Int32, folderId: Int32?, channelId: Int64, maxId: Int32, stillUnreadCount: Int32, pts: Int32) case updateReadChannelOutbox(channelId: Int64, maxId: Int32) case updateReadFeaturedStickers - case updateReadFeed(flags: Int32, filterId: Int32, maxPosition: Api.FeedPosition, unreadCount: Int32?, unreadMutedCount: Int32?) case updateReadHistoryInbox(flags: Int32, folderId: Int32?, peer: Api.Peer, maxId: Int32, stillUnreadCount: Int32, pts: Int32, ptsCount: Int32) case updateReadHistoryOutbox(peer: Api.Peer, maxId: Int32, pts: Int32, ptsCount: Int32) case updateReadMessagesContents(messages: [Int32], pts: Int32, ptsCount: Int32) @@ -1334,16 +1333,6 @@ public extension Api { buffer.appendInt32(1461528386) } - break - case .updateReadFeed(let flags, let filterId, let maxPosition, let unreadCount, let unreadMutedCount): - if boxed { - buffer.appendInt32(1951948721) - } - serializeInt32(flags, buffer: buffer, boxed: false) - serializeInt32(filterId, buffer: buffer, boxed: false) - maxPosition.serialize(buffer, true) - if Int(flags) & Int(1 << 0) != 0 {serializeInt32(unreadCount!, buffer: buffer, boxed: false)} - if Int(flags) & Int(1 << 0) != 0 {serializeInt32(unreadMutedCount!, buffer: buffer, boxed: false)} break case .updateReadHistoryInbox(let flags, let folderId, let peer, let maxId, let stillUnreadCount, let pts, let ptsCount): if boxed { @@ -1658,8 +1647,6 @@ public extension Api { return ("updateReadChannelOutbox", [("channelId", String(describing: channelId)), ("maxId", String(describing: maxId))]) case .updateReadFeaturedStickers: return ("updateReadFeaturedStickers", []) - case .updateReadFeed(let flags, let filterId, let maxPosition, let unreadCount, let unreadMutedCount): - return ("updateReadFeed", [("flags", String(describing: flags)), ("filterId", String(describing: filterId)), ("maxPosition", String(describing: maxPosition)), ("unreadCount", String(describing: unreadCount)), ("unreadMutedCount", String(describing: unreadMutedCount))]) case .updateReadHistoryInbox(let flags, let folderId, let peer, let maxId, let stillUnreadCount, let pts, let ptsCount): return ("updateReadHistoryInbox", [("flags", String(describing: flags)), ("folderId", String(describing: folderId)), ("peer", String(describing: peer)), ("maxId", String(describing: maxId)), ("stillUnreadCount", String(describing: stillUnreadCount)), ("pts", String(describing: pts)), ("ptsCount", String(describing: ptsCount))]) case .updateReadHistoryOutbox(let peer, let maxId, let pts, let ptsCount): @@ -3195,31 +3182,6 @@ public extension Api { public static func parse_updateReadFeaturedStickers(_ reader: BufferReader) -> Update? { return Api.Update.updateReadFeaturedStickers } - public static func parse_updateReadFeed(_ reader: BufferReader) -> Update? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Int32? - _2 = reader.readInt32() - var _3: Api.FeedPosition? - if let signature = reader.readInt32() { - _3 = Api.parse(reader, signature: signature) as? Api.FeedPosition - } - var _4: Int32? - if Int(_1!) & Int(1 << 0) != 0 {_4 = reader.readInt32() } - var _5: Int32? - if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt32() } - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil - let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 { - return Api.Update.updateReadFeed(flags: _1!, filterId: _2!, maxPosition: _3!, unreadCount: _4, unreadMutedCount: _5) - } - else { - return nil - } - } public static func parse_updateReadHistoryInbox(_ reader: BufferReader) -> Update? { var _1: Int32? _1 = reader.readInt32() diff --git a/submodules/TelegramApi/Sources/Api22.swift b/submodules/TelegramApi/Sources/Api22.swift index de2b47d5ef..b9a26d9242 100644 --- a/submodules/TelegramApi/Sources/Api22.swift +++ b/submodules/TelegramApi/Sources/Api22.swift @@ -1104,102 +1104,6 @@ public extension Api.contacts { } } -public extension Api.feed { - enum FeedMessages: TypeConstructorDescription { - case feedMessages(flags: Int32, maxPosition: Api.FeedPosition?, minPosition: Api.FeedPosition?, readMaxPosition: Api.FeedPosition?, messages: [Api.Message], chats: [Api.Chat], users: [Api.User]) - case feedMessagesNotModified - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .feedMessages(let flags, let maxPosition, let minPosition, let readMaxPosition, let messages, let chats, let users): - if boxed { - buffer.appendInt32(-587770695) - } - serializeInt32(flags, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 0) != 0 {maxPosition!.serialize(buffer, true)} - if Int(flags) & Int(1 << 1) != 0 {minPosition!.serialize(buffer, true)} - if Int(flags) & Int(1 << 2) != 0 {readMaxPosition!.serialize(buffer, true)} - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(messages.count)) - for item in messages { - item.serialize(buffer, true) - } - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(chats.count)) - for item in chats { - item.serialize(buffer, true) - } - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(users.count)) - for item in users { - item.serialize(buffer, true) - } - break - case .feedMessagesNotModified: - if boxed { - buffer.appendInt32(-619039485) - } - - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .feedMessages(let flags, let maxPosition, let minPosition, let readMaxPosition, let messages, let chats, let users): - return ("feedMessages", [("flags", String(describing: flags)), ("maxPosition", String(describing: maxPosition)), ("minPosition", String(describing: minPosition)), ("readMaxPosition", String(describing: readMaxPosition)), ("messages", String(describing: messages)), ("chats", String(describing: chats)), ("users", String(describing: users))]) - case .feedMessagesNotModified: - return ("feedMessagesNotModified", []) - } - } - - public static func parse_feedMessages(_ reader: BufferReader) -> FeedMessages? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Api.FeedPosition? - if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.FeedPosition - } } - var _3: Api.FeedPosition? - if Int(_1!) & Int(1 << 1) != 0 {if let signature = reader.readInt32() { - _3 = Api.parse(reader, signature: signature) as? Api.FeedPosition - } } - var _4: Api.FeedPosition? - if Int(_1!) & Int(1 << 2) != 0 {if let signature = reader.readInt32() { - _4 = Api.parse(reader, signature: signature) as? Api.FeedPosition - } } - var _5: [Api.Message]? - if let _ = reader.readInt32() { - _5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Message.self) - } - var _6: [Api.Chat]? - if let _ = reader.readInt32() { - _6 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self) - } - var _7: [Api.User]? - if let _ = reader.readInt32() { - _7 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self) - } - let _c1 = _1 != nil - let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil - let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil - let _c4 = (Int(_1!) & Int(1 << 2) == 0) || _4 != nil - let _c5 = _5 != nil - let _c6 = _6 != nil - let _c7 = _7 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 { - return Api.feed.FeedMessages.feedMessages(flags: _1!, maxPosition: _2, minPosition: _3, readMaxPosition: _4, messages: _5!, chats: _6!, users: _7!) - } - else { - return nil - } - } - public static func parse_feedMessagesNotModified(_ reader: BufferReader) -> FeedMessages? { - return Api.feed.FeedMessages.feedMessagesNotModified - } - - } -} public extension Api.help { enum AppUpdate: TypeConstructorDescription { case appUpdate(flags: Int32, id: Int32, version: String, text: String, entities: [Api.MessageEntity], document: Api.Document?, url: String?, sticker: Api.Document?) @@ -1344,3 +1248,61 @@ public extension Api.help { } } +public extension Api.help { + enum Country: TypeConstructorDescription { + case country(flags: Int32, iso2: String, defaultName: String, name: String?, countryCodes: [Api.help.CountryCode]) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .country(let flags, let iso2, let defaultName, let name, let countryCodes): + if boxed { + buffer.appendInt32(-1014526429) + } + serializeInt32(flags, buffer: buffer, boxed: false) + serializeString(iso2, buffer: buffer, boxed: false) + serializeString(defaultName, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 1) != 0 {serializeString(name!, buffer: buffer, boxed: false)} + buffer.appendInt32(481674261) + buffer.appendInt32(Int32(countryCodes.count)) + for item in countryCodes { + item.serialize(buffer, true) + } + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .country(let flags, let iso2, let defaultName, let name, let countryCodes): + return ("country", [("flags", String(describing: flags)), ("iso2", String(describing: iso2)), ("defaultName", String(describing: defaultName)), ("name", String(describing: name)), ("countryCodes", String(describing: countryCodes))]) + } + } + + public static func parse_country(_ reader: BufferReader) -> Country? { + var _1: Int32? + _1 = reader.readInt32() + var _2: String? + _2 = parseString(reader) + var _3: String? + _3 = parseString(reader) + var _4: String? + if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) } + var _5: [Api.help.CountryCode]? + if let _ = reader.readInt32() { + _5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.help.CountryCode.self) + } + let _c1 = _1 != nil + let _c2 = _2 != nil + let _c3 = _3 != nil + let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil + let _c5 = _5 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 { + return Api.help.Country.country(flags: _1!, iso2: _2!, defaultName: _3!, name: _4, countryCodes: _5!) + } + else { + return nil + } + } + + } +} diff --git a/submodules/TelegramApi/Sources/Api23.swift b/submodules/TelegramApi/Sources/Api23.swift index 70e96ff045..6781cecc18 100644 --- a/submodules/TelegramApi/Sources/Api23.swift +++ b/submodules/TelegramApi/Sources/Api23.swift @@ -1,61 +1,3 @@ -public extension Api.help { - enum Country: TypeConstructorDescription { - case country(flags: Int32, iso2: String, defaultName: String, name: String?, countryCodes: [Api.help.CountryCode]) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .country(let flags, let iso2, let defaultName, let name, let countryCodes): - if boxed { - buffer.appendInt32(-1014526429) - } - serializeInt32(flags, buffer: buffer, boxed: false) - serializeString(iso2, buffer: buffer, boxed: false) - serializeString(defaultName, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 1) != 0 {serializeString(name!, buffer: buffer, boxed: false)} - buffer.appendInt32(481674261) - buffer.appendInt32(Int32(countryCodes.count)) - for item in countryCodes { - item.serialize(buffer, true) - } - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .country(let flags, let iso2, let defaultName, let name, let countryCodes): - return ("country", [("flags", String(describing: flags)), ("iso2", String(describing: iso2)), ("defaultName", String(describing: defaultName)), ("name", String(describing: name)), ("countryCodes", String(describing: countryCodes))]) - } - } - - public static func parse_country(_ reader: BufferReader) -> Country? { - var _1: Int32? - _1 = reader.readInt32() - var _2: String? - _2 = parseString(reader) - var _3: String? - _3 = parseString(reader) - var _4: String? - if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) } - var _5: [Api.help.CountryCode]? - if let _ = reader.readInt32() { - _5 = Api.parseVector(reader, elementSignature: 0, elementType: Api.help.CountryCode.self) - } - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil - let _c5 = _5 != nil - if _c1 && _c2 && _c3 && _c4 && _c5 { - return Api.help.Country.country(flags: _1!, iso2: _2!, defaultName: _3!, name: _4, countryCodes: _5!) - } - else { - return nil - } - } - - } -} public extension Api.help { enum CountryCode: TypeConstructorDescription { case countryCode(flags: Int32, countryCode: String, prefixes: [String]?, patterns: [String]?) @@ -1350,3 +1292,39 @@ public extension Api.messages { } } +public extension Api.messages { + enum CheckedHistoryImportPeer: TypeConstructorDescription { + case checkedHistoryImportPeer(confirmText: String) + + public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { + switch self { + case .checkedHistoryImportPeer(let confirmText): + if boxed { + buffer.appendInt32(-1571952873) + } + serializeString(confirmText, buffer: buffer, boxed: false) + break + } + } + + public func descriptionFields() -> (String, [(String, Any)]) { + switch self { + case .checkedHistoryImportPeer(let confirmText): + return ("checkedHistoryImportPeer", [("confirmText", String(describing: confirmText))]) + } + } + + public static func parse_checkedHistoryImportPeer(_ reader: BufferReader) -> CheckedHistoryImportPeer? { + var _1: String? + _1 = parseString(reader) + let _c1 = _1 != nil + if _c1 { + return Api.messages.CheckedHistoryImportPeer.checkedHistoryImportPeer(confirmText: _1!) + } + else { + return nil + } + } + + } +} diff --git a/submodules/TelegramApi/Sources/Api24.swift b/submodules/TelegramApi/Sources/Api24.swift index b12751463a..fd0350a042 100644 --- a/submodules/TelegramApi/Sources/Api24.swift +++ b/submodules/TelegramApi/Sources/Api24.swift @@ -1,39 +1,3 @@ -public extension Api.messages { - enum CheckedHistoryImportPeer: TypeConstructorDescription { - case checkedHistoryImportPeer(confirmText: String) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .checkedHistoryImportPeer(let confirmText): - if boxed { - buffer.appendInt32(-1571952873) - } - serializeString(confirmText, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .checkedHistoryImportPeer(let confirmText): - return ("checkedHistoryImportPeer", [("confirmText", String(describing: confirmText))]) - } - } - - public static func parse_checkedHistoryImportPeer(_ reader: BufferReader) -> CheckedHistoryImportPeer? { - var _1: String? - _1 = parseString(reader) - let _c1 = _1 != nil - if _c1 { - return Api.messages.CheckedHistoryImportPeer.checkedHistoryImportPeer(confirmText: _1!) - } - else { - return nil - } - } - - } -} public extension Api.messages { enum DhConfig: TypeConstructorDescription { case dhConfig(g: Int32, p: Buffer, version: Int32, random: Buffer) diff --git a/submodules/TelegramApi/Sources/Api27.swift b/submodules/TelegramApi/Sources/Api27.swift index ebd33d06d4..45cc0835b2 100644 --- a/submodules/TelegramApi/Sources/Api27.swift +++ b/submodules/TelegramApi/Sources/Api27.swift @@ -2284,6 +2284,38 @@ public extension Api.functions.channels { }) } } +public extension Api.functions.channels { + static func toggleJoinRequest(channel: Api.InputChannel, enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(1277789622) + channel.serialize(buffer, true) + enabled.serialize(buffer, true) + return (FunctionDescription(name: "channels.toggleJoinRequest", parameters: [("channel", String(describing: channel)), ("enabled", String(describing: enabled))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in + let reader = BufferReader(buffer) + var result: Api.Updates? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.Updates + } + return result + }) + } +} +public extension Api.functions.channels { + static func toggleJoinToSend(channel: Api.InputChannel, enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(-456419968) + channel.serialize(buffer, true) + enabled.serialize(buffer, true) + return (FunctionDescription(name: "channels.toggleJoinToSend", parameters: [("channel", String(describing: channel)), ("enabled", String(describing: enabled))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in + let reader = BufferReader(buffer) + var result: Api.Updates? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.Updates + } + return result + }) + } +} public extension Api.functions.channels { static func togglePreHistoryHidden(channel: Api.InputChannel, enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() @@ -2704,44 +2736,6 @@ public extension Api.functions.contacts { }) } } -public extension Api.functions.feed { - static func getFeed(flags: Int32, filterId: Int32, offsetPosition: Api.FeedPosition?, addOffset: Int32, limit: Int32, maxPosition: Api.FeedPosition?, minPosition: Api.FeedPosition?, hash: Int64) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(2121717715) - serializeInt32(flags, buffer: buffer, boxed: false) - serializeInt32(filterId, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 0) != 0 {offsetPosition!.serialize(buffer, true)} - serializeInt32(addOffset, buffer: buffer, boxed: false) - serializeInt32(limit, buffer: buffer, boxed: false) - if Int(flags) & Int(1 << 1) != 0 {maxPosition!.serialize(buffer, true)} - if Int(flags) & Int(1 << 2) != 0 {minPosition!.serialize(buffer, true)} - serializeInt64(hash, buffer: buffer, boxed: false) - return (FunctionDescription(name: "feed.getFeed", parameters: [("flags", String(describing: flags)), ("filterId", String(describing: filterId)), ("offsetPosition", String(describing: offsetPosition)), ("addOffset", String(describing: addOffset)), ("limit", String(describing: limit)), ("maxPosition", String(describing: maxPosition)), ("minPosition", String(describing: minPosition)), ("hash", String(describing: hash))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.feed.FeedMessages? in - let reader = BufferReader(buffer) - var result: Api.feed.FeedMessages? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.feed.FeedMessages - } - return result - }) - } -} -public extension Api.functions.feed { - static func readFeed(filterId: Int32, maxPosition: Api.FeedPosition) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(-1271479809) - serializeInt32(filterId, buffer: buffer, boxed: false) - maxPosition.serialize(buffer, true) - return (FunctionDescription(name: "feed.readFeed", parameters: [("filterId", String(describing: filterId)), ("maxPosition", String(describing: maxPosition))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in - let reader = BufferReader(buffer) - var result: Api.Updates? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.Updates - } - return result - }) - } -} public extension Api.functions.folders { static func deleteFolder(folderId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { let buffer = Buffer() diff --git a/submodules/TelegramApi/Sources/Api5.swift b/submodules/TelegramApi/Sources/Api5.swift index 4b87712684..099cbad071 100644 --- a/submodules/TelegramApi/Sources/Api5.swift +++ b/submodules/TelegramApi/Sources/Api5.swift @@ -541,6 +541,7 @@ public extension Api { public extension Api { enum ExportedChatInvite: TypeConstructorDescription { case chatInviteExported(flags: Int32, link: String, adminId: Int64, date: Int32, startDate: Int32?, expireDate: Int32?, usageLimit: Int32?, usage: Int32?, requested: Int32?, title: String?) + case chatInvitePublicJoinRequests public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { switch self { @@ -558,6 +559,12 @@ public extension Api { if Int(flags) & Int(1 << 3) != 0 {serializeInt32(usage!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 7) != 0 {serializeInt32(requested!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 8) != 0 {serializeString(title!, buffer: buffer, boxed: false)} + break + case .chatInvitePublicJoinRequests: + if boxed { + buffer.appendInt32(-317687113) + } + break } } @@ -566,6 +573,8 @@ public extension Api { switch self { case .chatInviteExported(let flags, let link, let adminId, let date, let startDate, let expireDate, let usageLimit, let usage, let requested, let title): return ("chatInviteExported", [("flags", String(describing: flags)), ("link", String(describing: link)), ("adminId", String(describing: adminId)), ("date", String(describing: date)), ("startDate", String(describing: startDate)), ("expireDate", String(describing: expireDate)), ("usageLimit", String(describing: usageLimit)), ("usage", String(describing: usage)), ("requested", String(describing: requested)), ("title", String(describing: title))]) + case .chatInvitePublicJoinRequests: + return ("chatInvitePublicJoinRequests", []) } } @@ -607,6 +616,9 @@ public extension Api { return nil } } + public static func parse_chatInvitePublicJoinRequests(_ reader: BufferReader) -> ExportedChatInvite? { + return Api.ExportedChatInvite.chatInvitePublicJoinRequests + } } } @@ -650,52 +662,6 @@ public extension Api { } } -public extension Api { - enum FeedPosition: TypeConstructorDescription { - case feedPosition(date: Int32, peer: Api.Peer, id: Int32) - - public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { - switch self { - case .feedPosition(let date, let peer, let id): - if boxed { - buffer.appendInt32(1348066419) - } - serializeInt32(date, buffer: buffer, boxed: false) - peer.serialize(buffer, true) - serializeInt32(id, buffer: buffer, boxed: false) - break - } - } - - public func descriptionFields() -> (String, [(String, Any)]) { - switch self { - case .feedPosition(let date, let peer, let id): - return ("feedPosition", [("date", String(describing: date)), ("peer", String(describing: peer)), ("id", String(describing: id))]) - } - } - - public static func parse_feedPosition(_ reader: BufferReader) -> FeedPosition? { - var _1: Int32? - _1 = reader.readInt32() - var _2: Api.Peer? - if let signature = reader.readInt32() { - _2 = Api.parse(reader, signature: signature) as? Api.Peer - } - var _3: Int32? - _3 = reader.readInt32() - let _c1 = _1 != nil - let _c2 = _2 != nil - let _c3 = _3 != nil - if _c1 && _c2 && _c3 { - return Api.FeedPosition.feedPosition(date: _1!, peer: _2!, id: _3!) - } - else { - return nil - } - } - - } -} public extension Api { enum FileHash: TypeConstructorDescription { case fileHash(offset: Int32, limit: Int32, hash: Buffer) diff --git a/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift b/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift index 76ec2dcc7f..eb9be44c80 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/ApiGroupOrChannel.swift @@ -118,6 +118,12 @@ func parseTelegramGroupOrChannel(chat: Api.Chat) -> Peer? { if (flags & Int32(1 << 27)) != 0 { channelFlags.insert(.copyProtectionEnabled) } + if (flags & Int32(1 << 28)) != 0 { + channelFlags.insert(.joinToSend) + } + if (flags & Int32(1 << 29)) != 0 { + channelFlags.insert(.requestToJoin) + } let restrictionInfo: PeerAccessRestrictionInfo? if let restrictionReason = restrictionReason { diff --git a/submodules/TelegramCore/Sources/ApiUtils/BotInfo.swift b/submodules/TelegramCore/Sources/ApiUtils/BotInfo.swift index 67fc2d11ab..f99f7b8f1d 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/BotInfo.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/BotInfo.swift @@ -16,13 +16,21 @@ extension BotMenuButton { extension BotInfo { convenience init(apiBotInfo: Api.BotInfo) { switch apiBotInfo { - case let .botInfo(_, description, commands, menuButton): - self.init(description: description, commands: commands.map { command in - switch command { - case let .botCommand(command, description): - return BotCommand(text: command, description: description) + case let .botInfo(_, _, description, _, apiCommands, apiMenuButton): + var commands: [BotCommand] = [] + if let apiCommands = apiCommands { + commands = apiCommands.map { command in + switch command { + case let .botCommand(command, description): + return BotCommand(text: command, description: description) + } } - }, menuButton: BotMenuButton(apiBotMenuButton: menuButton)) + } + var menuButton: BotMenuButton = .commands + if let apiMenuButton = apiMenuButton { + menuButton = BotMenuButton(apiBotMenuButton: apiMenuButton) + } + self.init(description: description ?? "", commands: commands, menuButton: menuButton) } } } diff --git a/submodules/TelegramCore/Sources/ApiUtils/ExportedInvitation.swift b/submodules/TelegramCore/Sources/ApiUtils/ExportedInvitation.swift index b458031d8a..3abfba2a48 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/ExportedInvitation.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/ExportedInvitation.swift @@ -6,8 +6,48 @@ import TelegramApi extension ExportedInvitation { init(apiExportedInvite: Api.ExportedChatInvite) { switch apiExportedInvite { - case let .chatInviteExported(flags, link, adminId, date, startDate, expireDate, usageLimit, usage, requested, title): - self = ExportedInvitation(link: link, title: title, isPermanent: (flags & (1 << 5)) != 0, requestApproval: (flags & (1 << 6)) != 0, isRevoked: (flags & (1 << 0)) != 0, adminId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(adminId)), date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: usage, requestedCount: requested) + case let .chatInviteExported(flags, link, adminId, date, startDate, expireDate, usageLimit, usage, requested, title): + self = .link(link: link, title: title, isPermanent: (flags & (1 << 5)) != 0, requestApproval: (flags & (1 << 6)) != 0, isRevoked: (flags & (1 << 0)) != 0, adminId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(adminId)), date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: usage, requestedCount: requested) + case .chatInvitePublicJoinRequests: + self = .publicJoinRequest + } + } +} + +public extension ExportedInvitation { + var link: String? { + switch self { + case let .link(link, _, _, _, _, _, _, _, _, _, _, _): + return link + case .publicJoinRequest: + return nil + } + } + + var date: Int32? { + switch self { + case let .link(_, _, _, _, _, _, _, date, _, _, _, _): + return date + case .publicJoinRequest: + return nil + } + } + + var isPermanent: Bool { + switch self { + case let .link(_, _, isPermanent, _, _, _, _, _, _, _, _, _): + return isPermanent + case .publicJoinRequest: + return false + } + } + + var isRevoked: Bool { + switch self { + case let .link(_, _, _, _, isRevoked, _, _, _, _, _, _, _): + return isRevoked + case .publicJoinRequest: + return false } } } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_ExportedInvitation.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_ExportedInvitation.swift index 13c68ad3d0..f10d5c7861 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_ExportedInvitation.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_ExportedInvitation.swift @@ -1,73 +1,81 @@ import Postbox -public struct ExportedInvitation: Codable, Equatable { - public let link: String - public let title: String? - public let isPermanent: Bool - public let requestApproval: Bool - public let isRevoked: Bool - public let adminId: PeerId - public let date: Int32 - public let startDate: Int32? - public let expireDate: Int32? - public let usageLimit: Int32? - public let count: Int32? - public let requestedCount: Int32? - - public init(link: String, title: String?, isPermanent: Bool, requestApproval: Bool, isRevoked: Bool, adminId: PeerId, date: Int32, startDate: Int32?, expireDate: Int32?, usageLimit: Int32?, count: Int32?, requestedCount: Int32?) { - self.link = link - self.title = title - self.isPermanent = isPermanent - self.requestApproval = requestApproval - self.isRevoked = isRevoked - self.adminId = adminId - self.date = date - self.startDate = startDate - self.expireDate = expireDate - self.usageLimit = usageLimit - self.count = count - self.requestedCount = requestedCount - } +public enum ExportedInvitation: Codable, Equatable { + case link(link: String, title: String?, isPermanent: Bool, requestApproval: Bool, isRevoked: Bool, adminId: PeerId, date: Int32, startDate: Int32?, expireDate: Int32?, usageLimit: Int32?, count: Int32?, requestedCount: Int32?) + case publicJoinRequest public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: StringCodingKey.self) - self.link = try container.decode(String.self, forKey: "l") - self.title = try container.decodeIfPresent(String.self, forKey: "title") - self.isPermanent = try container.decode(Bool.self, forKey: "permanent") - self.requestApproval = try container.decodeIfPresent(Bool.self, forKey: "requestApproval") ?? false - self.isRevoked = try container.decode(Bool.self, forKey: "revoked") - self.adminId = PeerId(try container.decode(Int64.self, forKey: "adminId")) - self.date = try container.decode(Int32.self, forKey: "date") - self.startDate = try container.decodeIfPresent(Int32.self, forKey: "startDate") - self.expireDate = try container.decodeIfPresent(Int32.self, forKey: "expireDate") - self.usageLimit = try container.decodeIfPresent(Int32.self, forKey: "usageLimit") - self.count = try container.decodeIfPresent(Int32.self, forKey: "count") - self.requestedCount = try? container.decodeIfPresent(Int32.self, forKey: "requestedCount") + let type = try container.decodeIfPresent(Int32.self, forKey: "t") ?? 0 + if type == 0 { + let link = try container.decode(String.self, forKey: "l") + let title = try container.decodeIfPresent(String.self, forKey: "title") + let isPermanent = try container.decode(Bool.self, forKey: "permanent") + let requestApproval = try container.decodeIfPresent(Bool.self, forKey: "requestApproval") ?? false + let isRevoked = try container.decode(Bool.self, forKey: "revoked") + let adminId = PeerId(try container.decode(Int64.self, forKey: "adminId")) + let date = try container.decode(Int32.self, forKey: "date") + let startDate = try container.decodeIfPresent(Int32.self, forKey: "startDate") + let expireDate = try container.decodeIfPresent(Int32.self, forKey: "expireDate") + let usageLimit = try container.decodeIfPresent(Int32.self, forKey: "usageLimit") + let count = try container.decodeIfPresent(Int32.self, forKey: "count") + let requestedCount = try? container.decodeIfPresent(Int32.self, forKey: "requestedCount") + + self = .link(link: link, title: title, isPermanent: isPermanent, requestApproval: requestApproval, isRevoked: isRevoked, adminId: adminId, date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: count, requestedCount: requestedCount) + } else { + self = .publicJoinRequest + } } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: StringCodingKey.self) - try container.encode(self.link, forKey: "l") - try container.encodeIfPresent(self.title, forKey: "title") - try container.encode(self.isPermanent, forKey: "permanent") - try container.encode(self.requestApproval, forKey: "requestApproval") - try container.encode(self.isRevoked, forKey: "revoked") - try container.encode(self.adminId.toInt64(), forKey: "adminId") - try container.encode(self.date, forKey: "date") - try container.encodeIfPresent(self.startDate, forKey: "startDate") - try container.encodeIfPresent(self.expireDate, forKey: "expireDate") - try container.encodeIfPresent(self.usageLimit, forKey: "usageLimit") - try container.encodeIfPresent(self.count, forKey: "count") - try container.encodeIfPresent(self.requestedCount, forKey: "requestedCount") + switch self { + case let .link(link, title, isPermanent, requestApproval, isRevoked, adminId, date, startDate, expireDate, usageLimit, count, requestedCount): + let type: Int32 = 0 + try container.encode(type, forKey: "t") + try container.encode(link, forKey: "l") + try container.encodeIfPresent(title, forKey: "title") + try container.encode(isPermanent, forKey: "permanent") + try container.encode(requestApproval, forKey: "requestApproval") + try container.encode(isRevoked, forKey: "revoked") + try container.encode(adminId.toInt64(), forKey: "adminId") + try container.encode(date, forKey: "date") + try container.encodeIfPresent(startDate, forKey: "startDate") + try container.encodeIfPresent(expireDate, forKey: "expireDate") + try container.encodeIfPresent(usageLimit, forKey: "usageLimit") + try container.encodeIfPresent(count, forKey: "count") + try container.encodeIfPresent(requestedCount, forKey: "requestedCount") + case .publicJoinRequest: + let type: Int32 = 1 + try container.encode(type, forKey: "t") + } } public static func ==(lhs: ExportedInvitation, rhs: ExportedInvitation) -> Bool { - return lhs.link == rhs.link && lhs.title == rhs.title && lhs.isPermanent == rhs.isPermanent && lhs.requestApproval == rhs.requestApproval && lhs.isRevoked == rhs.isRevoked && lhs.adminId == rhs.adminId && lhs.date == rhs.date && lhs.startDate == rhs.startDate && lhs.expireDate == rhs.expireDate && lhs.usageLimit == rhs.usageLimit && lhs.count == rhs.count && lhs.requestedCount == rhs.requestedCount + switch lhs { + case let .link(link, title, isPermanent, requestApproval, isRevoked, adminId, date, startDate, expireDate, usageLimit, count, requestedCount): + if case .link(link, title, isPermanent, requestApproval, isRevoked, adminId, date, startDate, expireDate, usageLimit, count, requestedCount) = rhs { + return true + } else { + return false + } + case .publicJoinRequest: + if case .publicJoinRequest = rhs { + return true + } else { + return false + } + } } public func withUpdated(isRevoked: Bool) -> ExportedInvitation { - return ExportedInvitation(link: self.link, title: self.title, isPermanent: self.isPermanent, requestApproval: self.requestApproval, isRevoked: isRevoked, adminId: self.adminId, date: self.date, startDate: self.startDate, expireDate: self.expireDate, usageLimit: self.usageLimit, count: self.count, requestedCount: self.requestedCount) + switch self { + case let .link(link, title, isPermanent, requestApproval, _, adminId, date, startDate, expireDate, usageLimit, count, requestedCount): + return .link(link: link, title: title, isPermanent: isPermanent, requestApproval: requestApproval, isRevoked: isRevoked, adminId: adminId, date: date, startDate: startDate, expireDate: expireDate, usageLimit: usageLimit, count: count, requestedCount: requestedCount) + case .publicJoinRequest: + return .publicJoinRequest + } } } diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift index 43d39a29ec..5d76014559 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_TelegramChannel.swift @@ -145,6 +145,8 @@ public struct TelegramChannelFlags: OptionSet { public static let isFake = TelegramChannelFlags(rawValue: 1 << 6) public static let isGigagroup = TelegramChannelFlags(rawValue: 1 << 7) public static let copyProtectionEnabled = TelegramChannelFlags(rawValue: 1 << 8) + public static let joinToSend = TelegramChannelFlags(rawValue: 1 << 9) + public static let requestToJoin = TelegramChannelFlags(rawValue: 1 << 10) } public final class TelegramChannel: Peer, Equatable { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Messages/FeedHistory.swift b/submodules/TelegramCore/Sources/TelegramEngine/Messages/FeedHistory.swift index 18baaf03f0..82933b3cf4 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Messages/FeedHistory.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Messages/FeedHistory.swift @@ -343,112 +343,112 @@ private class FeedHistoryContextImpl { private func fetchHole(entry: MessageHistoryHolesViewEntry) -> Signal { //feed.getFeed flags:# filter_id:int offset_to_max_read:flags.3?true offset_position:flags.0?FeedPosition add_offset:int limit:int max_position:flags.1?FeedPosition min_position:flags.2?FeedPosition hash:long = messages.FeedMessages; - - let offsetPosition: Api.FeedPosition? - let addOffset: Int32 = 0 - - switch entry.direction { - case let .range(start, end): - if min(start.id, end.id) == 1 && max(start.id, end.id) == Int32.max - 1 { - offsetPosition = nil - } else { - return .never() - } - case let .aroundId(id): - let _ = id - return .never() - } - - var flags: Int32 = 0 - if let _ = offsetPosition { - flags |= 1 << 0 - } - - let account = self.account - let state = self.stateValue - return self.account.network.request(Api.functions.feed.getFeed( - flags: flags, - filterId: self.feedId, - offsetPosition: offsetPosition, - addOffset: addOffset, - limit: 100, - maxPosition: nil, - minPosition: nil, - hash: 0 - )) - |> map(Optional.init) - |> `catch` { _ -> Signal in - return .single(nil) - } - |> mapToSignal { result -> Signal in - return account.postbox.transaction { transaction -> State in - guard let result = result else { - var updatedState = state ?? State(messageIndices: [], holeIndices: [:]) - updatedState.holeIndices = [:] - return updatedState - } - - let messages: [Api.Message] - let chats: [Api.Chat] - let users: [Api.User] - - switch result { - case let .feedMessages(_, _, _, _, apiMessages, apiChats, apiUsers): - messages = apiMessages - chats = apiChats - users = apiUsers - case .feedMessagesNotModified: - messages = [] - users = [] - chats = [] - } - - var peers: [Peer] = [] - var peerPresences: [PeerId: PeerPresence] = [:] - for chat in chats { - if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) { - peers.append(groupOrChannel) - } - } - for user in users { - let telegramUser = TelegramUser(user: user) - peers.append(telegramUser) - if let presence = TelegramUserPresence(apiUser: user) { - peerPresences[telegramUser.id] = presence - } - } - - var storeMessages: [StoreMessage] = [] - - for message in messages { - if let storeMessage = StoreMessage(apiMessage: message, namespace: Namespaces.Message.Cloud) { - storeMessages.append(storeMessage) - } - } - - updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in - return updated - }) - updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences) - - let _ = transaction.addMessages(storeMessages, location: .Random) - - var updatedState = state ?? State(messageIndices: [], holeIndices: [:]) - var currentSet = Set(updatedState.messageIndices) - - for index in storeMessages.compactMap(\.index) { - if !currentSet.contains(index) { - currentSet.insert(index) - } - updatedState.messageIndices.append(index) - } - - updatedState.messageIndices.sort() - - updatedState.holeIndices = [:] - return updatedState - } - } + return .complete() +// let offsetPosition: Api.FeedPosition? +// let addOffset: Int32 = 0 +// +// switch entry.direction { +// case let .range(start, end): +// if min(start.id, end.id) == 1 && max(start.id, end.id) == Int32.max - 1 { +// offsetPosition = nil +// } else { +// return .never() +// } +// case let .aroundId(id): +// let _ = id +// return .never() +// } +// +// var flags: Int32 = 0 +// if let _ = offsetPosition { +// flags |= 1 << 0 +// } +// +// let account = self.account +// let state = self.stateValue +// return self.account.network.request(Api.functions.feed.getFeed( +// flags: flags, +// filterId: self.feedId, +// offsetPosition: offsetPosition, +// addOffset: addOffset, +// limit: 100, +// maxPosition: nil, +// minPosition: nil, +// hash: 0 +// )) +// |> map(Optional.init) +// |> `catch` { _ -> Signal in +// return .single(nil) +// } +// |> mapToSignal { result -> Signal in +// return account.postbox.transaction { transaction -> State in +// guard let result = result else { +// var updatedState = state ?? State(messageIndices: [], holeIndices: [:]) +// updatedState.holeIndices = [:] +// return updatedState +// } +// +// let messages: [Api.Message] +// let chats: [Api.Chat] +// let users: [Api.User] +// +// switch result { +// case let .feedMessages(_, _, _, _, apiMessages, apiChats, apiUsers): +// messages = apiMessages +// chats = apiChats +// users = apiUsers +// case .feedMessagesNotModified: +// messages = [] +// users = [] +// chats = [] +// } +// +// var peers: [Peer] = [] +// var peerPresences: [PeerId: PeerPresence] = [:] +// for chat in chats { +// if let groupOrChannel = parseTelegramGroupOrChannel(chat: chat) { +// peers.append(groupOrChannel) +// } +// } +// for user in users { +// let telegramUser = TelegramUser(user: user) +// peers.append(telegramUser) +// if let presence = TelegramUserPresence(apiUser: user) { +// peerPresences[telegramUser.id] = presence +// } +// } +// +// var storeMessages: [StoreMessage] = [] +// +// for message in messages { +// if let storeMessage = StoreMessage(apiMessage: message, namespace: Namespaces.Message.Cloud) { +// storeMessages.append(storeMessage) +// } +// } +// +// updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in +// return updated +// }) +// updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences) +// +// let _ = transaction.addMessages(storeMessages, location: .Random) +// +// var updatedState = state ?? State(messageIndices: [], holeIndices: [:]) +// var currentSet = Set(updatedState.messageIndices) +// +// for index in storeMessages.compactMap(\.index) { +// if !currentSet.contains(index) { +// currentSet.insert(index) +// } +// updatedState.messageIndices.append(index) +// } +// +// updatedState.messageIndices.sort() +// +// updatedState.holeIndices = [:] +// return updatedState +// } +// } } func applyMaxReadIndex(messageIndex: MessageIndex) { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelSendRestriction.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelSendRestriction.swift new file mode 100644 index 0000000000..20f562dfe8 --- /dev/null +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChannelSendRestriction.swift @@ -0,0 +1,51 @@ +import Postbox +import TelegramApi +import SwiftSignalKit + +public enum UpdateChannelJoinToSendError { + case generic +} + +func _internal_toggleChannelJoinToSend(postbox: Postbox, network: Network, accountStateManager: AccountStateManager, peerId: PeerId, enabled: Bool) -> Signal { + return postbox.transaction { transaction -> Peer? in + return transaction.getPeer(peerId) + } + |> castError(UpdateChannelJoinToSendError.self) + |> mapToSignal { peer in + guard let peer = peer, let inputChannel = apiInputChannel(peer) else { + return .fail(.generic) + } + return network.request(Api.functions.channels.toggleJoinToSend(channel: inputChannel, enabled: enabled ? .boolTrue : .boolFalse)) + |> `catch` { _ -> Signal in + return .fail(.generic) + } + |> mapToSignal { updates -> Signal in + accountStateManager.addUpdates(updates) + return .complete() + } + } +} + +public enum UpdateChannelJoinRequestError { + case generic +} + +func _internal_toggleChannelJoinRequest(postbox: Postbox, network: Network, accountStateManager: AccountStateManager, peerId: PeerId, enabled: Bool) -> Signal { + return postbox.transaction { transaction -> Peer? in + return transaction.getPeer(peerId) + } + |> castError(UpdateChannelJoinRequestError.self) + |> mapToSignal { peer in + guard let peer = peer, let inputChannel = apiInputChannel(peer) else { + return .fail(.generic) + } + return network.request(Api.functions.channels.toggleJoinRequest(channel: inputChannel, enabled: enabled ? .boolTrue : .boolFalse)) + |> `catch` { _ -> Signal in + return .fail(.generic) + } + |> mapToSignal { updates -> Signal in + accountStateManager.addUpdates(updates) + return .complete() + } + } +} diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/InvitationLinks.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/InvitationLinks.swift index f47874357f..3a9d5ed71a 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/InvitationLinks.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/InvitationLinks.swift @@ -245,7 +245,7 @@ func _internal_peerExportedInvitations(account: Account, peerId: PeerId, revoked return account.postbox.transaction { transaction -> Signal in if let peer = transaction.getPeer(peerId), let inputPeer = apiInputPeer(peer), let adminPeer = transaction.getPeer(adminId ?? account.peerId), let adminId = apiInputUser(adminPeer) { var flags: Int32 = 0 - if let _ = offsetLink { + if let _ = offsetLink?.date { flags |= (1 << 2) } if revoked { @@ -828,19 +828,27 @@ private final class PeerInvitationImportersContextImpl { case let .requests(maybeQuery): query = maybeQuery } - self.link = invite?.link + + var link: String? + var count: Int32 = 0 + if let invite = invite, case let .link(inviteLink, _, _, _, _, _, _, _, _, _, inviteCount, _) = invite { + link = inviteLink + if let inviteCount = inviteCount { + count = inviteCount + } + } + self.link = link + self.count = count + self.requested = requested self.query = query - let count = invite?.count ?? 0 - self.count = count - self.isLoadingMore = true self.disposable.set((account.postbox.transaction { transaction -> (peers: [PeerInvitationImportersState.Importer], count: Int32, canLoadMore: Bool)? in guard query == nil else { return nil } - let cachedResult = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerInvitationImporters, key: CachedPeerInvitationImporters.key(peerId: peerId, link: invite?.link ?? "requests", requested: self.requested)))?.get(CachedPeerInvitationImporters.self) + let cachedResult = transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerInvitationImporters, key: CachedPeerInvitationImporters.key(peerId: peerId, link: link ?? "requests", requested: requested)))?.get(CachedPeerInvitationImporters.self) if let cachedResult = cachedResult, (Int(cachedResult.count) == count || invite == nil) { var result: [PeerInvitationImportersState.Importer] = [] for peerId in cachedResult.peerIds { diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/JoinChannel.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/JoinChannel.swift index e4d435493b..ac45fba6a9 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/JoinChannel.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/JoinChannel.swift @@ -9,6 +9,7 @@ public enum JoinChannelError { case generic case tooMuchJoined case tooMuchUsers + case inviteRequestSent } func _internal_joinChannel(account: Account, peerId: PeerId, hash: String?) -> Signal { @@ -30,6 +31,8 @@ func _internal_joinChannel(account: Account, peerId: PeerId, hash: String?) -> S return .tooMuchJoined case "USERS_TOO_MUCH": return .tooMuchUsers + case "INVITE_REQUEST_SENT": + return .inviteRequestSent default: return .generic } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift index d18dfa0c1d..72cadcefd4 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift @@ -246,6 +246,14 @@ public extension TelegramEngine { public func toggleMessageCopyProtection(peerId: PeerId, enabled: Bool) -> Signal { return _internal_toggleMessageCopyProtection(account: self.account, peerId: peerId, enabled: enabled) } + + public func toggleChannelJoinToSend(peerId: PeerId, enabled: Bool) -> Signal { + return _internal_toggleChannelJoinToSend(postbox: self.account.postbox, network: self.account.network, accountStateManager: self.account.stateManager, peerId: peerId, enabled: enabled) + } + + public func toggleChannelJoinRequest(peerId: PeerId, enabled: Bool) -> Signal { + return _internal_toggleChannelJoinRequest(postbox: self.account.postbox, network: self.account.network, accountStateManager: self.account.stateManager, peerId: peerId, enabled: enabled) + } public func requestPeerPhotos(peerId: PeerId) -> Signal<[TelegramPeerPhoto], NoError> { return _internal_requestPeerPhotos(postbox: self.account.postbox, network: self.account.network, peerId: peerId) diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ToggleChannelSignatures.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ToggleChannelSignatures.swift index 7d2d0a535b..e6ed0ae26d 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ToggleChannelSignatures.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ToggleChannelSignatures.swift @@ -5,7 +5,7 @@ import TelegramApi import MtProtoKit -func _internal_toggleShouldChannelMessagesSignatures(account:Account, peerId:PeerId, enabled: Bool) -> Signal { +func _internal_toggleShouldChannelMessagesSignatures(account: Account, peerId: PeerId, enabled: Bool) -> Signal { return account.postbox.transaction { transaction -> Signal in if let peer = transaction.getPeer(peerId) as? TelegramChannel, let inputChannel = apiInputChannel(peer) { return account.network.request(Api.functions.channels.toggleSignatures(channel: inputChannel, enabled: enabled ? .boolTrue : .boolFalse)) |> retryRequest |> map { updates -> Void in diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift index e303220dd3..0eb33288f1 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/UpdateCachedPeerData.swift @@ -278,10 +278,12 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee var botInfos: [CachedPeerBotInfo] = [] for botInfo in chatFullBotInfo ?? [] { switch botInfo { - case let .botInfo(userId, _, _, _): - let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)) - let parsedBotInfo = BotInfo(apiBotInfo: botInfo) - botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo)) + case let .botInfo(_, userId, _, _, _, _): + if let userId = userId { + let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)) + let parsedBotInfo = BotInfo(apiBotInfo: botInfo) + botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo)) + } } } let participants = CachedGroupParticipants(apiParticipants: chatFullParticipants) @@ -449,10 +451,12 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee var botInfos: [CachedPeerBotInfo] = [] for botInfo in apiBotInfos { switch botInfo { - case let .botInfo(userId, _, _, _): - let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)) - let parsedBotInfo = BotInfo(apiBotInfo: botInfo) - botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo)) + case let .botInfo(_, userId, _, _, _, _): + if let userId = userId { + let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)) + let parsedBotInfo = BotInfo(apiBotInfo: botInfo) + botInfos.append(CachedPeerBotInfo(peerId: peerId, botInfo: parsedBotInfo)) + } } } diff --git a/submodules/TelegramUI/Resources/Animations/anim_delete.json b/submodules/TelegramUI/Resources/Animations/anim_delete.json index 23b20fd472..e805397c54 100644 --- a/submodules/TelegramUI/Resources/Animations/anim_delete.json +++ b/submodules/TelegramUI/Resources/Animations/anim_delete.json @@ -1 +1 @@ -{"v":"5.1.2","fr":60,"ip":0,"op":3600,"w":228,"h":228,"nm":"delete","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"bin2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[114,94,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-0p667_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,0.833]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_0p833"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-3.112,0],[0,0],[-0.269,3.1],[0,0]],"o":[[0,0],[0.269,3.1],[0,0],[3.113,0],[0,0],[0,0]],"v":[[-27,-34.5],[-21.476,29.02],[-15.499,34.5],[15.499,34.5],[21.476,29.02],[27,-34.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,1.057],[-1.884,32.041],[-1.107,0],[0,-1.057],[1.885,-32.041],[1.107,0]],"o":[[0,-0.038],[0.065,-1.105],[1.057,0],[0,0.038],[-0.065,1.105],[-1.058,0]],"v":[[8.586,23.086],[11.413,-25.032],[13.5,-27],[15.414,-25.086],[12.587,23.032],[10.5,25]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,1.105],[0,0],[-1.105,0],[0,-1.105],[0,0],[1.105,0]],"o":[[0,0],[0,-1.105],[1.105,0],[0,0],[0,1.105],[-1.105,0]],"v":[[-2,23],[-2,-25],[0,-27],[2,-25],[2,23],[0,25]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0.065,1.105],[0,0],[-1.057,0],[-0.066,-1.105],[0,0],[1.057,0]],"o":[[0,0],[-0.004,-1.17],[1.107,0],[0,0],[0.004,1.17],[-1.107,0]],"v":[[-12.587,23.032],[-15.411,-24.973],[-13.5,-27],[-11.412,-25.032],[-8.589,22.973],[-10.5,25]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":6,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"bin1 Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[45],"e":[0]},{"t":15}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[270,180,0],"e":[256,211.923,0],"to":[-2.33333325386047,5.32055473327637,0],"ti":[2.33333325386047,-5.32055473327637,0]},{"t":15}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.542,-0.903],[0,0],[0,0],[0,-3.314],[0,0],[3.314,0],[0,0],[0,0],[1.054,0]],"o":[[-1.054,0],[0,0],[0,0],[-3.314,0],[0,0],[0,-3.314],[0,0],[0,0],[-0.542,-0.903],[0,0]],"v":[[-7.301,-6],[-9.874,-4.544],[-12.6,0],[-24,0],[-30,6],[30,6],[24,0],[12.6,0],[9.874,-4.544],[7.301,-6]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-130,"op":3600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{"v":"5.1.2","fr":60,"ip":0,"op":180,"w":228,"h":228,"nm":"delete","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"bin2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[114,94,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-0.667]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-0p667_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,0.833]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_0p833"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-3.112,0],[0,0],[-0.269,3.1],[0,0]],"o":[[0,0],[0.269,3.1],[0,0],[3.113,0],[0,0],[0,0]],"v":[[-27,-34.5],[-21.476,29.02],[-15.499,34.5],[15.499,34.5],[21.476,29.02],[27,-34.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,1.057],[-1.884,32.041],[-1.107,0],[0,-1.057],[1.885,-32.041],[1.107,0]],"o":[[0,-0.038],[0.065,-1.105],[1.057,0],[0,0.038],[-0.065,1.105],[-1.058,0]],"v":[[8.586,23.086],[11.413,-25.032],[13.5,-27],[15.414,-25.086],[12.587,23.032],[10.5,25]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,1.105],[0,0],[-1.105,0],[0,-1.105],[0,0],[1.105,0]],"o":[[0,0],[0,-1.105],[1.105,0],[0,0],[0,1.105],[-1.105,0]],"v":[[-2,23],[-2,-25],[0,-27],[2,-25],[2,23],[0,25]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0.065,1.105],[0,0],[-1.057,0],[-0.066,-1.105],[0,0],[1.057,0]],"o":[[0,0],[-0.004,-1.17],[1.107,0],[0,0],[0.004,1.17],[-1.107,0]],"v":[[-12.587,23.032],[-15.411,-24.973],[-13.5,-27],[-11.412,-25.032],[-8.589,22.973],[-10.5,25]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":6,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"bin1 Outlines","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[45],"e":[0]},{"t":15}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[270,180,0],"e":[256,211.923,0],"to":[-2.33333325386047,5.32055473327637,0],"ti":[2.33333325386047,-5.32055473327637,0]},{"t":15}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100,100],"e":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.542,-0.903],[0,0],[0,0],[0,-3.314],[0,0],[3.314,0],[0,0],[0,0],[1.054,0]],"o":[[-1.054,0],[0,0],[0,0],[-3.314,0],[0,0],[0,-3.314],[0,0],[0,0],[-0.542,-0.903],[0,0]],"v":[[-7.301,-6],[-9.874,-4.544],[-12.6,0],[-24,0],[-30,6],[30,6],[24,0],[12.6,0],[9.874,-4.544],[7.301,-6]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-130,"op":180,"st":0,"bm":0}],"markers":[]} diff --git a/submodules/TelegramUI/Resources/Animations/anim_mute.json b/submodules/TelegramUI/Resources/Animations/anim_mute.json index a8d3b47c04..3023edec89 100644 --- a/submodules/TelegramUI/Resources/Animations/anim_mute.json +++ b/submodules/TelegramUI/Resources/Animations/anim_mute.json @@ -1 +1 @@ -{"v":"5.1.2","fr":60,"ip":0,"op":3600,"w":228,"h":228,"nm":"mute","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"un Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[117.875,88.875,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.863,0.863,-0.19]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p863_0p333_0","0p833_0p863_0p333_0","0p833_-0p19_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.365,0.365,0.476]},"n":["0p667_1_0p167_0p365","0p667_1_0p167_0p365","0p667_1_0p167_0p476"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":14,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,-34],[-33.992,-34]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,-34],[34,34]],"c":false}]},{"t":15}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Group 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 2","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.584313750267,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"mute Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[111,88.781,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.863,0.863,-12.69]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p863_0p333_0","0p833_0p863_0p333_0","0p833_-12p69_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.365,0.365,5.476]},"n":["0p667_1_0p167_0p365","0p667_1_0p167_0p365","0p667_1_0p167_5p476"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":14,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.995,-0.904],[0,0],[0.746,0],[0,0],[0,-3.866],[0,0],[-3.866,0],[0,0],[-0.552,-0.503],[0,0],[-2.006,2.207],[0,1.343],[0,0],[2.982,0]],"o":[[0,0],[-0.552,0.502],[0,0],[-3.866,0],[0,0],[0,3.866],[0,0],[0.746,0],[0,0],[2.207,2.007],[0.903,-0.995],[0,0],[0,-2.982],[-1.343,0]],"v":[[16.967,-36.589],[-6.142,-15.581],[-8.16,-14.801],[-19,-14.801],[-26,-7.801],[-26,7.199],[-19,14.199],[-8.16,14.199],[-6.142,14.98],[16.967,35.987],[24.596,35.625],[26,31.992],[26,-32.594],[20.6,-37.994]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256.994],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{"v":"5.1.2","fr":60,"ip":0,"op":180,"w":228,"h":228,"nm":"mute","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"un Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[117.875,88.875,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.863,0.863,-0.19]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p863_0p333_0","0p833_0p863_0p333_0","0p833_-0p19_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.365,0.365,0.476]},"n":["0p667_1_0p167_0p365","0p667_1_0p167_0p365","0p667_1_0p167_0p476"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":14,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,-34],[-33.992,-34]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,-34],[34,34]],"c":false}]},{"t":15}],"ix":2,"x":"var $bm_rt;\n$bm_rt = content('Group 1').content('Path 1').path;"},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 2","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.584313750267,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"mute Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[111,88.781,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.863,0.863,-12.69]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p863_0p333_0","0p833_0p863_0p333_0","0p833_-12p69_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.365,0.365,5.476]},"n":["0p667_1_0p167_0p365","0p667_1_0p167_0p365","0p667_1_0p167_5p476"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":14,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.995,-0.904],[0,0],[0.746,0],[0,0],[0,-3.866],[0,0],[-3.866,0],[0,0],[-0.552,-0.503],[0,0],[-2.006,2.207],[0,1.343],[0,0],[2.982,0]],"o":[[0,0],[-0.552,0.502],[0,0],[-3.866,0],[0,0],[0,3.866],[0,0],[0.746,0],[0,0],[2.207,2.007],[0.903,-0.995],[0,0],[0,-2.982],[-1.343,0]],"v":[[16.967,-36.589],[-6.142,-15.581],[-8.16,-14.801],[-19,-14.801],[-26,-7.801],[-26,7.199],[-19,14.199],[-8.16,14.199],[-6.142,14.98],[16.967,35.987],[24.596,35.625],[26,31.992],[26,-32.594],[20.6,-37.994]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256.994],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0}],"markers":[]} diff --git a/submodules/TelegramUI/Resources/Animations/anim_pin.json b/submodules/TelegramUI/Resources/Animations/anim_pin.json index adb1491446..b52c38e1c9 100644 --- a/submodules/TelegramUI/Resources/Animations/anim_pin.json +++ b/submodules/TelegramUI/Resources/Animations/anim_pin.json @@ -1 +1 @@ -{"v":"5.1.2","fr":60,"ip":0,"op":3600,"w":228,"h":228,"nm":"pinchat","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"pin Outlines","sr":1,"ks":{"o":{"a":0,"k":99,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[113.656,86.516,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-10.015]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-10p015_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,5.508]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_5p508"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":24}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.682,-2.385],[0,0],[7.227,-5.009],[0.494,-0.402],[0.078,-0.079],[-1.265,-1.266],[0,0],[-0.087,-0.07],[-1.129,1.388],[-0.211,0.297],[2.361,8.281],[0,0],[3.76,3.76],[0,0],[2.035,0]],"o":[[0,0],[-8.176,-2.331],[-0.37,0.258],[-0.086,0.07],[-1.265,1.265],[0,0],[0.079,0.078],[1.388,1.129],[0.312,-0.384],[5.172,-7.273],[0,0],[4.348,-3.067],[0,0],[-1.701,-1.701],[-2.465,0]],"v":[[10.943,-36.491],[-1.24,-19.219],[-25.643,-15.202],[-26.94,-14.213],[-27.187,-13.99],[-27.187,-9.408],[8.801,26.579],[9.049,26.802],[13.607,26.332],[14.391,25.311],[18.607,0.628],[35.879,-11.556],[36.955,-23.925],[23.313,-37.567],[17.514,-40.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-40.714,40.1],[-7.985,15.793],[-16.406,7.372]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256.714,257.1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{"v":"5.1.2","fr":60,"ip":0,"op":180,"w":228,"h":228,"nm":"pinchat","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"pin Outlines","sr":1,"ks":{"o":{"a":0,"k":99,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[113.656,86.516,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-10.015]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-10p015_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,5.508]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_5p508"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":24}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.682,-2.385],[0,0],[7.227,-5.009],[0.494,-0.402],[0.078,-0.079],[-1.265,-1.266],[0,0],[-0.087,-0.07],[-1.129,1.388],[-0.211,0.297],[2.361,8.281],[0,0],[3.76,3.76],[0,0],[2.035,0]],"o":[[0,0],[-8.176,-2.331],[-0.37,0.258],[-0.086,0.07],[-1.265,1.265],[0,0],[0.079,0.078],[1.388,1.129],[0.312,-0.384],[5.172,-7.273],[0,0],[4.348,-3.067],[0,0],[-1.701,-1.701],[-2.465,0]],"v":[[10.943,-36.491],[-1.24,-19.219],[-25.643,-15.202],[-26.94,-14.213],[-27.187,-13.99],[-27.187,-9.408],[8.801,26.579],[9.049,26.802],[13.607,26.332],[14.391,25.311],[18.607,0.628],[35.879,-11.556],[36.955,-23.925],[23.313,-37.567],[17.514,-40.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-40.714,40.1],[-7.985,15.793],[-16.406,7.372]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256.714,257.1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0}],"markers":[]} diff --git a/submodules/TelegramUI/Resources/Animations/anim_unmute.json b/submodules/TelegramUI/Resources/Animations/anim_unmute.json index f1059e9a2d..3463a35da6 100644 --- a/submodules/TelegramUI/Resources/Animations/anim_unmute.json +++ b/submodules/TelegramUI/Resources/Animations/anim_unmute.json @@ -1 +1 @@ -{"v":"5.1.2","fr":60,"ip":0,"op":3600,"w":228,"h":228,"nm":"unmute","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"vol1 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[120,90,0],"e":[131,90,0],"to":[1.83333337306976,0,0],"ti":[-1.83333337306976,0,0]},{"t":10}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.577,-0.531],[0.016,-0.789],[0,0],[-0.516,-0.561],[0,-5.477],[4.174,-4.561],[0.014,-0.704],[0,0],[-0.631,-0.578],[-1.119,1.223],[0,7.023],[5.163,5.605],[0.809,0]],"o":[[-0.627,0.576],[0,0],[0.015,0.706],[4.17,4.526],[0,5.479],[-0.513,0.56],[0,0],[0.016,0.793],[1.222,1.118],[5.16,-5.636],[0,-7.025],[-0.592,-0.641],[-0.726,0]],"v":[[-5.533,-19.371],[-6.5,-17.224],[-6.5,-17.104],[-5.707,-15.133],[0.5,-0.19],[-5.713,14.81],[-6.5,16.777],[-6.5,16.892],[-5.526,19.048],[-1.287,18.859],[6.5,-0.19],[-1.293,-19.198],[-3.501,-20.165]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[255.5,256.165],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"vol2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2,"s":[120,90,0],"e":[146,90,0],"to":[4.33333349227905,0,0],"ti":[-4.33333349227905,0,0]},{"t":12}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":2,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":12,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":17,"s":[115,115,100],"e":[100,100,100]},{"t":27}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.56,-0.468],[-1.06,-1.273],[0,-8.078],[6.916,-8.351],[-1.276,-1.057],[-1.057,1.275],[0,9.591],[7.755,9.312],[0.861,0]],"o":[[-1.274,1.06],[6.912,8.299],[0,8.082],[-1.057,1.276],[1.276,1.056],[7.751,-9.362],[0,-9.592],[-0.593,-0.713],[-0.675,0]],"v":[[-7.235,-28.988],[-7.622,-24.763],[2.684,-0.221],[-7.627,24.404],[-7.229,28.628],[-3.005,28.23],[8.684,-0.221],[-3.011,-28.603],[-5.319,-29.684]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[255.316,256.684],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"vol3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":4,"s":[120,89.062,0],"e":[162,89.062,0],"to":[7,0,0],"ti":[-7,0,0]},{"t":14}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":4,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":14,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":19,"s":[115,115,100],"e":[100,100,100]},{"t":29}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.563,-0.475],[-1.067,-1.267],[0,-12.342],[9.568,-11.435],[-1.27,-1.063],[-0.665,-0.01],[0,0],[-0.582,0.697],[0,13.826],[10.437,12.396],[0.855,0]],"o":[[-1.268,1.066],[9.564,11.36],[0,12.345],[-1.063,1.271],[0.549,0.459],[0,0],[0.842,-0.013],[10.432,-12.468],[0,-13.827],[-0.593,-0.705],[-0.683,0]],"v":[[-9.25,-39.794],[-9.613,-35.568],[4.682,-0.056],[-9.619,35.575],[-9.243,39.801],[-7.364,40.5],[-7.274,40.5],[-5.017,39.425],[10.682,-0.056],[-5.024,-39.432],[-7.319,-40.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[255.318,256.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"mute Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[100,88.781,0],"e":[85,88.781,0],"to":[-2.5,0,0],"ti":[2.5,0,0]},{"t":10}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.995,-0.904],[0,0],[0.746,0],[0,0],[0,-3.866],[0,0],[-3.866,0],[0,0],[-0.552,-0.503],[0,0],[-2.006,2.207],[0,1.343],[0,0],[2.982,0]],"o":[[0,0],[-0.552,0.502],[0,0],[-3.866,0],[0,0],[0,3.866],[0,0],[0.746,0],[0,0],[2.207,2.007],[0.903,-0.995],[0,0],[0,-2.982],[-1.343,0]],"v":[[16.967,-36.589],[-6.142,-15.581],[-8.16,-14.801],[-19,-14.801],[-26,-7.801],[-26,7.199],[-19,14.199],[-8.16,14.199],[-6.142,14.98],[16.967,35.987],[24.596,35.625],[26,31.992],[26,-32.594],[20.6,-37.994]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256.994],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{"v":"5.1.2","fr":60,"ip":0,"op":180,"w":228,"h":228,"nm":"unmute","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"vol1 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[120,90,0],"e":[131,90,0],"to":[1.83333337306976,0,0],"ti":[-1.83333337306976,0,0]},{"t":10}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.577,-0.531],[0.016,-0.789],[0,0],[-0.516,-0.561],[0,-5.477],[4.174,-4.561],[0.014,-0.704],[0,0],[-0.631,-0.578],[-1.119,1.223],[0,7.023],[5.163,5.605],[0.809,0]],"o":[[-0.627,0.576],[0,0],[0.015,0.706],[4.17,4.526],[0,5.479],[-0.513,0.56],[0,0],[0.016,0.793],[1.222,1.118],[5.16,-5.636],[0,-7.025],[-0.592,-0.641],[-0.726,0]],"v":[[-5.533,-19.371],[-6.5,-17.224],[-6.5,-17.104],[-5.707,-15.133],[0.5,-0.19],[-5.713,14.81],[-6.5,16.777],[-6.5,16.892],[-5.526,19.048],[-1.287,18.859],[6.5,-0.19],[-1.293,-19.198],[-3.501,-20.165]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[255.5,256.165],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"vol2 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":2,"s":[120,90,0],"e":[146,90,0],"to":[4.33333349227905,0,0],"ti":[-4.33333349227905,0,0]},{"t":12}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":2,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":12,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":17,"s":[115,115,100],"e":[100,100,100]},{"t":27}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.56,-0.468],[-1.06,-1.273],[0,-8.078],[6.916,-8.351],[-1.276,-1.057],[-1.057,1.275],[0,9.591],[7.755,9.312],[0.861,0]],"o":[[-1.274,1.06],[6.912,8.299],[0,8.082],[-1.057,1.276],[1.276,1.056],[7.751,-9.362],[0,-9.592],[-0.593,-0.713],[-0.675,0]],"v":[[-7.235,-28.988],[-7.622,-24.763],[2.684,-0.221],[-7.627,24.404],[-7.229,28.628],[-3.005,28.23],[8.684,-0.221],[-3.011,-28.603],[-5.319,-29.684]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[255.316,256.684],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"vol3 Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":4,"s":[120,89.062,0],"e":[162,89.062,0],"to":[7,0,0],"ti":[-7,0,0]},{"t":14}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":4,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":14,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":19,"s":[115,115,100],"e":[100,100,100]},{"t":29}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.563,-0.475],[-1.067,-1.267],[0,-12.342],[9.568,-11.435],[-1.27,-1.063],[-0.665,-0.01],[0,0],[-0.582,0.697],[0,13.826],[10.437,12.396],[0.855,0]],"o":[[-1.268,1.066],[9.564,11.36],[0,12.345],[-1.063,1.271],[0.549,0.459],[0,0],[0.842,-0.013],[10.432,-12.468],[0,-13.827],[-0.593,-0.705],[-0.683,0]],"v":[[-9.25,-39.794],[-9.613,-35.568],[4.682,-0.056],[-9.619,35.575],[-9.243,39.801],[-7.364,40.5],[-7.274,40.5],[-5.017,39.425],[10.682,-0.056],[-5.024,-39.432],[-7.319,-40.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[255.318,256.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"mute Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[100,88.781,0],"e":[85,88.781,0],"to":[-2.5,0,0],"ti":[2.5,0,0]},{"t":10}],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":25}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.995,-0.904],[0,0],[0.746,0],[0,0],[0,-3.866],[0,0],[-3.866,0],[0,0],[-0.552,-0.503],[0,0],[-2.006,2.207],[0,1.343],[0,0],[2.982,0]],"o":[[0,0],[-0.552,0.502],[0,0],[-3.866,0],[0,0],[0,3.866],[0,0],[0.746,0],[0,0],[2.207,2.007],[0.903,-0.995],[0,0],[0,-2.982],[-1.343,0]],"v":[[16.967,-36.589],[-6.142,-15.581],[-8.16,-14.801],[-19,-14.801],[-26,-7.801],[-26,7.199],[-19,14.199],[-8.16,14.199],[-6.142,14.98],[16.967,35.987],[24.596,35.625],[26,31.992],[26,-32.594],[20.6,-37.994]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256.994],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0}],"markers":[]} diff --git a/submodules/TelegramUI/Resources/Animations/anim_unpin.json b/submodules/TelegramUI/Resources/Animations/anim_unpin.json index 3a0750f7a8..dbe2c23a20 100644 --- a/submodules/TelegramUI/Resources/Animations/anim_unpin.json +++ b/submodules/TelegramUI/Resources/Animations/anim_unpin.json @@ -1 +1 @@ -{"v":"5.1.2","fr":60,"ip":0,"op":3600,"w":228,"h":228,"nm":"unpinpinchat","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"un Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[118,84.062,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":24}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,-34],[-33.992,-34]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,-34],[34,34]],"c":false}]},{"t":15}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 2","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"st","c":{"a":0,"k":[0.097999999102,0.57599995931,0.980000035903,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"pin Outlines","sr":1,"ks":{"o":{"a":0,"k":99,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[113.656,86.516,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.859,0.859,-13.056]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p859_0p333_0","0p833_0p859_0p333_0","0p833_-13p056_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.341,0.341,5.111]},"n":["0p667_1_0p167_0p341","0p667_1_0p167_0p341","0p667_1_0p167_5p111"],"t":11,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":24}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.682,-2.385],[0,0],[7.227,-5.009],[0.494,-0.402],[0.078,-0.079],[-1.265,-1.266],[0,0],[-0.087,-0.07],[-1.129,1.388],[-0.211,0.297],[2.361,8.281],[0,0],[3.76,3.76],[0,0],[2.035,0]],"o":[[0,0],[-8.176,-2.331],[-0.37,0.258],[-0.086,0.07],[-1.265,1.265],[0,0],[0.079,0.078],[1.388,1.129],[0.312,-0.384],[5.172,-7.273],[0,0],[4.348,-3.067],[0,0],[-1.701,-1.701],[-2.465,0]],"v":[[10.943,-36.491],[-1.24,-19.219],[-25.643,-15.202],[-26.94,-14.213],[-27.187,-13.99],[-27.187,-9.408],[8.801,26.579],[9.049,26.802],[13.607,26.332],[14.391,25.311],[18.607,0.628],[35.879,-11.556],[36.955,-23.925],[23.313,-37.567],[17.514,-40.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-40.714,40.1],[-7.985,15.793],[-16.406,7.372]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256.714,257.1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{"v":"5.1.2","fr":60,"ip":0,"op":180,"w":228,"h":228,"nm":"unpinpinchat","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"un Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[118,84.062,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.872,0.872,-11.778]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p872_0p333_0","0p833_0p872_0p333_0","0p833_-11p778_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.426,0.426,6.389]},"n":["0p667_1_0p167_0p426","0p667_1_0p167_0p426","0p667_1_0p167_6p389"],"t":10,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":24}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":5,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,-34],[-33.992,-34]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-34,-34],[34,34]],"c":false}]},{"t":15}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 2","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"st","c":{"a":0,"k":[0.097999999102,0.57599995931,0.980000035903,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":15,"ix":5},"lc":2,"lj":1,"ml":10,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"pin Outlines","sr":1,"ks":{"o":{"a":0,"k":99,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[113.656,86.516,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.859,0.859,-13.056]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p833_0p859_0p333_0","0p833_0p859_0p333_0","0p833_-13p056_0p333_0"],"t":0,"s":[0,0,100],"e":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.341,0.341,5.111]},"n":["0p667_1_0p167_0p341","0p667_1_0p167_0p341","0p667_1_0p167_5p111"],"t":11,"s":[100,100,100],"e":[115,115,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"n":["0p667_1_0p333_0","0p667_1_0p333_0","0p667_1_0p333_0"],"t":15,"s":[115,115,100],"e":[100,100,100]},{"t":24}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.682,-2.385],[0,0],[7.227,-5.009],[0.494,-0.402],[0.078,-0.079],[-1.265,-1.266],[0,0],[-0.087,-0.07],[-1.129,1.388],[-0.211,0.297],[2.361,8.281],[0,0],[3.76,3.76],[0,0],[2.035,0]],"o":[[0,0],[-8.176,-2.331],[-0.37,0.258],[-0.086,0.07],[-1.265,1.265],[0,0],[0.079,0.078],[1.388,1.129],[0.312,-0.384],[5.172,-7.273],[0,0],[4.348,-3.067],[0,0],[-1.701,-1.701],[-2.465,0]],"v":[[10.943,-36.491],[-1.24,-19.219],[-25.643,-15.202],[-26.94,-14.213],[-27.187,-13.99],[-27.187,-9.408],[8.801,26.579],[9.049,26.802],[13.607,26.332],[14.391,25.311],[18.607,0.628],[35.879,-11.556],[36.955,-23.925],[23.313,-37.567],[17.514,-40.1]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-40.714,40.1],[-7.985,15.793],[-16.406,7.372]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256.714,257.1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0}],"markers":[]} diff --git a/submodules/TelegramUI/Sources/ChatChannelSubscriberInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatChannelSubscriberInputPanelNode.swift index 962f665435..4f4cf02bf3 100644 --- a/submodules/TelegramUI/Sources/ChatChannelSubscriberInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatChannelSubscriberInputPanelNode.swift @@ -14,6 +14,8 @@ import ChatPresentationInterfaceState private enum SubscriberAction: Equatable { case join + case joinGroup + case applyToJoin case kicked case muteNotifications case unmuteNotifications @@ -25,6 +27,10 @@ private func titleAndColorForAction(_ action: SubscriberAction, theme: Presentat switch action { case .join: return (strings.Channel_JoinChannel, theme.chat.inputPanel.panelControlAccentColor) + case .joinGroup: + return (strings.Group_JoinGroup, theme.chat.inputPanel.panelControlAccentColor) + case .applyToJoin: + return (strings.Group_ApplyToJoin, theme.chat.inputPanel.panelControlAccentColor) case .kicked: return (strings.Channel_JoinChannel, theme.chat.inputPanel.panelControlDisabledColor) case .muteNotifications: @@ -75,7 +81,15 @@ private func actionForPeer(peer: Peer, interfaceState: ChatPresentationInterface case .kicked: return .kicked case .left: - return .join + if case .group = channel.info { + if channel.flags.contains(.requestToJoin) { + return .applyToJoin + } else { + return .joinGroup + } + } else { + return .join + } case .member: if isMuted { return .unmuteNotifications @@ -175,7 +189,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { } switch action { - case .join: + case .join, .joinGroup, .applyToJoin: var delayActivity = false if let peer = peer as? TelegramChannel, case .broadcast = peer.info { delayActivity = true @@ -212,6 +226,10 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode { } let text: String switch error { + case .inviteRequestSent: + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + strongSelf.interfaceInteraction?.presentController(UndoOverlayController(presentationData: presentationData, content: .inviteRequestSent(title: presentationInterfaceState.strings.Group_RequestToJoinSent, text: presentationInterfaceState.strings.Group_RequestToJoinSentDescriptionGroup ), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), nil) + return case .tooMuchJoined: strongSelf.interfaceInteraction?.getNavigationController()?.pushViewController(oldChannelsController(context: context, intent: .join, completed: { value in if value { diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index ac43604d13..e7c8ea7209 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -2931,7 +2931,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G window.rootViewController?.present(controller, animated: true) } case .speak: - let _ = speakText(text.string) + let _ = speakText(context: strongSelf.context, text: text.string) case .translate: strongSelf.chatDisplayNode.dismissInput() diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift index 0e08faf9f9..033774677c 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateInputPanels.swift @@ -152,7 +152,9 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState isMember = true case .left: if case .replyThread = chatPresentationInterfaceState.chatLocation { - isMember = true + if !channel.flags.contains(.joinToSend) { + isMember = true + } } } diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift index 3859580099..5aec0a2665 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsControllerNode.swift @@ -154,16 +154,16 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode { return true } case let .editExportedInvitation(_, invite), let .revokeExportedInvitation(invite), let .deleteExportedInvitation(invite), let .participantJoinedViaInvite(invite), let .participantJoinByRequest(invite, _): - if !invite.link.hasSuffix("...") { + if let inviteLink = invite.link, !inviteLink.hasSuffix("...") { if invite.isPermanent { let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData) var items: [ActionSheetItem] = [] - items.append(ActionSheetTextItem(title: invite.link)) + items.append(ActionSheetTextItem(title: inviteLink)) items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.InviteLink_ContextRevoke, color: .destructive, action: { [weak actionSheet] in actionSheet?.dismissAnimated() if let strongSelf = self { - let _ = (strongSelf.context.engine.peers.revokePeerExportedInvitation(peerId: peer.id, link: invite.link) + let _ = (strongSelf.context.engine.peers.revokePeerExportedInvitation(peerId: peer.id, link: inviteLink) |> deliverOnMainQueue).start(completed: { [weak self] in self?.eventLogContext.reload() }) diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift b/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift index 17f7649a2f..44cf6bff55 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsHistoryTransition.swift @@ -1275,7 +1275,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { var text: String = "" var entities: [MessageTextEntity] = [] - let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_DeletedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link.replacingOccurrences(of: "https://", with: "")) + let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_DeletedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link?.replacingOccurrences(of: "https://", with: "") ?? "") appendAttributedText(text: rawText, generateEntities: { index in if index == 0, let author = author { @@ -1301,7 +1301,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { var text: String = "" var entities: [MessageTextEntity] = [] - let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_RevokedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link.replacingOccurrences(of: "https://", with: "")) + let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_RevokedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link?.replacingOccurrences(of: "https://", with: "") ?? "") appendAttributedText(text: rawText, generateEntities: { index in if index == 0, let author = author { @@ -1327,7 +1327,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { var text: String = "" var entities: [MessageTextEntity] = [] - let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_EditedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", updatedInvite.link.replacingOccurrences(of: "https://", with: "")) + let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_EditedInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", updatedInvite.link?.replacingOccurrences(of: "https://", with: "") ?? "") appendAttributedText(text: rawText, generateEntities: { index in if index == 0, let author = author { @@ -1353,7 +1353,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { var text: String = "" var entities: [MessageTextEntity] = [] - let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_JoinedViaInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link.replacingOccurrences(of: "https://", with: "")) + let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_JoinedViaInviteLink(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link?.replacingOccurrences(of: "https://", with: "") ?? "") appendAttributedText(text: rawText, generateEntities: { index in if index == 0, let author = author { @@ -1478,7 +1478,14 @@ struct ChatRecentActionsEntry: Comparable, Identifiable { var text: String = "" var entities: [MessageTextEntity] = [] - let rawText: PresentationStrings.FormattedString = self.presentationData.strings.Channel_AdminLog_JoinedViaRequest(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", invite.link.replacingOccurrences(of: "https://", with: ""), approver.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "") + let rawText: PresentationStrings.FormattedString + switch invite { + case let .link(link, _, _, _, _, _, _, _, _, _, _, _): + rawText = self.presentationData.strings.Channel_AdminLog_JoinedViaRequest(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", link.replacingOccurrences(of: "https://", with: ""), approver.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "") + case .publicJoinRequest: + rawText = self.presentationData.strings.Channel_AdminLog_JoinedViaPublicRequest(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", approver.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "") + } + appendAttributedText(text: rawText, generateEntities: { index in if index == 0, let author = author { diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index ecdf8f7c6d..5015b8c57d 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -2367,7 +2367,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { text = current.inputText.attributedSubstring(from: NSMakeRange(current.selectionRange.lowerBound, current.selectionRange.count)).string return (current, inputMode) } - let _ = speakText(text) + if let context = self.context { + let _ = speakText(context: context, text: text) + } if #available(iOS 13.0, *) { UIMenuController.shared.hideMenu() diff --git a/submodules/TranslateUI/Sources/TranslateScreen.swift b/submodules/TranslateUI/Sources/TranslateScreen.swift index da8dfe58c5..c56dda4d84 100644 --- a/submodules/TranslateUI/Sources/TranslateScreen.swift +++ b/submodules/TranslateUI/Sources/TranslateScreen.swift @@ -160,7 +160,7 @@ private final class TranslateScreenComponent: CombinedComponent { self.isSpeakingTranslatedText = false self.isSpeakingOriginalText = true - self.speechHolder = speakText(self.text) + self.speechHolder = speakText(context: self.context, text: self.text) self.speechHolder?.completion = { [weak self] in guard let strongSelf = self else { return @@ -188,7 +188,7 @@ private final class TranslateScreenComponent: CombinedComponent { self.isSpeakingOriginalText = false self.isSpeakingTranslatedText = true - self.speechHolder = speakText(translatedText) + self.speechHolder = speakText(context: self.context, text: translatedText) self.speechHolder?.completion = { [weak self] in guard let strongSelf = self else { return diff --git a/submodules/rlottie/LottieInstance.mm b/submodules/rlottie/LottieInstance.mm index 57c601ee0c..be5ddb4844 100755 --- a/submodules/rlottie/LottieInstance.mm +++ b/submodules/rlottie/LottieInstance.mm @@ -10,7 +10,7 @@ @implementation LottieInstance -- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data fitzModifier:(LottieFitzModifier)fitzModifier cacheKey:(NSString * _Nonnull)cacheKey { +- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data fitzModifier:(LottieFitzModifier)fitzModifier colorReplacements:(NSDictionary * _Nullable)colorReplacements cacheKey:(NSString * _Nonnull)cacheKey { self = [super init]; if (self != nil) { rlottie::FitzModifier modifier; @@ -35,7 +35,15 @@ break; } - _animation = rlottie::Animation::loadFromData(std::string(reinterpret_cast(data.bytes), data.length), std::string([cacheKey UTF8String]), "", false, {}, modifier); + std::vector> colorsVector; + if (colorReplacements != nil) { + for (NSNumber *color in colorReplacements.allKeys) { + NSNumber *replacement = colorReplacements[color]; + colorsVector.push_back({ color.unsignedIntValue, replacement.unsignedIntValue }); + } + } + + _animation = rlottie::Animation::loadFromData(std::string(reinterpret_cast(data.bytes), data.length), std::string([cacheKey UTF8String]), "", false, colorsVector, modifier); if (_animation == nullptr) { return nil; } diff --git a/submodules/rlottie/PublicHeaders/RLottieBinding/LottieInstance.h b/submodules/rlottie/PublicHeaders/RLottieBinding/LottieInstance.h index f926fe08dd..891d777f0a 100755 --- a/submodules/rlottie/PublicHeaders/RLottieBinding/LottieInstance.h +++ b/submodules/rlottie/PublicHeaders/RLottieBinding/LottieInstance.h @@ -19,7 +19,8 @@ typedef NS_ENUM(int32_t, LottieFitzModifier) { @property (nonatomic, readonly) int32_t frameRate; @property (nonatomic, readonly) CGSize dimensions; -- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data fitzModifier:(LottieFitzModifier)fitzModifier cacheKey:(NSString * _Nonnull)cacheKey; +- (instancetype _Nullable)initWithData:(NSData * _Nonnull)data fitzModifier:(LottieFitzModifier)fitzModifier colorReplacements:(NSDictionary * _Nullable)colorReplacements cacheKey:(NSString * _Nonnull)cacheKey; + - (void)renderFrameWithIndex:(int32_t)index into:(uint8_t * _Nonnull)buffer width:(int32_t)width height:(int32_t)height bytesPerRow:(int32_t)bytesPerRow; @end