From e68a4c7b7fa548ecbb5aeeacb04b8988d4377dc2 Mon Sep 17 00:00:00 2001 From: Denis Shilovich Date: Wed, 12 Feb 2025 15:12:23 +0000 Subject: [PATCH] 1.9.7 (442) --- MODULE.bazel.lock | 6 +- Package.resolved | 4 +- .../Sources/PresentationCallManager.swift | 1 + .../Sources/ChatListController.swift | 3 +- .../Sources/ChatListControllerNode.swift | 5 + .../Sources/CallControllerNodeV2.swift | 3 + .../Sources/PresentationCallManager.swift | 11 +- .../ChatInterfaceStateContextMenus.swift | 111 +++++++++++++++++- 8 files changed, 127 insertions(+), 17 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 8a5acf7e8bc..21ec8c0978f 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -633,7 +633,7 @@ "bzlTransitiveDigest": "8/YWyYftd8THfVoADvrOmQLl45wUGfP2MVjLM5FFn50=", "usagesDigest": "voXBMcSNlo2fnK6JIvInIrncYhBKKG8nBeKvToaUA0Y=", "recordedFileInputs": { - "@@//Package.resolved": "555fc2f610571bf821780fe1e4fafd54265845ad9bcd5adda8dd0b3ed13e12d9", + "@@//Package.resolved": "ef5de94abf32065dcb5401064f2141203b1a39605898d1edb8ffaafaa9ea69cc", "@@//Package.swift": "fb3cb1d48066e64f8bf17fe1a49f689b7a6bf4bfc07aa90b9b80a02188501951" }, "recordedDirentsInputs": {}, @@ -1328,9 +1328,9 @@ "ruleClassName": "swift_package", "attributes": { "bazel_package_name": "swiftpkg_wallet_core", - "commit": "e55a95330d61bfe29a8ee9dac87afb59fe20ab73", + "commit": "b58fe8fef70e2a5446371e25cc2cc32dd003f978", "remote": "https://github.com/trustwallet/wallet-core.git", - "version": "4.2.9", + "version": "4.2.10", "init_submodules": false, "recursive_init_submodules": true, "patch_args": [ diff --git a/Package.resolved b/Package.resolved index ff200590c07..116b89a91b8 100644 --- a/Package.resolved +++ b/Package.resolved @@ -356,8 +356,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/trustwallet/wallet-core.git", "state" : { - "revision" : "e55a95330d61bfe29a8ee9dac87afb59fe20ab73", - "version" : "4.2.9" + "revision" : "b58fe8fef70e2a5446371e25cc2cc32dd003f978", + "version" : "4.2.10" } }, { diff --git a/submodules/AccountContext/Sources/PresentationCallManager.swift b/submodules/AccountContext/Sources/PresentationCallManager.swift index c02c0773b4c..45c22384b71 100644 --- a/submodules/AccountContext/Sources/PresentationCallManager.swift +++ b/submodules/AccountContext/Sources/PresentationCallManager.swift @@ -481,5 +481,6 @@ public protocol PresentationCallManager: AnyObject { func stopRecordCall(needStopPartTimer: Bool) func setupPeer(peer: EnginePeer) func showRecordSaveToast() + func stopPartTimer() // } diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index b54492f6475..9aa0f718e6b 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -819,12 +819,13 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController _ = (self.ready.get() |> deliverOnMainQueue) .start { [weak self] flag in guard let self else { return } - + if flag, NGSettings.rememberFolderOnExit, NGData.isPremium() { let lastFolder = NGSettings.lastFolder if lastFolder != -1 { + self.chatListDisplayNode.mainContainerNode.resetPendingItemNode() self.selectTab(id: .filter(lastFolder)) } } diff --git a/submodules/ChatListUI/Sources/ChatListControllerNode.swift b/submodules/ChatListUI/Sources/ChatListControllerNode.swift index 139b8bfb699..f8c4dde1266 100644 --- a/submodules/ChatListUI/Sources/ChatListControllerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListControllerNode.swift @@ -1056,6 +1056,11 @@ public final class ChatListContainerNode: ASDisplayNode, ASGestureRecognizerDele } } } +// MARK: Nicegram NCG-7102 bottom folders fix + public func resetPendingItemNode() { + self.pendingItemNode = nil + } +// } final class ChatListControllerNode: ASDisplayNode, ASGestureRecognizerDelegate { diff --git a/submodules/TelegramCallsUI/Sources/CallControllerNodeV2.swift b/submodules/TelegramCallsUI/Sources/CallControllerNodeV2.swift index b98e8d5dfc8..26f7cfb7478 100644 --- a/submodules/TelegramCallsUI/Sources/CallControllerNodeV2.swift +++ b/submodules/TelegramCallsUI/Sources/CallControllerNodeV2.swift @@ -148,6 +148,9 @@ final class CallControllerNodeV2: ViewControllerTracingNode, CallControllerNodeP return } self.endCall?() +// MARK: Nicegram NCG-5828 call recording + self.sharedContext.callManager?.stopPartTimer() +// } self.callScreen.backAction = { [weak self] in guard let self else { diff --git a/submodules/TelegramCallsUI/Sources/PresentationCallManager.swift b/submodules/TelegramCallsUI/Sources/PresentationCallManager.swift index ef58298b2df..7038ee0249e 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationCallManager.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationCallManager.swift @@ -1020,7 +1020,7 @@ public final class PresentationCallManagerImpl: PresentationCallManager { return dateFormatter }() - private let partLength: TimeInterval = 60 * 30 + private let partLength: TimeInterval = 30 * 60 public func startRecordCall( with completion: @escaping () -> Void @@ -1105,7 +1105,7 @@ public final class PresentationCallManagerImpl: PresentationCallManager { randomId: id ) let text = if partNumber > 1 { - "\(userDisplayName)-\(dateFormatter.string(from: date))- part \(partNumber)" + "\(userDisplayName)-\(dateFormatter.string(from: date))-part-\(partNumber)" } else { "\(userDisplayName)-\(dateFormatter.string(from: date))" } @@ -1126,8 +1126,7 @@ public final class PresentationCallManagerImpl: PresentationCallManager { title: "", performer: nil, waveform: nil - ), - .FileName(fileName: text) + ) ], alternativeRepresentations: [] ) @@ -1160,6 +1159,7 @@ public final class PresentationCallManagerImpl: PresentationCallManager { ) } }, completed: { [weak self] in + self?.partNumber += 1 self?.deleteFile(from: path) self?.showRecordSaveToast() sendCallRecorderAnalytics(with: .end) @@ -1187,13 +1187,12 @@ public final class PresentationCallManagerImpl: PresentationCallManager { let timer = Foundation.Timer(timeInterval: partLength, repeats: true) { [weak self] _ in self?.stopRecordCall(needStopPartTimer: false) self?.startRecordCall {} - self?.partNumber += 1 } self.partTimer = timer RunLoop.main.add(timer, forMode: .common) } - private func stopPartTimer() { + public func stopPartTimer() { partTimer?.invalidate() partTimer = nil } diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index b0bced38019..f2aa79d8de8 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -38,6 +38,7 @@ import NGUI import PeerInfoUI import NGData import NGSpeechToText +import AVFoundation // import TranslateUI import DebugSettingsUI @@ -495,7 +496,9 @@ func updatedChatEditInterfaceMessageState(context: AccountContext, state: ChatPr previewState ) } - +// MARK: Nicegram NCG-5828 call recording +var saveMediaDisposable: MetaDisposable? +// func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState: ChatPresentationInterfaceState, context: AccountContext, messages: [Message], controllerInteraction: ChatControllerInteraction?, selectAll: Bool, interfaceInteraction: ChatPanelInterfaceInteraction?, readStats: MessageReadStats? = nil, messageNode: ChatMessageItemView? = nil) -> Signal { guard let interfaceInteraction = interfaceInteraction, let controllerInteraction = controllerInteraction else { return .single(ContextController.Items(content: .list([]))) @@ -944,7 +947,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState return (data, updatingMessageMedia, infoSummaryData, appConfig, isMessageRead, messageViewsPrivacyTips, availableReactions, translationSettings, loggingSettings, notificationSoundList, accountPeer) } - + return dataSignal |> deliverOnMainQueue |> map { data, updatingMessageMedia, infoSummaryData, appConfig, isMessageRead, messageViewsPrivacyTips, availableReactions, translationSettings, loggingSettings, notificationSoundList, accountPeer -> ContextController.Items in @@ -1496,10 +1499,108 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState } // MARK: Nicegram NCG-5828 call recording else if file.isVoice { - actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_SaveToFiles, icon: { theme in + actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.WebBrowser_Download_Download, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.actionSheet.primaryTextColor) - }, action: { _, f in - controllerInteraction.saveMediaToFiles(message.id) + }, action: { _, f in + let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Messages.Message(id: message.id)) + |> deliverOnMainQueue).startStandalone(next: { message in + guard let message else { + return + } + var file: TelegramMediaFile? + let title: String = message.text + + for media in message.media { + if let mediaFile = media as? TelegramMediaFile, mediaFile.isVoice { + file = mediaFile + } + } + + guard let file else { + return + } + + var signal = fetchMediaData(context: context, postbox: context.account.postbox, userLocation: .other, mediaReference: .message(message: MessageReference(message._asMessage()), media: file)) + + let disposable: MetaDisposable + if let current = saveMediaDisposable { + disposable = current + } else { + disposable = MetaDisposable() + saveMediaDisposable = disposable + } + + var cancelImpl: (() -> Void)? + let presentationData = context.sharedContext.currentPresentationData.with { $0 } + let progressSignal = Signal { subscriber in + let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: { + cancelImpl?() + })) + controllerInteraction.presentController(controller, nil) + return ActionDisposable { [weak controller] in + Queue.mainQueue().async() { + controller?.dismiss() + } + } + } + |> runOn(Queue.mainQueue()) + |> delay(0.15, queue: Queue.mainQueue()) + let progressDisposable = progressSignal.startStrict() + + signal = signal + |> afterDisposed { + Queue.mainQueue().async { + progressDisposable.dispose() + } + } + cancelImpl = { [weak disposable] in + disposable?.set(nil) + } + disposable.set((signal + |> deliverOnMainQueue).startStrict(next: { state, _ in + switch state { + case .progress: + break + case let .data(data): + if data.complete { + var symlinkPath = data.path + ".ogg" + if fileSize(symlinkPath) != nil { + try? FileManager.default.removeItem(atPath: symlinkPath) + } + let _ = try? FileManager.default.linkItem(atPath: data.path, toPath: symlinkPath) + + let audioUrl = URL(fileURLWithPath: symlinkPath) + let audioAsset = AVURLAsset(url: audioUrl) + + var fileExtension = "ogg" + + if let filename = file.fileName { + if let dotIndex = filename.lastIndex(of: ".") { + fileExtension = String(filename[filename.index(after: dotIndex)...]) + } + } + + var nameComponents: [String] = [] + if !title.isEmpty { + nameComponents.append(title) + } + + if !nameComponents.isEmpty { + try? FileManager.default.removeItem(atPath: symlinkPath) + + let fileName = "\(nameComponents.joined(separator: " – ")).\(fileExtension)" + symlinkPath = symlinkPath.replacingOccurrences(of: audioUrl.lastPathComponent, with: fileName) + let _ = try? FileManager.default.linkItem(atPath: data.path, toPath: symlinkPath) + } + + let url = URL(fileURLWithPath: symlinkPath) + + let activityController = UIActivityViewController(activityItems: [url], applicationActivities: nil) + context.sharedContext.applicationBindings.presentNativeController(activityController) + } + } + })) + }) f(.default) }))) }