Various fixes

This commit is contained in:
Ilya Laktyushin 2025-07-09 00:43:23 +02:00
parent 3e31d12db6
commit 6d2757eb91
10 changed files with 96 additions and 35 deletions

View File

@ -14425,6 +14425,12 @@ Sorry for the inconvenience.";
"Notification.TodoTasks_1" = "%@ task";
"Notification.TodoTasks_any" = "%@ tasks";
"Notification.TodoTasksDone_1" = "%@ task as done";
"Notification.TodoTasksDone_any" = "%@ tasks as done";
"Notification.TodoTasksUndone_1" = "%@ task as not done";
"Notification.TodoTasksUndone_any" = "%@ tasks as not done";
"Notification.TodoCompleted" = "%1$@ marked \"%2$@\" as done.";
"Notification.TodoIncompleted" = "%1$@ marked \"%2$@\" as undone.";
"Notification.TodoMultipleCompleted" = "%1$@ marked %2$@ as done.";
@ -14434,6 +14440,9 @@ Sorry for the inconvenience.";
"Notification.TodoMultipleCompletedYou" = "You marked %1$@ as done.";
"Notification.TodoMultipleIncompletedYou" = "You marked %1$@ as not done.";
"Notification.TodoMultiple" = "%1$@ marked %2$@.";
"Notification.TodoMultipleYou" = "You marked %1$@.";
"Notification.TodoAddedTasks_1" = "%@ task";
"Notification.TodoAddedTasks_any" = "%@ tasks";

View File

