mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
9a791da77b
commit
27c5ca7474
@ -764,6 +764,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in
|
||||
}, setupEditMessage: { _, _ in
|
||||
}, beginMessageSelection: { _, _ in
|
||||
}, cancelMessageSelection: { _ in
|
||||
}, deleteSelectedMessages: {
|
||||
}, reportSelectedMessages: {
|
||||
}, reportMessages: { _, _ in
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ public final class ChatRecentActionsController: TelegramBaseController {
|
||||
self.panelInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in
|
||||
}, setupEditMessage: { _, _ in
|
||||
}, beginMessageSelection: { _, _ in
|
||||
}, cancelMessageSelection: { _ in
|
||||
}, deleteSelectedMessages: {
|
||||
}, reportSelectedMessages: {
|
||||
}, reportMessages: { _, _ in
|
||||
|
@ -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
|
||||
|
@ -337,6 +337,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
||||
self.interfaceInteraction = ChatPanelInterfaceInteraction(setupReplyMessage: { _, _ in
|
||||
}, setupEditMessage: { _, _ in
|
||||
}, beginMessageSelection: { _, _ in
|
||||
}, cancelMessageSelection: { _ in
|
||||
}, deleteSelectedMessages: {
|
||||
}, reportSelectedMessages: {
|
||||
}, reportMessages: { _, _ in
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user