Various improvements

This commit is contained in:
Isaac 2024-01-29 22:23:50 +01:00
parent 9a791da77b
commit 27c5ca7474
15 changed files with 99 additions and 34 deletions

View File

@ -764,6 +764,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
self.interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in
}, setupEditMessage: { _, _ in
}, beginMessageSelection: { _, _ in
}, cancelMessageSelection: { _ in
}, deleteSelectedMessages: {
}, reportSelectedMessages: {
}, reportMessages: { _, _ in

View File

@ -72,6 +72,7 @@ public final class ChatPanelInterfaceInteraction {
public let setupReplyMessage: (MessageId?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void
public let setupEditMessage: (MessageId?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void
public let beginMessageSelection: ([MessageId], @escaping (ContainedViewLayoutTransition) -> Void) -> Void
public let cancelMessageSelection: (ContainedViewLayoutTransition) -> Void
public let deleteSelectedMessages: () -> Void
public let reportSelectedMessages: () -> Void
public let reportMessages: ([Message], ContextControllerProtocol?) -> Void
@ -182,6 +183,7 @@ public final class ChatPanelInterfaceInteraction {
setupReplyMessage: @escaping (MessageId?, @escaping (ContainedViewLayoutTransition, @escaping () -> Void) -> Void) -> Void,
setupEditMessage: @escaping (MessageId?, @escaping (ContainedViewLayoutTransition) -> Void) -> Void,
beginMessageSelection: @escaping ([MessageId], @escaping (ContainedViewLayoutTransition) -> Void) -> Void,
cancelMessageSelection: @escaping (ContainedViewLayoutTransition) -> Void,
deleteSelectedMessages: @escaping () -> Void,
reportSelectedMessages: @escaping () -> Void,
reportMessages: @escaping ([Message], ContextControllerProtocol?) -> Void,
@ -291,6 +293,7 @@ public final class ChatPanelInterfaceInteraction {
self.setupReplyMessage = setupReplyMessage
self.setupEditMessage = setupEditMessage
self.beginMessageSelection = beginMessageSelection
self.cancelMessageSelection = cancelMessageSelection
self.deleteSelectedMessages = deleteSelectedMessages
self.reportSelectedMessages = reportSelectedMessages
self.reportMessages = reportMessages
@ -407,6 +410,7 @@ public final class ChatPanelInterfaceInteraction {
self.init(setupReplyMessage: { _, _ in
}, setupEditMessage: { _, _ in
}, beginMessageSelection: { _, _ in
}, cancelMessageSelection: { _ in
}, deleteSelectedMessages: {
}, reportSelectedMessages: {
}, reportMessages: { _, _ in

View File

@ -377,10 +377,7 @@ final class ContextSourceContainer: ASDisplayNode {
super.init()
#if DEBUG
#else
self.addSubnode(self.backgroundNode)
#endif
for i in 0 ..< configuration.sources.count {
let source = configuration.sources[i]

View File

@ -65,6 +65,8 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
public private(set) var accessoryPanelContainerHeight: CGFloat = 0.0
public let mediaAccessoryPanelVisibility: MediaAccessoryPanelVisibility
public var tempHideAccessoryPanels: Bool = false
public let locationBroadcastPanelSource: LocationBroadcastPanelSource
public let groupCallPanelSource: GroupCallPanelSource
@ -408,13 +410,17 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
let navigationHeight = super.navigationLayout(layout: layout).navigationFrame.height - self.additionalNavigationBarHeight
let mediaAccessoryPanelHidden: Bool
switch self.mediaAccessoryPanelVisibility {
case .always:
mediaAccessoryPanelHidden = false
case .none:
if self.tempHideAccessoryPanels {
mediaAccessoryPanelHidden = true
case let .specific(size):
mediaAccessoryPanelHidden = size != layout.metrics.widthClass
} else {
switch self.mediaAccessoryPanelVisibility {
case .always:
mediaAccessoryPanelHidden = false
case .none:
mediaAccessoryPanelHidden = true
case let .specific(size):
mediaAccessoryPanelHidden = size != layout.metrics.widthClass
}
}
var additionalHeight: CGFloat = 0.0

View File

@ -18,7 +18,7 @@ public enum UpdateMessageReaction {
}
}
public func updateMessageReactionsInteractively(account: Account, messageId: MessageId, reactions: [UpdateMessageReaction], isLarge: Bool, storeAsRecentlyUsed: Bool) -> Signal<Never, NoError> {
public func updateMessageReactionsInteractively(account: Account, messageId: MessageId, reactions: [UpdateMessageReaction], isLarge: Bool, storeAsRecentlyUsed: Bool, add: Bool = false) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> Void in
var sendAsPeerId = account.peerId
if let cachedData = transaction.getPeerCachedData(peerId: messageId.peerId) {
@ -40,6 +40,25 @@ public func updateMessageReactionsInteractively(account: Account, messageId: Mes
}
var mappedReactions: [PendingReactionsMessageAttribute.PendingReaction] = []
var reactions: [UpdateMessageReaction] = reactions
if add {
if let message = transaction.getMessage(messageId), let effectiveReactions = message.effectiveReactions(isTags: message.areReactionsTags(accountPeerId: account.peerId)) {
for reaction in effectiveReactions {
if !reactions.contains(where: { $0.reaction == reaction.value }) {
let mappedValue: UpdateMessageReaction
switch reaction.value {
case let .builtin(value):
mappedValue = .builtin(value)
case let .custom(fileId):
mappedValue = .custom(fileId: fileId, file: nil)
}
reactions.append(mappedValue)
}
}
}
}
for reaction in reactions {
switch reaction {
case let .custom(fileId, file):

View File

@ -307,7 +307,22 @@ public extension TelegramEngine {
messageId: id,
reactions: reactions,
isLarge: false,
storeAsRecentlyUsed: false
storeAsRecentlyUsed: false,
add: false
).start()
}
public func addMessageReactions(
id: EngineMessage.Id,
reactions: [UpdateMessageReaction]
) {
let _ = updateMessageReactionsInteractively(
account: self.account,
messageId: id,
reactions: reactions,
isLarge: false,
storeAsRecentlyUsed: false,
add: true
).start()
}

View File

@ -310,24 +310,29 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
return
}
var reactions = actions.editTags
if reactions.contains(updateReaction.reaction) {
reactions.remove(updateReaction.reaction)
} else {
reactions.insert(updateReaction.reaction)
}
let mappedUpdatedReactions = reactions.map { reaction -> UpdateMessageReaction in
switch reaction {
case let .builtin(value):
return .builtin(value)
case let .custom(fileId):
return .custom(fileId: fileId, file: nil)
}
}
self.interfaceInteraction?.cancelMessageSelection(.animated(duration: 0.4, curve: .spring))
if let selectionState = presentationInterfaceState.interfaceState.selectionState {
for id in selectionState.selectedIds {
context.engine.messages.setMessageReactions(id: id, reactions: mappedUpdatedReactions)
if actions.editTags.contains(updateReaction.reaction) {
var reactions = actions.editTags
reactions.remove(updateReaction.reaction)
let mappedUpdatedReactions = reactions.map { reaction -> UpdateMessageReaction in
switch reaction {
case let .builtin(value):
return .builtin(value)
case let .custom(fileId):
return .custom(fileId: fileId, file: nil)
}
}
if let selectionState = presentationInterfaceState.interfaceState.selectionState {
for id in selectionState.selectedIds {
context.engine.messages.setMessageReactions(id: id, reactions: mappedUpdatedReactions)
}
}
} else {
if let selectionState = presentationInterfaceState.interfaceState.selectionState {
for id in selectionState.selectedIds {
context.engine.messages.addMessageReactions(id: id, reactions: [updateReaction])
}
}
}

View File

@ -63,6 +63,7 @@ public final class ChatRecentActionsController: TelegramBaseController {
self.panelInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in
}, setupEditMessage: { _, _ in
}, beginMessageSelection: { _, _ in
}, cancelMessageSelection: { _ in
}, deleteSelectedMessages: {
}, reportSelectedMessages: {
}, reportMessages: { _, _ in

View File

@ -305,6 +305,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
let interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in
}, setupEditMessage: { _, _ in
}, beginMessageSelection: { _, _ in
}, cancelMessageSelection: { _ in
}, deleteSelectedMessages: {
deleteMessages()
}, reportSelectedMessages: {
@ -11301,7 +11302,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
//TODO:localize
items.append(.action(ContextMenuActionItem(text: "View as Chats", icon: { theme in
if !isViewingAsTopics {
return nil
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: .clear)
}
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
}, iconPosition: .left, action: { [weak sourceController] _, a in
@ -11319,7 +11320,7 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen, KeyShortc
})))
items.append(.action(ContextMenuActionItem(text: strings.Chat_ContextViewAsMessages, icon: { theme in
if isViewingAsTopics {
return nil
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: .clear)
}
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
}, iconPosition: .left, action: { [weak sourceController] _, a in

View File

@ -337,6 +337,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
self.interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in
}, setupEditMessage: { _, _ in
}, beginMessageSelection: { _, _ in
}, cancelMessageSelection: { _ in
}, deleteSelectedMessages: {
}, reportSelectedMessages: {
}, reportMessages: { _, _ in

View File

@ -414,6 +414,8 @@ func updateChatPresentationInterfaceStateImpl(
selfController.chatDisplayNode.collapseInput()
}
selfController.tempHideAccessoryPanels = selfController.presentationInterfaceState.search != nil
if selfController.isNodeLoaded {
selfController.chatDisplayNode.updateChatPresentationInterfaceState(updatedChatPresentationInterfaceState, transition: transition, interactive: interactive, completion: completion)
} else {

View File

@ -8639,6 +8639,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} else {
completion(.immediate)
}
}, cancelMessageSelection: { [weak self] transition in
guard let self else {
return
}
self.updateChatPresentationInterfaceState(transition: transition, interactive: true, { $0.updatedInterfaceState { $0.withoutSelectionState() } })
}, deleteSelectedMessages: { [weak self] in
if let strongSelf = self {
if let messageIds = strongSelf.presentationInterfaceState.interfaceState.selectionState?.selectedIds, !messageIds.isEmpty {

View File

@ -1656,7 +1656,12 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
isSending = true
title = chatPresentationInterfaceState.strings.Conversation_ContextMenuCancelSending
} else {
title = chatPresentationInterfaceState.strings.Conversation_ContextMenuDelete
if case .peer(context.account.peerId) = chatPresentationInterfaceState.chatLocation, message.effectivelyIncoming(context.account.peerId) {
//TODO:localize
title = "Remove"
} else {
title = chatPresentationInterfaceState.strings.Conversation_ContextMenuDelete
}
}
if let autoremoveDeadline = autoremoveDeadline, !isEditing, !isSending {

View File

@ -184,6 +184,9 @@ func rightNavigationButtonForChatInterfaceState(context: AccountContext, present
}
func secondaryRightNavigationButtonForChatInterfaceState(context: AccountContext, presentationInterfaceState: ChatPresentationInterfaceState, strings: PresentationStrings, currentButton: ChatNavigationButton?, target: Any?, selector: Selector?, chatInfoNavigationButton: ChatNavigationButton?, moreInfoNavigationButton: ChatNavigationButton?) -> ChatNavigationButton? {
if presentationInterfaceState.interfaceState.selectionState != nil {
return nil
}
if case .peer(context.account.peerId) = presentationInterfaceState.chatLocation {
return moreInfoNavigationButton
}

View File

@ -262,7 +262,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
}
}
var nextLeftX: CGFloat = 11.0
var nextLeftX: CGFloat = 12.0
let calendarButtonSize = self.calendarButton.update(
transition: .immediate,
@ -372,7 +372,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
environment: {},
containerSize: size
)
let resultsTextFrame = CGRect(origin: CGPoint(x: nextLeftX, y: floor((size.height - resultsTextSize.height) * 0.5)), size: resultsTextSize)
let resultsTextFrame = CGRect(origin: CGPoint(x: nextLeftX - 3.0, y: floor((size.height - resultsTextSize.height) * 0.5)), size: resultsTextSize)
if let resultsTextView = resultsText.view {
if resultsTextView.superview == nil {
resultsTextView.alpha = 0.0
@ -381,7 +381,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
resultsTextTransition.setFrame(view: resultsTextView, frame: resultsTextFrame)
transition.setAlpha(view: resultsTextView, alpha: 1.0)
}
nextLeftX += resultsTextSize.width
nextLeftX += -3.0 + resultsTextSize.width
} else {
if let resultsText = self.resultsText {
self.resultsText = nil