@ -92,6 +92,15 @@ private extension ContextControllerTakeViewInfo.ContainingItem {
}
}
var onDismiss: (() -> Void)? {
switch self {
case let .node(containingNode):
return containingNode.onDismiss
case let .view(containingView):
return containingView.onDismiss
}
}
var layoutUpdated: ((CGSize, ListViewItemUpdateAnimation) -> Void)? {
get {
switch self {
@ -1596,6 +1605,7 @@ final class ContextControllerExtractedPresentationNode: ASDisplayNode, ContextCo
contentNode.containingItem.isExtractedToContextPreview = false
contentNode.containingItem.isExtractedToContextPreviewUpdated?(false)
contentNode.containingItem.onDismiss?()
restoreOverlayViews.forEach({ $0() })
completion()

View File

@ -20,6 +20,7 @@ public final class ContextExtractedContentContainingNode: ASDisplayNode {
public var layoutUpdated: ((CGSize, ListViewItemUpdateAnimation) -> Void)?
public var updateDistractionFreeMode: ((Bool) -> Void)?
public var requestDismiss: (() -> Void)?
public var onDismiss: (() -> Void)?
public override init() {
self.contentNode = ContextExtractedContentNode()
@ -50,6 +51,7 @@ public final class ContextExtractedContentContainingView: UIView {
public var layoutUpdated: ((CGSize, ListViewItemUpdateAnimation) -> Void)?
public var updateDistractionFreeMode: ((Bool) -> Void)?
public var requestDismiss: (() -> Void)?
public var onDismiss: (() -> Void)?
public override init(frame: CGRect) {
self.contentView = ContextExtractedContentView()

View File

@ -509,9 +509,29 @@ private func makeSubtreeSnapshot(layer: CALayer, keepPortals: Bool = false, keep
return nil
}
}
var unhide = false
var markToHide = false
if keepPortals {
if let view = (layer.delegate as? UIView) {
if view.tag == 0x1bad, view.alpha > 0.0 {
return nil
} else if view.tag == 0x2bad {
markToHide = true
} else if view.tag == 0x3bad {
unhide = true
}
}
}
let view = UIView()
if markToHide {
view.tag = 0x2bad
}
view.layer.isHidden = layer.isHidden
view.layer.opacity = layer.opacity
if unhide {
view.layer.opacity = 1.0
} else {
view.layer.opacity = layer.opacity
}
view.layer.contents = layer.contents
view.layer.contentsRect = layer.contentsRect
view.layer.contentsScale = layer.contentsScale
@ -541,10 +561,14 @@ private func makeSubtreeSnapshot(layer: CALayer, keepPortals: Bool = false, keep
}
view.layer.cornerRadius = layer.cornerRadius
view.layer.backgroundColor = layer.backgroundColor
if let sublayers = layer.sublayers {
for sublayer in sublayers {
let subtree = makeSubtreeSnapshot(layer: sublayer, keepPortals: keepPortals, keepTransform: keepTransform)
if let subtree = subtree {
if subtree.tag == 0x2bad {
return nil
}
if keepTransform {
subtree.layer.transform = sublayer.transform
}
@ -568,6 +592,7 @@ private func makeSubtreeSnapshot(layer: CALayer, keepPortals: Bool = false, keep
}
}
}
return view
}

View File

@ -1349,11 +1349,11 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
if message.author?.id == accountPeerId {
let resultString: PresentationStrings.FormattedString
if completed.count > 1 || (completed.count == 1 && taskTitle == nil) {
resultString = strings.Notification_TodoMultipleCompletedYou(strings.Notification_TodoTasks(Int32(completed.count)))
resultString = strings.Notification_TodoMultipleYou(strings.Notification_TodoTasksDone(Int32(completed.count)))
} else if let _ = completed.first {
resultString = strings.Notification_TodoCompletedYou(taskTitle ?? "")
} else if incompleted.count > 1 || (incompleted.count == 1 && taskTitle == nil) {
resultString = strings.Notification_TodoMultipleIncompletedYou(strings.Notification_TodoTasks(Int32(incompleted.count)))
resultString = strings.Notification_TodoMultipleYou(strings.Notification_TodoTasksUndone(Int32(incompleted.count)))
} else if let _ = incompleted.first {
resultString = strings.Notification_TodoIncompletedYou(taskTitle ?? "")
} else {
@ -1368,11 +1368,11 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
let resultString: PresentationStrings.FormattedString
if completed.count > 1 || (completed.count == 1 && taskTitle == nil) {
resultString = strings.Notification_TodoMultipleCompleted(peerName, strings.Notification_TodoTasks(Int32(completed.count)))
resultString = strings.Notification_TodoMultiple(peerName, strings.Notification_TodoTasksDone(Int32(completed.count)))
} else if let _ = completed.first {
resultString = strings.Notification_TodoCompleted(peerName, taskTitle ?? "")
} else if incompleted.count > 1 || (incompleted.count == 1 && taskTitle == nil) {
resultString = strings.Notification_TodoMultipleIncompleted(peerName, strings.Notification_TodoTasks(Int32(incompleted.count)))
resultString = strings.Notification_TodoMultiple(peerName, strings.Notification_TodoTasksUndone(Int32(incompleted.count)))
} else if let _ = incompleted.first {
resultString = strings.Notification_TodoIncompleted(peerName, taskTitle ?? "")
} else {

View File

@ -448,7 +448,6 @@ private final class ChatMessageTodoItemNode: ASDisplayNode {
self.buttonNode = TodoTrackingButtonNode()
self.separatorNode = ASDisplayNode()
self.separatorNode.isLayerBacked = true
super.init()
@ -472,6 +471,8 @@ private final class ChatMessageTodoItemNode: ASDisplayNode {
self.buttonNode.highligthedChanged = { [weak self] highlighted in
if let strongSelf = self {
if highlighted {
strongSelf.containerNode.view.tag = 0x2bad
if let theme = strongSelf.presentationData?.theme.theme, theme.overallDarkAppearance, let contentNode = strongSelf.supernode as? ChatMessageTodoBubbleContentNode, let backdropNode = contentNode.bubbleBackgroundNode?.backdropNode {
strongSelf.highlightedBackgroundNode.layer.compositingFilter = "overlayBlendMode"
strongSelf.highlightedBackgroundNode.frame = strongSelf.view.convert(strongSelf.highlightedBackgroundNode.frame, to: backdropNode.view)
@ -496,6 +497,8 @@ private final class ChatMessageTodoItemNode: ASDisplayNode {
}
}
} else {
strongSelf.containerNode.view.tag = 0
strongSelf.highlightedBackgroundNode.alpha = 0.0
strongSelf.highlightedBackgroundNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, completion: { finished in
if finished && strongSelf.highlightedBackgroundNode.supernode != strongSelf {
@ -611,17 +614,6 @@ private final class ChatMessageTodoItemNode: ASDisplayNode {
if let backgroundNode = self.backgroundNode {
self.backgroundNode = nil
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()
self.extractedTitleNode = nil
self.extractedNameView?.removeFromSuperview()
self.extractedNameView = nil
backgroundNode?.removeFromSupernode()
})
}
@ -633,6 +625,31 @@ private final class ChatMessageTodoItemNode: ASDisplayNode {
}
}
}
self.contextSourceNode.isExtractedToContextPreviewUpdated = { [weak self] isExtracted in
guard let self else {
return
}
if !isExtracted {
self.extractedRadioView?.removeFromSuperview()
self.extractedRadioView = nil
self.extractedIconView?.removeFromSuperview()
self.extractedIconView = nil
self.extractedAvatarView?.removeFromSuperview()
self.extractedAvatarView = nil
self.extractedTitleNode?.textNode.removeFromSupernode()
self.extractedTitleNode = nil
self.extractedNameView?.removeFromSuperview()
self.extractedNameView = nil
}
}
}
override func didLoad() {
super.didLoad()
self.highlightedBackgroundNode.view.tag = 0x1bad
self.separatorNode.view.tag = 0x3bad
}
@objc private func buttonPressed() {

View File

@ -72,6 +72,8 @@ func textStringForForwardedMessage(_ message: Message, strings: PresentationStri
return ("", [], true)
case _ as TelegramMediaPoll:
return (strings.ForwardedPolls(1), [], true)
case let todo as TelegramMediaTodo:
return (todo.text, [], true)
case let dice as TelegramMediaDice:
return (dice.emoji, [], true)
case let invoice as TelegramMediaInvoice:

View File

@ -117,7 +117,7 @@ private func actionForAttribute(attribute: StarGift.UniqueGift.Attribute, presen
}
}
return ContextMenuActionItem(text: title, entities: entities, entityFiles: entityFiles, enableEntityAnimations: false, parseMarkdown: true, icon: { theme in
return ContextMenuActionItem(text: title, entities: entities, entityFiles: entityFiles, enableEntityAnimations: false, parseMarkdown: true, icon: { theme in
return isSelected ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
}, action: { _, f in
getController()?.dismiss(result: .dismissWithoutContent, completion: nil)
@ -363,8 +363,7 @@ private final class GiftAttributeListContextItemNode: ASDisplayNode, ContextMenu
self.actionNodes[itemId] = actionNode
self.scrollNode.addSubnode(actionNode)
}
case .attribute(let attribute):
case let .attribute(attribute):
if self.actionNodes[itemId] == nil {
let selectedAttributes = Set(self.item.selectedAttributes)
guard let action = actionForAttribute(
@ -398,7 +397,6 @@ private final class GiftAttributeListContextItemNode: ASDisplayNode, ContextMenu
self.actionNodes[itemId]?.setItem(item: action)
}
}
case .noResults:
if self.actionNodes[itemId] == nil {
let nopAction: ((ContextControllerProtocol?, @escaping (ContextMenuActionResult) -> Void) -> Void)? = nil

View File

@ -233,15 +233,21 @@ extension ChatControllerImpl {
)
)
let messageContentSource = ChatMessageContextExtractedContentSource(chatController: self, chatNode: self.chatDisplayNode, engine: self.context.engine, message: message, selectAll: false, snapshot: true)
sources.append(
ContextController.Source(
id: AnyHashable(OptionsId.message),
title: self.presentationData.strings.Chat_Todo_ContextMenu_SectionList,
source: .extracted(ChatMessageContextExtractedContentSource(chatController: self, chatNode: self.chatDisplayNode, engine: self.context.engine, message: message, selectAll: false, snapshot: true)),
source: .extracted(messageContentSource),
items: .single(actions)
)
)
contentNode.onDismiss = { [weak messageContentSource] in
messageContentSource?.snapshotView?.removeFromSuperview()
}
let contextController = ContextController(
presentationData: self.presentationData,
configuration: ContextController.Configuration(

View File

@ -72,7 +72,7 @@ final class ChatMessageContextExtractedContentSource: ContextExtractedContentSou
self.snapshot = snapshot
}
private var snapshotView: UIView?
private(set) var snapshotView: UIView?
func takeView() -> ContextControllerTakeViewInfo? {
guard let chatNode = self.chatNode else {
@ -89,12 +89,10 @@ 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))
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
}
if self.snapshot, let snapshotView = contentNode.contentNode.view.snapshotContentTree(unhide: false, keepPortals: true, keepTransform: true) {
contentNode.view.superview?.addSubview(snapshotView)
self.snapshotView = snapshotView
}
}
}
@ -119,12 +117,6 @@ final class ChatMessageContextExtractedContentSource: ContextExtractedContentSou
}
}
if let snapshotView = self.snapshotView {
Queue.mainQueue().after(0.4) {
snapshotView.removeFromSuperview()
}
}
return result
}
}