mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-01 07:57:01 +00:00
Various improvements
This commit is contained in:
parent
7b5883c115
commit
4e804bf9d9
@ -14338,3 +14338,6 @@ Sorry for the inconvenience.";
|
||||
|
||||
"Gift.Buy.ErrorTooEarly.Title" = "Try Later";
|
||||
"Gift.Buy.ErrorTooEarly.Text" = "You will be able to buy this gift on %@.";
|
||||
|
||||
"Chat.PauseVoiceMessageTooltip" = "Pause to trim or replay.";
|
||||
"Chat.PauseVideoMessageTooltip" = "Pause to trim or replay.";
|
||||
|
@ -1265,6 +1265,7 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate {
|
||||
}, openMessagePayment: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateRecordingTrimRange: { _, _, _, _ in
|
||||
}, dismissAllTooltips: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, updateChatLocationThread: { _, _ in
|
||||
}, toggleChatSidebarMode: {
|
||||
|
@ -109,7 +109,7 @@ final class CameraOutput: NSObject {
|
||||
private var videoConnection: AVCaptureConnection?
|
||||
private var previewConnection: AVCaptureConnection?
|
||||
|
||||
private var roundVideoFilter: CameraRoundVideoFilter?
|
||||
private var roundVideoFilter: CameraRoundLegacyVideoFilter?
|
||||
private let semaphore = DispatchSemaphore(value: 1)
|
||||
|
||||
private let videoQueue = DispatchQueue(label: "", qos: .userInitiated)
|
||||
@ -577,11 +577,11 @@ final class CameraOutput: NSObject {
|
||||
return nil
|
||||
}
|
||||
|
||||
let filter: CameraRoundVideoFilter
|
||||
let filter: CameraRoundLegacyVideoFilter
|
||||
if let current = self.roundVideoFilter {
|
||||
filter = current
|
||||
} else {
|
||||
filter = CameraRoundVideoFilter(ciContext: self.ciContext, colorSpace: self.colorSpace, simple: self.exclusive)
|
||||
filter = CameraRoundLegacyVideoFilter(ciContext: self.ciContext, colorSpace: self.colorSpace, simple: self.exclusive)
|
||||
self.roundVideoFilter = filter
|
||||
}
|
||||
if !filter.isPrepared {
|
||||
|
@ -176,6 +176,7 @@ public final class ChatPanelInterfaceInteraction {
|
||||
public let updateDisplayHistoryFilterAsList: (Bool) -> Void
|
||||
public let openBoostToUnrestrict: () -> Void
|
||||
public let updateRecordingTrimRange: (Double, Double, Bool, Bool) -> Void
|
||||
public let dismissAllTooltips: () -> Void
|
||||
public let requestLayout: (ContainedViewLayoutTransition) -> Void
|
||||
public let chatController: () -> ViewController?
|
||||
public let statuses: ChatPanelInterfaceInteractionStatuses?
|
||||
@ -291,6 +292,7 @@ public final class ChatPanelInterfaceInteraction {
|
||||
openMessagePayment: @escaping () -> Void,
|
||||
openBoostToUnrestrict: @escaping () -> Void,
|
||||
updateRecordingTrimRange: @escaping (Double, Double, Bool, Bool) -> Void,
|
||||
dismissAllTooltips: @escaping () -> Void,
|
||||
updateHistoryFilter: @escaping ((ChatPresentationInterfaceState.HistoryFilter?) -> ChatPresentationInterfaceState.HistoryFilter?) -> Void,
|
||||
updateChatLocationThread: @escaping (Int64?, ChatControllerAnimateInnerChatSwitchDirection?) -> Void,
|
||||
toggleChatSidebarMode: @escaping () -> Void,
|
||||
@ -409,6 +411,7 @@ public final class ChatPanelInterfaceInteraction {
|
||||
self.openMessagePayment = openMessagePayment
|
||||
self.openBoostToUnrestrict = openBoostToUnrestrict
|
||||
self.updateRecordingTrimRange = updateRecordingTrimRange
|
||||
self.dismissAllTooltips = dismissAllTooltips
|
||||
self.updateHistoryFilter = updateHistoryFilter
|
||||
self.updateChatLocationThread = updateChatLocationThread
|
||||
self.toggleChatSidebarMode = toggleChatSidebarMode
|
||||
@ -536,6 +539,7 @@ public final class ChatPanelInterfaceInteraction {
|
||||
}, openMessagePayment: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateRecordingTrimRange: { _, _, _, _ in
|
||||
}, dismissAllTooltips: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, updateChatLocationThread: { _, _ in
|
||||
}, toggleChatSidebarMode: {
|
||||
|
@ -204,6 +204,8 @@ private enum ApplicationSpecificGlobalNotice: Int32 {
|
||||
case starGiftWearTips = 77
|
||||
case channelSuggestTooltip = 78
|
||||
case multipleStoriesTooltip = 79
|
||||
case voiceMessagesPauseSuggestion = 80
|
||||
case videoMessagesPauseSuggestion = 81
|
||||
|
||||
var key: ValueBoxKey {
|
||||
let v = ValueBoxKey(length: 4)
|
||||
@ -569,6 +571,14 @@ private struct ApplicationSpecificNoticeKeys {
|
||||
static func multipleStoriesTooltip() -> NoticeEntryKey {
|
||||
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.multipleStoriesTooltip.key)
|
||||
}
|
||||
|
||||
static func voiceMessagesPauseSuggestion() -> NoticeEntryKey {
|
||||
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.voiceMessagesPauseSuggestion.key)
|
||||
}
|
||||
|
||||
static func videoMessagesPauseSuggestion() -> NoticeEntryKey {
|
||||
return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.videoMessagesPauseSuggestion.key)
|
||||
}
|
||||
}
|
||||
|
||||
public struct ApplicationSpecificNotice {
|
||||
@ -2458,4 +2468,58 @@ public struct ApplicationSpecificNotice {
|
||||
return Int(previousValue)
|
||||
}
|
||||
}
|
||||
|
||||
public static func getVoiceMessagesPauseSuggestion(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Int32, NoError> {
|
||||
return accountManager.transaction { transaction -> Int32 in
|
||||
if let value = transaction.getNotice(ApplicationSpecificNoticeKeys.voiceMessagesPauseSuggestion())?.get(ApplicationSpecificCounterNotice.self) {
|
||||
return value.value
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static func incrementVoiceMessagesPauseSuggestion(accountManager: AccountManager<TelegramAccountManagerTypes>, count: Int = 1) -> Signal<Int, NoError> {
|
||||
return accountManager.transaction { transaction -> Int in
|
||||
var currentValue: Int32 = 0
|
||||
if let value = transaction.getNotice(ApplicationSpecificNoticeKeys.voiceMessagesPauseSuggestion())?.get(ApplicationSpecificCounterNotice.self) {
|
||||
currentValue = value.value
|
||||
}
|
||||
let previousValue = currentValue
|
||||
currentValue += Int32(count)
|
||||
|
||||
if let entry = CodableEntry(ApplicationSpecificCounterNotice(value: currentValue)) {
|
||||
transaction.setNotice(ApplicationSpecificNoticeKeys.voiceMessagesPauseSuggestion(), entry)
|
||||
}
|
||||
|
||||
return Int(previousValue)
|
||||
}
|
||||
}
|
||||
|
||||
public static func getVideoMessagesPauseSuggestion(accountManager: AccountManager<TelegramAccountManagerTypes>) -> Signal<Int32, NoError> {
|
||||
return accountManager.transaction { transaction -> Int32 in
|
||||
if let value = transaction.getNotice(ApplicationSpecificNoticeKeys.videoMessagesPauseSuggestion())?.get(ApplicationSpecificCounterNotice.self) {
|
||||
return value.value
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static func incrementVideoMessagesPauseSuggestion(accountManager: AccountManager<TelegramAccountManagerTypes>, count: Int = 1) -> Signal<Int, NoError> {
|
||||
return accountManager.transaction { transaction -> Int in
|
||||
var currentValue: Int32 = 0
|
||||
if let value = transaction.getNotice(ApplicationSpecificNoticeKeys.videoMessagesPauseSuggestion())?.get(ApplicationSpecificCounterNotice.self) {
|
||||
currentValue = value.value
|
||||
}
|
||||
let previousValue = currentValue
|
||||
currentValue += Int32(count)
|
||||
|
||||
if let entry = CodableEntry(ApplicationSpecificCounterNotice(value: currentValue)) {
|
||||
transaction.setNotice(ApplicationSpecificNoticeKeys.videoMessagesPauseSuggestion(), entry)
|
||||
}
|
||||
|
||||
return Int(previousValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +169,7 @@ public final class ChatRecentActionsController: TelegramBaseController {
|
||||
}, openMessagePayment: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateRecordingTrimRange: { _, _, _, _ in
|
||||
}, dismissAllTooltips: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, updateChatLocationThread: { _, _ in
|
||||
}, toggleChatSidebarMode: {
|
||||
|
@ -434,6 +434,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
|
||||
}, openMessagePayment: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateRecordingTrimRange: { _, _, _, _ in
|
||||
}, dismissAllTooltips: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, updateChatLocationThread: { _, _ in
|
||||
}, toggleChatSidebarMode: {
|
||||
|
@ -783,6 +783,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
||||
}, openMessagePayment: {
|
||||
}, openBoostToUnrestrict: {
|
||||
}, updateRecordingTrimRange: { _, _, _, _ in
|
||||
}, dismissAllTooltips: {
|
||||
}, updateHistoryFilter: { _ in
|
||||
}, updateChatLocationThread: { _, _ in
|
||||
}, toggleChatSidebarMode: {
|
||||
|
@ -1199,6 +1199,8 @@ public class VideoMessageCameraScreen: ViewController {
|
||||
self.currentLiveUploadData = nil
|
||||
}
|
||||
|
||||
let _ = ApplicationSpecificNotice.incrementVideoMessagesPauseSuggestion(accountManager: self.context.sharedContext.accountManager, count: 3).startStandalone()
|
||||
|
||||
self.pauseCameraCapture()
|
||||
|
||||
self.results.append(result)
|
||||
@ -1251,22 +1253,35 @@ public class VideoMessageCameraScreen: ViewController {
|
||||
return result
|
||||
}
|
||||
|
||||
fileprivate func maybePresentViewOnceTooltip() {
|
||||
fileprivate func maybePresentTooltips() {
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let _ = (ApplicationSpecificNotice.getVideoMessagesPlayOnceSuggestion(accountManager: context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] counter in
|
||||
|
||||
let _ = (ApplicationSpecificNotice.getVideoMessagesPauseSuggestion(accountManager: self.context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] pauseCounter in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if counter >= 3 {
|
||||
return
|
||||
|
||||
if pauseCounter >= 3 {
|
||||
let _ = (ApplicationSpecificNotice.getVideoMessagesPlayOnceSuggestion(accountManager: self.context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] counter in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if counter >= 3 {
|
||||
return
|
||||
}
|
||||
Queue.mainQueue().after(0.3) {
|
||||
self.displayViewOnceTooltip(text: presentationData.strings.Chat_TapToPlayVideoMessageOnceTooltip, hasIcon: true)
|
||||
}
|
||||
let _ = ApplicationSpecificNotice.incrementVideoMessagesPlayOnceSuggestion(accountManager: self.context.sharedContext.accountManager).startStandalone()
|
||||
})
|
||||
} else {
|
||||
Queue.mainQueue().after(0.3) {
|
||||
self.displayPauseTooltip(text: presentationData.strings.Chat_PauseVideoMessageTooltip)
|
||||
}
|
||||
let _ = ApplicationSpecificNotice.incrementVideoMessagesPauseSuggestion(accountManager: self.context.sharedContext.accountManager).startStandalone()
|
||||
}
|
||||
|
||||
Queue.mainQueue().after(0.3) {
|
||||
self.displayViewOnceTooltip(text: presentationData.strings.Chat_TapToPlayVideoMessageOnceTooltip, hasIcon: true)
|
||||
}
|
||||
|
||||
let _ = ApplicationSpecificNotice.incrementVideoMessagesPlayOnceSuggestion(accountManager: self.context.sharedContext.accountManager).startStandalone()
|
||||
})
|
||||
}
|
||||
|
||||
@ -1299,6 +1314,36 @@ public class VideoMessageCameraScreen: ViewController {
|
||||
)
|
||||
controller.present(tooltipController, in: .window(.root))
|
||||
}
|
||||
|
||||
private func displayPauseTooltip(text: String) {
|
||||
guard let controller = self.controller, let sourceView = self.componentHost.findTaggedView(tag: viewOnceButtonTag) else {
|
||||
return
|
||||
}
|
||||
|
||||
self.dismissAllTooltips()
|
||||
|
||||
let absoluteFrame = sourceView.convert(sourceView.bounds, to: self.view)
|
||||
let location = CGRect(origin: CGPoint(x: absoluteFrame.midX - 20.0, y: absoluteFrame.midY + 53.0), size: CGSize())
|
||||
|
||||
let tooltipController = TooltipScreen(
|
||||
account: context.account,
|
||||
sharedContext: context.sharedContext,
|
||||
text: .markdown(text: text),
|
||||
balancedTextLayout: true,
|
||||
constrainWidth: 240.0,
|
||||
style: .customBlur(UIColor(rgb: 0x18181a), 0.0),
|
||||
arrowStyle: .small,
|
||||
icon: nil,
|
||||
location: .point(location, .right),
|
||||
displayDuration: .default,
|
||||
inset: 8.0,
|
||||
cornerRadius: 8.0,
|
||||
shouldDismissOnTouch: { _, _ in
|
||||
return .ignore
|
||||
}
|
||||
)
|
||||
controller.present(tooltipController, in: .window(.root))
|
||||
}
|
||||
|
||||
fileprivate func dismissAllTooltips() {
|
||||
guard let controller = self.controller else {
|
||||
@ -1934,7 +1979,7 @@ public class VideoMessageCameraScreen: ViewController {
|
||||
self.updateCameraState({ $0.updatedRecording(.handsFree) }, transition: .spring(duration: 0.4))
|
||||
}
|
||||
|
||||
self.node.maybePresentViewOnceTooltip()
|
||||
self.node.maybePresentTooltips()
|
||||
}
|
||||
|
||||
public func discardVideo() {
|
||||
|
@ -4112,6 +4112,11 @@ extension ChatControllerImpl {
|
||||
return
|
||||
}
|
||||
self.updateTrimRange(start: start, end: end, updatedEnd: updatedEnd, apply: apply)
|
||||
}, dismissAllTooltips: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.dismissAllTooltips()
|
||||
}, updateHistoryFilter: { [weak self] update in
|
||||
guard let self else {
|
||||
return
|
||||
|
@ -276,6 +276,8 @@ extension ChatControllerImpl {
|
||||
audioRecorderValue.stop()
|
||||
}
|
||||
|
||||
self.dismissAllTooltips()
|
||||
|
||||
switch updatedAction {
|
||||
case .dismiss:
|
||||
self.recorderDataDisposable.set(nil)
|
||||
@ -528,7 +530,11 @@ extension ChatControllerImpl {
|
||||
})
|
||||
}
|
||||
|
||||
self.videoRecorderValue?.lockVideoRecording()
|
||||
if let _ = self.audioRecorderValue {
|
||||
self.maybePresentAudioPauseTooltip()
|
||||
} else if let videoRecorderValue = self.videoRecorderValue {
|
||||
videoRecorderValue.lockVideoRecording()
|
||||
}
|
||||
}
|
||||
|
||||
func deleteMediaRecording() {
|
||||
@ -544,6 +550,56 @@ extension ChatControllerImpl {
|
||||
$0.updatedInterfaceState { $0.withUpdatedMediaDraftState(nil) }
|
||||
})
|
||||
self.updateDownButtonVisibility()
|
||||
|
||||
self.dismissAllTooltips()
|
||||
}
|
||||
|
||||
private func maybePresentAudioPauseTooltip() {
|
||||
let _ = (ApplicationSpecificNotice.getVoiceMessagesPauseSuggestion(accountManager: self.context.sharedContext.accountManager)
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] pauseCounter in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
if pauseCounter >= 3 {
|
||||
return
|
||||
} else {
|
||||
Queue.mainQueue().after(0.3) {
|
||||
self.displayPauseTooltip(text: self.presentationData.strings.Chat_PauseVoiceMessageTooltip)
|
||||
}
|
||||
let _ = ApplicationSpecificNotice.incrementVoiceMessagesPauseSuggestion(accountManager: self.context.sharedContext.accountManager).startStandalone()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private func displayPauseTooltip(text: String) {
|
||||
guard let layout = self.validLayout else {
|
||||
return
|
||||
}
|
||||
|
||||
self.dismissAllTooltips()
|
||||
|
||||
let insets = layout.insets(options: [.input])
|
||||
let location = CGRect(origin: CGPoint(x: layout.size.width - layout.safeInsets.right - 42.0 - UIScreenPixel, y: layout.size.height - insets.bottom - 122.0), size: CGSize())
|
||||
|
||||
let tooltipController = TooltipScreen(
|
||||
account: self.context.account,
|
||||
sharedContext: self.context.sharedContext,
|
||||
text: .markdown(text: text),
|
||||
balancedTextLayout: true,
|
||||
constrainWidth: 240.0,
|
||||
style: .customBlur(UIColor(rgb: 0x18181a), 0.0),
|
||||
arrowStyle: .small,
|
||||
icon: nil,
|
||||
location: .point(location, .right),
|
||||
displayDuration: .default,
|
||||
inset: 8.0,
|
||||
cornerRadius: 8.0,
|
||||
shouldDismissOnTouch: { _, _ in
|
||||
return .ignore
|
||||
}
|
||||
)
|
||||
self.present(tooltipController, in: .window(.root))
|
||||
}
|
||||
|
||||
private func withAudioRecorder(_ f: (ManagedAudioRecorder) -> Void) {
|
||||
|
@ -9111,6 +9111,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if let controller = controller as? QuickShareToastScreen {
|
||||
controller.dismissWithCommitAction()
|
||||
}
|
||||
if let controller = controller as? TooltipScreen, !controller.alwaysVisible {
|
||||
controller.dismiss()
|
||||
}
|
||||
})
|
||||
self.forEachController({ controller in
|
||||
if let controller = controller as? UndoOverlayController {
|
||||
|
@ -2924,6 +2924,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
|
||||
|
||||
self.tooltipController?.dismiss()
|
||||
if self.viewOnce {
|
||||
self.interfaceInteraction?.dismissAllTooltips()
|
||||
self.displayViewOnceTooltip(text: interfaceState.strings.Chat_PlayVoiceMessageOnceTooltip)
|
||||
|
||||
let _ = ApplicationSpecificNotice.incrementVoiceMessagesPlayOnceSuggestion(accountManager: context.sharedContext.accountManager, count: 3).startStandalone()
|
||||
|
Loading…
x
Reference in New Issue
Block a user