diff --git a/Telegram/Telegram-iOS/Resources/GiftDiamond.tgs b/Telegram/Telegram-iOS/Resources/GiftDiamond.tgs deleted file mode 100644 index 60709e5bbd..0000000000 Binary files a/Telegram/Telegram-iOS/Resources/GiftDiamond.tgs and /dev/null differ diff --git a/Telegram/Telegram-iOS/Resources/GiftDiamond1.tgs b/Telegram/Telegram-iOS/Resources/GiftDiamond1.tgs new file mode 100644 index 0000000000..7a0a883ac4 Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/GiftDiamond1.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/GiftDiamond2.tgs b/Telegram/Telegram-iOS/Resources/GiftDiamond2.tgs new file mode 100644 index 0000000000..caa69f5266 Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/GiftDiamond2.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/GiftDiamond3.tgs b/Telegram/Telegram-iOS/Resources/GiftDiamond3.tgs new file mode 100644 index 0000000000..bcf3609d1f Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/GiftDiamond3.tgs differ diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 2ee614d0c8..8fbcc99a42 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -14504,4 +14504,6 @@ Sorry for the inconvenience."; "Bot.AddToGroup.Title" = "Add to Group"; "Bot.AddToChannel.Title" = "Add to Channel"; -"ScheduledMessages.TodoUnavailable" = "Voting will become available after the message is published."; +"ScheduledMessages.TodoUnavailable" = "Completing tasks will become available after the message is published."; + +"Attachment.DiscardTodoAlertText" = "Discard checklist items?"; diff --git a/submodules/ComposePollUI/Sources/ComposePollScreen.swift b/submodules/ComposePollUI/Sources/ComposePollScreen.swift index ad42d62299..5e11feb4dd 100644 --- a/submodules/ComposePollUI/Sources/ComposePollScreen.swift +++ b/submodules/ComposePollUI/Sources/ComposePollScreen.swift @@ -1834,7 +1834,7 @@ public class ComposePollScreen: ViewControllerComponentContainer, AttachmentCont public func prepareForReuse() { } - public func requestDismiss(completion: @escaping () -> Void) { + public func requestDismiss(completion: @escaping () -> Void) { completion() } diff --git a/submodules/StatisticsUI/Sources/ChannelStatsController.swift b/submodules/StatisticsUI/Sources/ChannelStatsController.swift index 382a785978..abfc97fd36 100644 --- a/submodules/StatisticsUI/Sources/ChannelStatsController.swift +++ b/submodules/StatisticsUI/Sources/ChannelStatsController.swift @@ -1178,6 +1178,10 @@ private enum StatsEntry: ItemListNodeEntry { } else if transaction.flags.contains(.isRefund) { title = NSAttributedString(string: presentationData.strings.Monetization_Transaction_Refund, font: font, textColor: theme.list.itemPrimaryTextColor) detailText = stringForMediumCompactDate(timestamp: transaction.date, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat) + } else if case .peer = transaction.peer { + return StarsTransactionItem(context: arguments.context, presentationData: presentationData, transaction: transaction, action: { + arguments.openStarsTransaction(transaction) + }, sectionId: self.section, style: .blocks) } else { title = NSAttributedString() detailText = "" diff --git a/submodules/StatisticsUI/Sources/StarsTransactionItem.swift b/submodules/StatisticsUI/Sources/StarsTransactionItem.swift index 426c3b0db8..13d4e41574 100644 --- a/submodules/StatisticsUI/Sources/StarsTransactionItem.swift +++ b/submodules/StatisticsUI/Sources/StarsTransactionItem.swift @@ -278,17 +278,12 @@ final class StarsTransactionItemNode: ListViewItemNode, ItemListItemNode { } let itemLabel: NSAttributedString - let labelString: String + let formattedLabel = formatCurrencyAmountText(item.transaction.count, dateTimeFormat: item.presentationData.dateTimeFormat, showPlus: true) - let absCount = StarsAmount(value: abs(item.transaction.count.amount.value), nanos: abs(item.transaction.count.amount.nanos)) - let formattedLabel = presentationStringsFormattedNumber(absCount, item.presentationData.dateTimeFormat.groupingSeparator) - if item.transaction.count.amount < StarsAmount.zero { - labelString = "- \(formattedLabel)" - } else { - labelString = "+ \(formattedLabel)" - } - let itemLabelColor = labelString.hasPrefix("-") ? item.presentationData.theme.list.itemDestructiveColor : item.presentationData.theme.list.itemDisclosureActions.constructive.fillColor - itemLabel = NSAttributedString(string: labelString, font: Font.medium(fontBaseDisplaySize), textColor: itemLabelColor) + let smallLabelFont = Font.with(size: floor(fontBaseDisplaySize / 17.0 * 13.0)) + let labelFont = Font.medium(fontBaseDisplaySize) + let labelColor = formattedLabel.hasPrefix("-") ? item.presentationData.theme.list.itemDestructiveColor : item.presentationData.theme.list.itemDisclosureActions.constructive.fillColor + itemLabel = tonAmountAttributedString(formattedLabel, integralFont: labelFont, fractionalFont: smallLabelFont, color: labelColor, decimalSeparator: item.presentationData.dateTimeFormat.decimalSeparator) var itemDateColor = item.presentationData.theme.list.itemSecondaryTextColor itemDate = stringForMediumCompactDate(timestamp: item.transaction.date, strings: item.presentationData.strings, dateTimeFormat: item.presentationData.dateTimeFormat) @@ -334,6 +329,18 @@ final class StarsTransactionItemNode: ListViewItemNode, ItemListItemNode { maximumNumberOfLines: 1 ))) ) + + let itemIconName: String + let itemIconColor: UIColor? + switch item.transaction.count.currency { + case .stars: + itemIconName = "Premium/Stars/StarMedium" + itemIconColor = nil + case .ton: + itemIconName = "Ads/TonAbout" + itemIconColor = labelColor + } + let itemSize = strongSelf.componentView.update( transition: .immediate, component: AnyComponent(ListActionItemComponent( @@ -342,7 +349,7 @@ final class StarsTransactionItemNode: ListViewItemNode, ItemListItemNode { contentInsets: UIEdgeInsets(top: 9.0, left: 0.0, bottom: 8.0, right: 0.0), leftIcon: .custom(AnyComponentWithIdentity(id: "avatar", component: AnyComponent(StarsAvatarComponent(context: item.context, theme: item.presentationData.theme, peer: item.transaction.peer, photo: nil, media: [], uniqueGift: nil, backgroundColor: item.presentationData.theme.list.itemBlocksBackgroundColor))), false), icon: nil, - accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: "label", component: AnyComponent(StarsLabelComponent(text: itemLabel))), insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))), + accessory: .custom(ListActionItemComponent.CustomAccessory(component: AnyComponentWithIdentity(id: "label", component: AnyComponent(StarsLabelComponent(text: itemLabel, iconName: itemIconName, iconColor: itemIconColor))), insets: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 16.0))), action: { [weak self] _ in guard let self, let item = self.item else { return diff --git a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift index f61320c87b..9536782077 100644 --- a/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift +++ b/submodules/TelegramPresentationData/Sources/Resources/PresentationResourcesChat.swift @@ -1447,7 +1447,7 @@ public struct PresentationResourcesChat { public static func chatServiceMessageTodoAppendedIcon(_ theme: PresentationTheme) -> UIImage? { return theme.image(PresentationResourceKey.chatServiceMessageTodoAppendedIcon.rawValue, { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/ServiceTodoIncompleted"), color: .white) + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Message/ServiceTodoAppended"), color: .white) }) } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift index c32acf3826..1f898eb3df 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift @@ -442,7 +442,7 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { } } for i in 0 ..< labelRects.count { - labelRects[i] = labelRects[i].insetBy(dx: -6.0, dy: floor((labelRects[i].height - 22.0) / 2.0)) + labelRects[i] = labelRects[i].insetBy(dx: -7.0, dy: floor((labelRects[i].height - 22.0) / 2.0)) labelRects[i].size.height = 22.0 labelRects[i].origin.x = floor((labelLayout.size.width - labelRects[i].width) / 2.0) } @@ -458,7 +458,7 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { if let (currentOffset, currentImage, currentRects) = cachedMaskBackgroundImage, currentRects == labelRects { backgroundMaskImage = (currentOffset, currentImage) } else { - backgroundMaskImage = LinkHighlightingNode.generateImage(color: .white, inset: 0.0, innerRadius: 10.0, outerRadius: 10.0, rects: labelRects, useModernPathCalculation: false) + backgroundMaskImage = LinkHighlightingNode.generateImage(color: .white, inset: 0.0, innerRadius: 11.0, outerRadius: 11.0, rects: labelRects, useModernPathCalculation: false) backgroundMaskUpdated = true } } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift index 44bf777edc..6bdd21ecc7 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift @@ -417,21 +417,22 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { } title = item.presentationData.strings.Notification_StarsGift_Title(Int32(count)) text = incoming ? item.presentationData.strings.Notification_StarsGift_Subtitle : item.presentationData.strings.Notification_StarsGift_SubtitleYou(peerName).string - case let .giftTon(currency, amount, cryptoCurrency, cryptoAmount, _): - months = 1000 + case let .giftTon(_, amount, _, cryptoAmount, _): + if amount < 10000000000 { + months = 1000 + } else if amount < 50000000000 { + months = 2000 + } else { + months = 3000 + } var peerName = "" if let peer = item.message.peers[item.message.id.peerId] { peerName = EnginePeer(peer).compactDisplayTitle } - //TODO:localize - let _ = currency - let _ = amount - let _ = cryptoCurrency - let cryptoAmount = cryptoAmount ?? 0 - title = "$ \(formatTonAmountText(cryptoAmount, dateTimeFormat: item.presentationData.dateTimeFormat))" + title = "$ \(formatTonAmountText(cryptoAmount, dateTimeFormat: item.presentationData.dateTimeFormat, maxDecimalPositions: 3))" text = incoming ? "Use TON to submit post suggestions to channels." : "With TON, \(peerName) will be able to submit post suggestions to channels." buttonTitle = "" case let .prizeStars(count, _, channelId, _, _): @@ -644,7 +645,11 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { switch months { case 1000: - animationName = "GiftDiamond" + animationName = "GiftDiamond1" + case 2000: + animationName = "GiftDiamond2" + case 3000: + animationName = "GiftDiamond3" case 12: animationName = "Gift12" case 6: @@ -787,8 +792,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { } } for i in 0 ..< labelRects.count { - labelRects[i] = labelRects[i].insetBy(dx: -6.0, dy: floor((labelRects[i].height - 20.0) / 2.0)) - labelRects[i].size.height = 20.0 + labelRects[i] = labelRects[i].insetBy(dx: -7.0, dy: floor((labelRects[i].height - 22.0) / 2.0)) + labelRects[i].size.height = 22.0 labelRects[i].origin.x = floor((labelLayout.size.width - labelRects[i].width) / 2.0) } @@ -798,7 +803,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { if let (currentOffset, currentImage, currentRects) = cachedMaskBackgroundImage, currentRects == labelRects { backgroundMaskImage = (currentOffset, currentImage) } else { - backgroundMaskImage = LinkHighlightingNode.generateImage(color: .black, inset: 0.0, innerRadius: 10.0, outerRadius: 10.0, rects: labelRects, useModernPathCalculation: false) + backgroundMaskImage = LinkHighlightingNode.generateImage(color: .black, inset: 0.0, innerRadius: 11.0, outerRadius: 11.0, rects: labelRects, useModernPathCalculation: false) backgroundMaskUpdated = true } } else { @@ -807,7 +812,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { var backgroundSize = giftSize if hasServiceMessage { - backgroundSize.height += labelLayout.size.height + 18.0 + backgroundSize.height += labelLayout.size.height + 20.0 } else { backgroundSize.height += 4.0 } @@ -828,7 +833,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { let overlayColor = item.presentationData.theme.theme.overallDarkAppearance && uniquePatternFile == nil ? UIColor(rgb: 0xffffff, alpha: 0.12) : UIColor(rgb: 0x000000, alpha: 0.12) - let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((boundingWidth - giftSize.width) / 2.0), y: hasServiceMessage ? labelLayout.size.height + 12.0 : 0.0), size: giftSize) + let imageFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((boundingWidth - giftSize.width) / 2.0), y: hasServiceMessage ? labelLayout.size.height + 13.0 : 0.0), size: giftSize) let mediaBackgroundFrame = imageFrame.insetBy(dx: -2.0, dy: -2.0) var iconSize = CGSize(width: 160.0, height: 160.0) diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift index 3cd40d5a24..fe537f66c2 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageTodoBubbleContentNode/Sources/ChatMessageTodoBubbleContentNode.swift @@ -376,6 +376,7 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { private var backgroundWallpaperNode: ChatMessageBubbleBackdrop? private var backgroundNode: ChatMessageBackground? private var extractedRadioView: UIView? + private var extractedIconView: UIView? private var extractedAvatarView: UIView? private var extractedTitleNode: TextNodeWithEntities? private var extractedNameView: UIView? @@ -549,6 +550,11 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { // self.backgroundWallpaperNode?.update(rect: mappedRect, within: containerSize) // } + if let extractedIconView = self.iconNode?.view.snapshotContentTree() { + self.extractedIconView = extractedIconView + self.contextSourceNode.contentNode.view.addSubview(extractedIconView) + } + if let extractedRadioView = self.radioNode?.view.snapshotContentTree() { self.extractedRadioView = extractedRadioView self.contextSourceNode.contentNode.view.addSubview(extractedRadioView) @@ -585,6 +591,8 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { transition.updateAlpha(node: backgroundNode, alpha: 0.0, completion: { [weak backgroundNode] _ in self.extractedRadioView?.removeFromSuperview() self.extractedRadioView = nil + self.extractedIconView?.removeFromSuperview() + self.extractedIconView = nil self.extractedAvatarView?.removeFromSuperview() self.extractedAvatarView = nil self.extractedTitleNode?.textNode.removeFromSupernode() @@ -737,7 +745,7 @@ private final class ChatMessageTodoItemNode: ASDisplayNode { } else { titleNodeFrame = CGRect(origin: CGPoint(x: leftInset, y: 12.0), size: titleLayout.size) } - if let _ = completion, canMark && todo.flags.contains(.othersCanComplete) { + if let _ = completion, todo.flags.contains(.othersCanComplete) { titleNodeFrame = titleNodeFrame.offsetBy(dx: 0.0, dy: -6.0) } diff --git a/submodules/TelegramUI/Components/ComposeTodoScreen/Sources/ComposeTodoScreen.swift b/submodules/TelegramUI/Components/ComposeTodoScreen/Sources/ComposeTodoScreen.swift index 45e196a195..11bf50912b 100644 --- a/submodules/TelegramUI/Components/ComposeTodoScreen/Sources/ComposeTodoScreen.swift +++ b/submodules/TelegramUI/Components/ComposeTodoScreen/Sources/ComposeTodoScreen.swift @@ -28,6 +28,7 @@ import TextFormat import TextFieldComponent import ListComposePollOptionComponent import Markdown +import PresentationDataUtils final class ComposeTodoScreenComponent: Component { typealias EnvironmentType = ViewControllerComponentContainer.Environment @@ -1750,10 +1751,30 @@ public class ComposeTodoScreen: ViewControllerComponentContainer, AttachmentCont } public func requestDismiss(completion: @escaping () -> Void) { - completion() + guard let componentView = self.node.hostView.componentView as? ComposeTodoScreenComponent.View else { + return + } + let presentationData = self.context.sharedContext.currentPresentationData.with { $0 } + if let input = componentView.validatedInput(), !input.text.isEmpty || !input.items.isEmpty { + let text = presentationData.strings.Attachment_DiscardTodoAlertText + let controller = textAlertController(context: self.context, title: nil, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Attachment_CancelSelectionAlertNo, action: { + }), TextAlertAction(type: .defaultAction, title: presentationData.strings.Attachment_CancelSelectionAlertYes, action: { + completion() + })]) + self.present(controller, in: .window(.root)) + } else { + completion() + } } public func shouldDismissImmediately() -> Bool { - return true + guard let componentView = self.node.hostView.componentView as? ComposeTodoScreenComponent.View else { + return true + } + if let input = componentView.validatedInput(), !input.text.isEmpty || !input.items.isEmpty { + return false + } else { + return true + } } } diff --git a/submodules/TelegramUI/Components/ListComposePollOptionComponent/Sources/ListComposePollOptionComponent.swift b/submodules/TelegramUI/Components/ListComposePollOptionComponent/Sources/ListComposePollOptionComponent.swift index f58ef64eeb..d30878f224 100644 --- a/submodules/TelegramUI/Components/ListComposePollOptionComponent/Sources/ListComposePollOptionComponent.swift +++ b/submodules/TelegramUI/Components/ListComposePollOptionComponent/Sources/ListComposePollOptionComponent.swift @@ -802,8 +802,13 @@ public final class ListComposePollOptionComponent: Component { } if let deleteAction = component.deleteAction { - if self.deleteRevealView == nil { - let deleteRevealView = DeleteRevealView(title: component.strings.Common_Delete, color: component.theme.list.itemDisclosureActions.destructive.fillColor) + var deleteRevealViewTransition = transition + let deleteRevealView: DeleteRevealView + if let current = self.deleteRevealView { + deleteRevealView = current + } else { + deleteRevealViewTransition = .immediate + deleteRevealView = DeleteRevealView(title: component.strings.Common_Delete, color: component.theme.list.itemDisclosureActions.destructive.fillColor) deleteRevealView.tapped = { [weak self] action in guard let self else { return @@ -818,14 +823,17 @@ public final class ListComposePollOptionComponent: Component { } self.deleteRevealView = deleteRevealView self.addSubview(deleteRevealView) + + if self.recognizer == nil { + let recognizer = RevealOptionsGestureRecognizer(target: self, action: #selector(self.handlePan(_:))) + recognizer.delegate = self + self.addGestureRecognizer(recognizer) + self.recognizer = recognizer + } } - if self.recognizer == nil { - let recognizer = RevealOptionsGestureRecognizer(target: self, action: #selector(self.handlePan(_:))) - recognizer.delegate = self - self.addGestureRecognizer(recognizer) - self.recognizer = recognizer - } + let _ = deleteRevealView.updateLayout(availableSize: size, revealOffset: self.revealOffset, transition: deleteRevealViewTransition) + deleteRevealView.frame = CGRect(origin: .zero, size: size) } else { if let deleteRevealView = self.deleteRevealView { self.deleteRevealView = nil @@ -841,11 +849,6 @@ public final class ListComposePollOptionComponent: Component { self.revealOffset = 0.0 } - if let deleteRevealView = self.deleteRevealView { - let _ = deleteRevealView.updateLayout(availableSize: size, revealOffset: self.revealOffset, transition: transition) - deleteRevealView.frame = CGRect(origin: .zero, size: size) - } - self.separatorInset = leftInset return size diff --git a/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift b/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift index 01e9437a83..fe3287bfe5 100644 --- a/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift +++ b/submodules/TelegramUI/Components/Stars/StarsImageComponent/Sources/StarsImageComponent.swift @@ -851,10 +851,26 @@ public final class StarsImageComponent: Component { if let current = self.animationNode { animationNode = current } else { - let stickerName: String = count == 1000 ? "GiftDiamond" : "Gift\(count)" + let animationName: String + switch count { + case 1000: + animationName = "GiftDiamond1" + case 2000: + animationName = "GiftDiamond2" + case 3000: + animationName = "GiftDiamond3" + case 12: + animationName = "Gift12" + case 6: + animationName = "Gift6" + case 3: + animationName = "Gift3" + default: + animationName = "Gift3" + } animationNode = DefaultAnimatedStickerNodeImpl() animationNode.autoplay = true - animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: stickerName), width: 384, height: 384, playbackMode: .still(.end), mode: .direct(cachePathPrefix: nil)) + animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: animationName), width: 384, height: 384, playbackMode: .still(.end), mode: .direct(cachePathPrefix: nil)) animationNode.visibility = true containerNode.view.addSubview(animationNode.view) self.animationNode = animationNode diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenTodoContextMenu.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenTodoContextMenu.swift index 4e7950a5f3..e82d49d104 100644 --- a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenTodoContextMenu.swift +++ b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenTodoContextMenu.swift @@ -222,14 +222,12 @@ extension ChatControllerImpl { self.canReadHistory.set(false) - //TODO:localize var sources: [ContextController.Source] = [] sources.append( ContextController.Source( id: AnyHashable(OptionsId.item), title: self.presentationData.strings.Chat_Todo_ContextMenu_SectionTask, footer: self.presentationData.strings.Chat_Todo_ContextMenu_SectionsInfo, - //source: .extracted(ChatMessageLinkContextExtractedContentSource(chatNode: self.chatDisplayNode, contentNode: contentNode)), source: .extracted(ChatTodoItemContextExtractedContentSource(chatNode: self.chatDisplayNode, contentNode: contentNode)), items: .single(ContextController.Items(content: .list(items))) ) diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 4dd22f4bf6..f66d3be0d0 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -978,6 +978,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } else if let incompletedTaskId = incompleted.first { todoTaskId = incompletedTaskId } + } else if case let .todoAppendTasks(tasks) = action.action { + if let task = tasks.first { + todoTaskId = task.id + } } self.navigateToMessage(from: message.id, to: .id(attribute.messageId, NavigateToMessageParams(timestamp: nil, quote: attribute.isQuote ? attribute.quote.flatMap { quote in NavigateToMessageParams.Quote(string: quote.text, offset: quote.offset) } : nil, todoTaskId: todoTaskId))) break diff --git a/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift b/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift index 1a108becc2..26c463dc18 100644 --- a/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift +++ b/submodules/TelegramUI/Sources/ChatControllerOpenAttachmentMenu.swift @@ -2132,7 +2132,19 @@ extension ChatControllerImpl { guard let self else { return } - if canEdit { + func areItemsOnlyAppended(existing: [TelegramMediaTodo.Item], updated: [TelegramMediaTodo.Item]) -> Bool { + guard updated.count >= existing.count else { + return false + } + for (index, existingItem) in existing.enumerated() { + if index >= updated.count || updated[index] != existingItem { + return false + } + } + return true + } + + if canEdit && !areItemsOnlyAppended(existing: existingTodo.items, updated: todo.items) { let _ = self.context.engine.messages.requestEditMessage( messageId: messageId, text: "", diff --git a/submodules/TelegramUI/Sources/ChatMessageContextControllerContentSource.swift b/submodules/TelegramUI/Sources/ChatMessageContextControllerContentSource.swift index 8de16d6c54..367095962b 100644 --- a/submodules/TelegramUI/Sources/ChatMessageContextControllerContentSource.swift +++ b/submodules/TelegramUI/Sources/ChatMessageContextControllerContentSource.swift @@ -90,9 +90,11 @@ final class ChatMessageContextExtractedContentSource: ContextExtractedContentSou if item.content.contains(where: { $0.0.stableId == self.message.stableId }), let contentNode = itemNode.getMessageContextSourceNode(stableId: self.selectAll ? nil : self.message.stableId) { result = ContextControllerTakeViewInfo(containingItem: .node(contentNode), contentAreaInScreenSpace: chatNode.convert(chatNode.frameForVisibleArea(), to: nil)) - if self.snapshot, let snapshotView = contentNode.contentNode.view.snapshotContentTree(unhide: false, keepPortals: true, keepTransform: true) { - contentNode.view.superview?.addSubview(snapshotView) - self.snapshotView = snapshotView + Queue.mainQueue().justDispatch { + if self.snapshot, let snapshotView = contentNode.contentNode.view.snapshotContentTree(unhide: false, keepPortals: true, keepTransform: true) { + contentNode.view.superview?.addSubview(snapshotView) + self.snapshotView = snapshotView + } } } } diff --git a/submodules/TelegramUI/Sources/OpenChatMessage.swift b/submodules/TelegramUI/Sources/OpenChatMessage.swift index 60683621d9..818a7bf450 100644 --- a/submodules/TelegramUI/Sources/OpenChatMessage.swift +++ b/submodules/TelegramUI/Sources/OpenChatMessage.swift @@ -328,11 +328,6 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool { params.blockInteraction.set(.single(true)) - var presentInCurrent = false - if let channel = params.message.peers[params.message.id.peerId] as? TelegramChannel, case .broadcast = channel.info { - presentInCurrent = true - } - let _ = (gallery |> deliverOnMainQueue).startStandalone(next: { gallery in params.blockInteraction.set(.single(false)) @@ -340,13 +335,16 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool { gallery.centralItemUpdated = { messageId in params.centralItemUpdated?(messageId) } - params.present(gallery, GalleryControllerPresentationArguments(transitionArguments: { messageId, media in + + let arguments = GalleryControllerPresentationArguments(transitionArguments: { messageId, media in let selectedTransitionNode = params.transitionNode(messageId, media, false) if let selectedTransitionNode = selectedTransitionNode { return GalleryTransitionArguments(transitionNode: selectedTransitionNode, addToTransitionSurface: params.addToTransitionSurface) } return nil - }), presentInCurrent ? .current : .window(.root)) + }) + + params.present(gallery, arguments, .window(.root)) }) return true case let .secretGallery(gallery):