From fc71d6c458e8584a6f3a072988e7449cfea29895 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 20 Nov 2019 07:29:01 +0400 Subject: [PATCH] Add sending options tip --- .../TelegramNotices/Sources/Notices.swift | 27 ++++++ .../TelegramUI/ChatController.swift | 96 +++++++++++++------ .../ChatScheduleTimeController.swift | 20 +--- 3 files changed, 95 insertions(+), 48 deletions(-) diff --git a/submodules/TelegramNotices/Sources/Notices.swift b/submodules/TelegramNotices/Sources/Notices.swift index 62b7251ee8..7f281eb5c5 100644 --- a/submodules/TelegramNotices/Sources/Notices.swift +++ b/submodules/TelegramNotices/Sources/Notices.swift @@ -132,6 +132,7 @@ private enum ApplicationSpecificGlobalNotice: Int32 { case callsTabTip = 12 case cellularDataPermissionWarning = 13 case chatMessageSearchResultsTip = 14 + case chatMessageOptionsTip = 15 var key: ValueBoxKey { let v = ValueBoxKey(length: 4) @@ -233,6 +234,10 @@ private struct ApplicationSpecificNoticeKeys { static func chatMessageSearchResultsTip() -> NoticeEntryKey { return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.chatMessageSearchResultsTip.key) } + + static func chatMessageOptionsTip() -> NoticeEntryKey { + return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.chatMessageOptionsTip.key) + } } public struct ApplicationSpecificNotice { @@ -546,6 +551,28 @@ public struct ApplicationSpecificNotice { } } + public static func getChatMessageOptionsTip(accountManager: AccountManager) -> Signal { + return accountManager.transaction { transaction -> Int32 in + if let value = transaction.getNotice(ApplicationSpecificNoticeKeys.chatMessageOptionsTip()) as? ApplicationSpecificCounterNotice { + return value.value + } else { + return 0 + } + } + } + + public static func incrementChatMessageOptionsTip(accountManager: AccountManager, count: Int32 = 1) -> Signal { + return accountManager.transaction { transaction -> Void in + var currentValue: Int32 = 0 + if let value = transaction.getNotice(ApplicationSpecificNoticeKeys.chatMessageOptionsTip()) as? ApplicationSpecificCounterNotice { + currentValue = value.value + } + currentValue += count + + transaction.setNotice(ApplicationSpecificNoticeKeys.chatMessageOptionsTip(), ApplicationSpecificCounterNotice(value: currentValue)) + } + } + public static func reset(accountManager: AccountManager) -> Signal { return accountManager.transaction { transaction -> Void in } diff --git a/submodules/TelegramUI/TelegramUI/ChatController.swift b/submodules/TelegramUI/TelegramUI/ChatController.swift index 6737c25c21..e7a9b9d7dc 100644 --- a/submodules/TelegramUI/TelegramUI/ChatController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatController.swift @@ -270,7 +270,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G private var raiseToListen: RaiseToListenManager? private var voicePlaylistDidEndTimestamp: Double = 0.0 - + + private weak var sendingOptionsTooltipController: TooltipController? private weak var searchResultsTooltipController: TooltipController? private weak var messageTooltipController: TooltipController? private weak var videoUnmuteTooltipController: TooltipController? @@ -4104,15 +4105,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.window?.presentInGlobalOverlay(slowmodeTooltipController) }, displaySendMessageOptions: { [weak self] node, gesture in if let strongSelf = self, let textInputNode = strongSelf.chatDisplayNode.textInputNode(), let layout = strongSelf.validLayout { + let previousSupportedOrientations = strongSelf.supportedOrientations if layout.size.width > layout.size.height { strongSelf.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .landscape) } else { strongSelf.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait) } + let _ = ApplicationSpecificNotice.incrementChatMessageOptionsTip(accountManager: strongSelf.context.sharedContext.accountManager, count: 4).start() + let controller = ChatSendMessageActionSheetController(context: strongSelf.context, controllerInteraction: strongSelf.controllerInteraction, interfaceState: strongSelf.presentationInterfaceState, gesture: gesture, sendButtonFrame: node.view.convert(node.bounds, to: nil), textInputNode: textInputNode, completion: { [weak self] in if let strongSelf = self { - strongSelf.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .all) + strongSelf.supportedOrientations = previousSupportedOrientations } }) strongSelf.sendMessageActionsController = controller @@ -4478,36 +4482,49 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let _ = checkPeerChatServiceActions(postbox: self.context.account.postbox, peerId: peerId).start() } - if self.chatDisplayNode.frameForInputActionButton() != nil, self.presentationInterfaceState.interfaceState.mediaRecordingMode == .audio { - var canSendMedia = false - if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel { - if channel.hasBannedPermission(.banSendMedia) == nil { + if self.chatDisplayNode.frameForInputActionButton() != nil { + let inputText = self.presentationInterfaceState.interfaceState.effectiveInputState.inputText.string + if !inputText.isEmpty { + if inputText.count > 4 { + let _ = (ApplicationSpecificNotice.getChatMessageOptionsTip(accountManager: context.sharedContext.accountManager) + |> deliverOnMainQueue).start(next: { [weak self] counter in + if let strongSelf = self, counter < 3 { + let _ = ApplicationSpecificNotice.incrementChatMessageOptionsTip(accountManager: strongSelf.context.sharedContext.accountManager).start() + strongSelf.displaySendingOptionsTooltip() + } + }) + } + } else if self.presentationInterfaceState.interfaceState.mediaRecordingMode == .audio { + var canSendMedia = false + if let channel = self.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel { + if channel.hasBannedPermission(.banSendMedia) == nil { + canSendMedia = true + } + } else if let group = self.presentationInterfaceState.renderedPeer?.peer as? TelegramGroup { + if !group.hasBannedPermission(.banSendMedia) { + canSendMedia = true + } + } else { canSendMedia = true } - } else if let group = self.presentationInterfaceState.renderedPeer?.peer as? TelegramGroup { - if !group.hasBannedPermission(.banSendMedia) { - canSendMedia = true + if canSendMedia { + let _ = (ApplicationSpecificNotice.getChatMediaMediaRecordingTips(accountManager: self.context.sharedContext.accountManager) + |> deliverOnMainQueue).start(next: { [weak self] counter in + guard let strongSelf = self else { + return + } + var displayTip = false + if counter == 0 { + displayTip = true + } else if counter < 3 && arc4random_uniform(4) == 1 { + displayTip = true + } + if displayTip { + let _ = ApplicationSpecificNotice.incrementChatMediaMediaRecordingTips(accountManager: strongSelf.context.sharedContext.accountManager).start() + strongSelf.displayMediaRecordingTooltip() + } + }) } - } else { - canSendMedia = true - } - if canSendMedia { - let _ = (ApplicationSpecificNotice.getChatMediaMediaRecordingTips(accountManager: self.context.sharedContext.accountManager) - |> deliverOnMainQueue).start(next: { [weak self] counter in - guard let strongSelf = self else { - return - } - var displayTip = false - if counter == 0 { - displayTip = true - } else if counter < 3 && arc4random_uniform(4) == 1 { - displayTip = true - } - if displayTip { - let _ = ApplicationSpecificNotice.incrementChatMediaMediaRecordingTips(accountManager: strongSelf.context.sharedContext.accountManager).start() - strongSelf.displayMediaRecordingTooltip() - } - }) } } } @@ -7871,7 +7888,28 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } + private func displaySendingOptionsTooltip() { + guard let rect = self.chatDisplayNode.frameForInputActionButton() else { + return + } + self.sendingOptionsTooltipController?.dismiss() + let tooltipController = TooltipController(content: .text(self.presentationData.strings.Conversation_SendingOptionsTooltip), timeout: 3.0, dismissByTapOutside: true, dismissImmediatelyOnLayoutUpdate: true) + self.sendingOptionsTooltipController = tooltipController + tooltipController.dismissed = { [weak self, weak tooltipController] _ in + if let strongSelf = self, let tooltipController = tooltipController, strongSelf.sendingOptionsTooltipController === tooltipController { + strongSelf.sendingOptionsTooltipController = nil + } + } + self.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: { [weak self] in + if let strongSelf = self { + return (strongSelf.chatDisplayNode, rect) + } + return nil + })) + } + private func dismissAllTooltips() { + self.sendingOptionsTooltipController?.dismiss() self.searchResultsTooltipController?.dismiss() self.messageTooltipController?.dismiss() self.videoUnmuteTooltipController?.dismiss() diff --git a/submodules/TelegramUI/TelegramUI/ChatScheduleTimeController.swift b/submodules/TelegramUI/TelegramUI/ChatScheduleTimeController.swift index 476b4f34e5..641e481c43 100644 --- a/submodules/TelegramUI/TelegramUI/ChatScheduleTimeController.swift +++ b/submodules/TelegramUI/TelegramUI/ChatScheduleTimeController.swift @@ -23,7 +23,6 @@ final class ChatScheduleTimeController: ViewController { private let context: AccountContext private let peerId: PeerId private let mode: ChatScheduleTimeControllerMode - private let editingTime: Bool private let currentTime: Int32? private let minimalTime: Int32? private let dismissByTapOutside: Bool @@ -35,7 +34,6 @@ final class ChatScheduleTimeController: ViewController { self.context = context self.peerId = peerId self.mode = mode - self.editingTime = currentTime != nil self.currentTime = currentTime != scheduleWhenOnlineTimestamp ? currentTime : nil self.minimalTime = minimalTime self.dismissByTapOutside = dismissByTapOutside @@ -71,23 +69,7 @@ final class ChatScheduleTimeController: ViewController { guard let strongSelf = self else { return } - if time == scheduleWhenOnlineTimestamp { - let _ = (strongSelf.context.account.viewTracker.peerView(strongSelf.peerId) - |> take(1) - |> deliverOnMainQueue).start(next: { [weak self] peerView in - guard let strongSelf = self, let peer = peerViewMainPeer(peerView) else { - return - } - let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) - if !strongSelf.editingTime, let presence = peerView.peerPresences[peer.id] as? TelegramUserPresence, case let .present(statusTimestamp) = presence.status, statusTimestamp >= timestamp { - strongSelf.completion(0) - } else { - strongSelf.completion(time) - } - }) - } else { - strongSelf.completion(time + 5) - } + strongSelf.completion(time == scheduleWhenOnlineTimestamp ? time : time + 5) strongSelf.dismiss() } self.controllerNode.dismiss = { [weak self] in