From bf94ea75e9d901d1d3396cec471e794fd46cf09e Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Mon, 6 Feb 2023 00:55:17 +0400 Subject: [PATCH] Various fixes --- .../Telegram-iOS/en.lproj/Localizable.strings | 3 + .../AuthorizationSequenceController.swift | 5 +- .../Sources/ChatListSearchContainerNode.swift | 7 ++ .../Sources/Node/ChatListItem.swift | 2 +- submodules/DebugSettingsUI/BUILD | 1 - .../Sources/DebugController.swift | 39 +---------- .../Sources/InAppPurchaseManager.swift | 2 +- .../LegacyComponents/TGMediaVideoConverter.h | 6 +- .../Sources/TGMediaAssetsController.m | 14 ++++ .../Sources/TGMediaVideoConverter.m | 17 ++--- .../Sources/TGPhotoQualityController.m | 9 ++- .../Sources/MediaPickerScreen.swift | 2 +- .../SearchBarNode/Sources/SearchBarNode.swift | 5 +- .../DataAndStorageSettingsController.swift | 68 ++++++++++++++----- .../Sources/VoiceChatController.swift | 8 ++- .../Sources/MessageContentKind.swift | 2 +- .../Sources/BackgroundColorComponent.swift | 2 +- .../ChatMessageAnimatedStickerItemNode.swift | 2 +- .../ChatMessageAttachedContentNode.swift | 2 +- .../Sources/ChatMessageBubbleItemNode.swift | 2 +- .../ChatMessageCallBubbleContentNode.swift | 2 +- .../ChatMessageContactBubbleContentNode.swift | 2 +- .../ChatMessageInteractiveFileNode.swift | 2 +- ...atMessageInteractiveInstantVideoNode.swift | 2 +- .../ChatMessageMapBubbleContentNode.swift | 2 +- .../ChatMessageMediaBubbleContentNode.swift | 4 +- .../ChatMessagePollBubbleContentNode.swift | 2 +- ...atMessageRestrictedBubbleContentNode.swift | 2 +- .../Sources/ChatMessageStickerItemNode.swift | 2 +- .../ChatMessageTextBubbleContentNode.swift | 2 +- .../Sources/ChatTranslationPanelNode.swift | 65 +++++++++--------- .../Sources/CreateChannelController.swift | 8 ++- .../Sources/CreateGroupController.swift | 9 ++- .../Sources/FetchVideoMediaResource.swift | 12 +++- .../InstantVideoRadialStatusNode.swift | 3 + .../Sources/PeerInfo/PeerInfoHeaderNode.swift | 4 +- .../Sources/PeerInfo/PeerInfoScreen.swift | 9 ++- .../StringForMessageTimestampStatus.swift | 7 +- .../Sources/MediaInputSettings.swift | 6 +- 39 files changed, 202 insertions(+), 141 deletions(-) diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 7fb7cb997e..8ad165c8d4 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -8886,3 +8886,6 @@ Sorry for the inconvenience."; "Translation.Language.ta" = "Tamil"; "Translation.Language.tr" = "Turkish"; "Translation.Language.uz" = "Uzbek"; + +"Settings.RaiseToListen" = "Raise to Listen"; +"Settings.RaiseToListenInfo" = "Raise to Listen allows you to quickly listen and reply to incoming audio messages by raising the phone to your ear."; diff --git a/submodules/AuthorizationUI/Sources/AuthorizationSequenceController.swift b/submodules/AuthorizationUI/Sources/AuthorizationSequenceController.swift index b9c6992c24..223da9bb54 100644 --- a/submodules/AuthorizationUI/Sources/AuthorizationSequenceController.swift +++ b/submodules/AuthorizationUI/Sources/AuthorizationSequenceController.swift @@ -954,7 +954,8 @@ public final class AuthorizationSequenceController: NavigationController, MFMail } } - let signal = TGMediaVideoConverter.convert(avatarAsset, adjustments: avatarAdjustments, watcher: nil, entityRenderer: entityRenderer)! + let tempFile = EngineTempBox.shared.tempFile(fileName: "video.mp4") + let signal = TGMediaVideoConverter.convert(avatarAsset, adjustments: avatarAdjustments, path: tempFile.path, watcher: nil, entityRenderer: entityRenderer)! let signalDisposable = signal.start(next: { next in if let result = next as? TGMediaVideoConversionResult { @@ -964,6 +965,8 @@ public final class AuthorizationSequenceController: NavigationController, MFMail let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) subscriber.putNext(resource) + + EngineTempBox.shared.dispose(tempFile) } } subscriber.putCompletion() diff --git a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift index 23a1cbf1ab..c9cdd41346 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchContainerNode.swift @@ -126,6 +126,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo private var selectedFilterPromise = Promise() private var transitionFraction: CGFloat = 0.0 + private var appearanceTimestamp: Double? + private weak var copyProtectionTooltipController: TooltipController? private lazy var hapticFeedback = { HapticFeedback() }() @@ -306,6 +308,10 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo return } + if let appearanceTimestamp = strongSelf.appearanceTimestamp, CACurrentMediaTime() - appearanceTimestamp < 0.5 { + return + } + var key: ChatListSearchPaneKey? var date = strongSelf.currentSearchOptions.date var peer = strongSelf.currentSearchOptions.peer @@ -667,6 +673,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo if isFirstTime { self.filterContainerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) + self.appearanceTimestamp = CACurrentMediaTime() } var bottomIntrinsicInset = layout.intrinsicInsets.bottom diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift index e3271143bc..9166b6a686 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift @@ -1848,7 +1848,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { entities = translation.entities } - messageString = stringWithAppliedEntities(trimToLineCount(messageText, lineCount: authorAttributedString == nil ? 2 : 1), entities: entities, baseColor: theme.messageTextColor, linkColor: theme.messageTextColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: italicTextFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message._asMessage()) + messageString = foldLineBreaks(stringWithAppliedEntities(messageText, entities: entities, baseColor: theme.messageTextColor, linkColor: theme.messageTextColor, baseFont: textFont, linkFont: textFont, boldFont: textFont, italicFont: italicTextFont, boldItalicFont: textFont, fixedFont: textFont, blockQuoteFont: textFont, underlineLinks: false, message: message._asMessage())) } else if spoilers != nil || customEmojiRanges != nil { let mutableString = NSMutableAttributedString(string: messageText, font: textFont, textColor: theme.messageTextColor) if let spoilers = spoilers { diff --git a/submodules/DebugSettingsUI/BUILD b/submodules/DebugSettingsUI/BUILD index a8ea3aa7b3..60710882b0 100644 --- a/submodules/DebugSettingsUI/BUILD +++ b/submodules/DebugSettingsUI/BUILD @@ -25,7 +25,6 @@ swift_library( "//submodules/GZip:GZip", "//third-party/ZipArchive:ZipArchive", "//submodules/InAppPurchaseManager:InAppPurchaseManager", - "//submodules/Utils/DarwinDirStat", ], visibility = [ "//visibility:public", diff --git a/submodules/DebugSettingsUI/Sources/DebugController.swift b/submodules/DebugSettingsUI/Sources/DebugController.swift index 46e8ae0508..8f2a768db3 100644 --- a/submodules/DebugSettingsUI/Sources/DebugController.swift +++ b/submodules/DebugSettingsUI/Sources/DebugController.swift @@ -16,7 +16,6 @@ import AppBundle import ZipArchive import WebKit import InAppPurchaseManager -import DarwinDirStat @objc private final class DebugControllerMailComposeDelegate: NSObject, MFMailComposeViewControllerDelegate { public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { @@ -948,15 +947,10 @@ private enum DebugControllerEntry: ItemListNodeEntry { case .resetTranslationStates: return ItemListActionItem(presentationData: presentationData, title: "Reset Translation States", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { if let context = arguments.context { - let size = statForDirectory(path: NSTemporaryDirectory()) - let controller = textAlertController(context: context, title: nil, text: "temp dir size \(size)", actions: [TextAlertAction(type: .genericAction, title: "OK", action: {})]) - arguments.presentController(controller, nil) + let _ = context.engine.itemCache.clear(collectionIds: [ + ApplicationSpecificItemCacheCollectionId.translationState + ]).start() } -// if let context = arguments.context { -// let _ = context.engine.itemCache.clear(collectionIds: [ -// ApplicationSpecificItemCacheCollectionId.translationState -// ]).start() -// } }) case .crash: return ItemListActionItem(presentationData: presentationData, title: "Crash", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: { @@ -1545,30 +1539,3 @@ public func triggerDebugSendLogsUI(context: AccountContext, additionalInfo: Stri pushController(controller) }) } - -private func statForDirectory(path: String) -> Int64 { - if #available(macOS 10.13, *) { - var s = darwin_dirstat() - var result = dirstat_np(path, 1, &s, MemoryLayout.size) - if result != -1 { - return Int64(s.total_size) - } else { - result = dirstat_np(path, 0, &s, MemoryLayout.size) - if result != -1 { - return Int64(s.total_size) - } else { - return 0 - } - } - } else { - let fileManager = FileManager.default - let folderURL = URL(fileURLWithPath: path) - var folderSize: Int64 = 0 - if let files = try? fileManager.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: nil, options: []) { - for file in files { - folderSize += (fileSize(file.path) ?? 0) - } - } - return folderSize - } -} diff --git a/submodules/InAppPurchaseManager/Sources/InAppPurchaseManager.swift b/submodules/InAppPurchaseManager/Sources/InAppPurchaseManager.swift index e8d9d6cc0a..99d606b32d 100644 --- a/submodules/InAppPurchaseManager/Sources/InAppPurchaseManager.swift +++ b/submodules/InAppPurchaseManager/Sources/InAppPurchaseManager.swift @@ -83,7 +83,7 @@ public final class InAppPurchaseManager: NSObject { } public func pricePerMonth(_ monthsCount: Int) -> String { - let price = self.skProduct.price.dividing(by: NSDecimalNumber(value: monthsCount)).prettyPrice().round(2) + let price = self.skProduct.price.dividing(by: NSDecimalNumber(value: monthsCount)).round(2) return self.numberFormatter.string(from: price) ?? "" } diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaVideoConverter.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaVideoConverter.h index 71a174799a..ed5638c23d 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaVideoConverter.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaVideoConverter.h @@ -16,11 +16,11 @@ @interface TGMediaVideoConverter : NSObject -+ (SSignal *)convertAVAsset:(AVAsset *)avAsset adjustments:(TGMediaVideoEditAdjustments *)adjustments watcher:(TGMediaVideoFileWatcher *)watcher entityRenderer:(id)entityRenderer; -+ (SSignal *)convertAVAsset:(AVAsset *)avAsset adjustments:(TGMediaVideoEditAdjustments *)adjustments watcher:(TGMediaVideoFileWatcher *)watcher inhibitAudio:(bool)inhibitAudio entityRenderer:(id)entityRenderer; ++ (SSignal *)convertAVAsset:(AVAsset *)avAsset adjustments:(TGMediaVideoEditAdjustments *)adjustments path:(NSString *)path watcher:(TGMediaVideoFileWatcher *)watcher entityRenderer:(id)entityRenderer; ++ (SSignal *)convertAVAsset:(AVAsset *)avAsset adjustments:(TGMediaVideoEditAdjustments *)adjustments path:(NSString *)path watcher:(TGMediaVideoFileWatcher *)watcher inhibitAudio:(bool)inhibitAudio entityRenderer:(id)entityRenderer; + (SSignal *)hashForAVAsset:(AVAsset *)avAsset adjustments:(TGMediaVideoEditAdjustments *)adjustments; -+ (SSignal *)renderUIImage:(UIImage *)image duration:(NSTimeInterval)duration adjustments:(TGMediaVideoEditAdjustments *)adjustments watcher:(TGMediaVideoFileWatcher *)watcher entityRenderer:(id)entityRenderer; ++ (SSignal *)renderUIImage:(UIImage *)image duration:(NSTimeInterval)duration adjustments:(TGMediaVideoEditAdjustments *)adjustments path:(NSString *)path watcher:(TGMediaVideoFileWatcher *)watcher entityRenderer:(id)entityRenderer; + (NSUInteger)estimatedSizeForPreset:(TGMediaVideoConversionPreset)preset duration:(NSTimeInterval)duration hasAudio:(bool)hasAudio; + (TGMediaVideoConversionPreset)bestAvailablePresetForDimensions:(CGSize)dimensions; diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetsController.m b/submodules/LegacyComponents/Sources/TGMediaAssetsController.m index 92d6206d3d..6b2cd0c26e 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetsController.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetsController.m @@ -1475,6 +1475,8 @@ } } + bool spoiler = [editingContext spoilerForItem:asset]; + if ([asset isKindOfClass:[UIImage class]]) { if (intent == TGMediaAssetsControllerSendFileIntent) { @@ -1513,6 +1515,10 @@ if (groupedId != nil && !hasAnyTimers) dict[@"groupedId"] = groupedId; + if (spoiler) { + dict[@"spoiler"] = @true; + } + id generatedItem = descriptionGenerator(dict, caption, nil, nil); return generatedItem; }]; @@ -1560,6 +1566,10 @@ if (groupedId != nil && !hasAnyTimers) dict[@"groupedId"] = groupedId; + if (spoiler) { + dict[@"spoiler"] = @true; + } + id generatedItem = descriptionGenerator(dict, caption, nil, nil); return generatedItem; }] catch:^SSignal *(__unused id error) @@ -1636,6 +1646,10 @@ else if (groupedId != nil && !hasAnyTimers) dict[@"groupedId"] = groupedId; + if (spoiler) { + dict[@"spoiler"] = @true; + } + id generatedItem = descriptionGenerator(dict, caption, nil, nil); return generatedItem; }]; diff --git a/submodules/LegacyComponents/Sources/TGMediaVideoConverter.m b/submodules/LegacyComponents/Sources/TGMediaVideoConverter.m index b8ec8db47a..4de1146338 100644 --- a/submodules/LegacyComponents/Sources/TGMediaVideoConverter.m +++ b/submodules/LegacyComponents/Sources/TGMediaVideoConverter.m @@ -101,12 +101,12 @@ @implementation TGMediaVideoConverter -+ (SSignal *)convertAVAsset:(AVAsset *)avAsset adjustments:(TGMediaVideoEditAdjustments *)adjustments watcher:(TGMediaVideoFileWatcher *)watcher entityRenderer:(id)entityRenderer ++ (SSignal *)convertAVAsset:(AVAsset *)avAsset adjustments:(TGMediaVideoEditAdjustments *)adjustments path:(NSString *)path watcher:(TGMediaVideoFileWatcher *)watcher entityRenderer:(id)entityRenderer { - return [self convertAVAsset:avAsset adjustments:adjustments watcher:watcher inhibitAudio:false entityRenderer:entityRenderer]; + return [self convertAVAsset:avAsset adjustments:adjustments path:path watcher:watcher inhibitAudio:false entityRenderer:entityRenderer]; } -+ (SSignal *)convertAVAsset:(AVAsset *)avAsset adjustments:(TGMediaVideoEditAdjustments *)adjustments watcher:(TGMediaVideoFileWatcher *)watcher inhibitAudio:(bool)inhibitAudio entityRenderer:(id)entityRenderer ++ (SSignal *)convertAVAsset:(AVAsset *)avAsset adjustments:(TGMediaVideoEditAdjustments *)adjustments path:(NSString *)path watcher:(TGMediaVideoFileWatcher *)watcher inhibitAudio:(bool)inhibitAudio entityRenderer:(id)entityRenderer { if ([avAsset isKindOfClass:[NSURL class]]) { avAsset = [[AVURLAsset alloc] initWithURL:(NSURL *)avAsset options:nil]; @@ -116,7 +116,7 @@ return [[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { SAtomic *context = [[SAtomic alloc] initWithValue:[TGMediaVideoConversionContext contextWithQueue:queue subscriber:subscriber]]; - NSURL *outputUrl = [self _randomTemporaryURL]; + NSURL *outputUrl = [NSURL fileURLWithPath:path]; NSArray *requiredKeys = @[ @"tracks", @"duration" ]; [avAsset loadValuesAsynchronouslyForKeys:requiredKeys completionHandler:^ @@ -222,14 +222,14 @@ }]; } -+ (SSignal *)renderUIImage:(UIImage *)image duration:(NSTimeInterval)duration adjustments:(TGMediaVideoEditAdjustments *)adjustments watcher:(TGMediaVideoFileWatcher *)watcher entityRenderer:(id)entityRenderer ++ (SSignal *)renderUIImage:(UIImage *)image duration:(NSTimeInterval)duration adjustments:(TGMediaVideoEditAdjustments *)adjustments path:(NSString *)path watcher:(TGMediaVideoFileWatcher *)watcher entityRenderer:(id)entityRenderer { SQueue *queue = [[SQueue alloc] init]; return [[SSignal alloc] initWithGenerator:^id(SSubscriber *subscriber) { SAtomic *context = [[SAtomic alloc] initWithValue:[TGMediaVideoConversionContext contextWithQueue:queue subscriber:subscriber]]; - NSURL *outputUrl = [self _randomTemporaryURL]; + NSURL *outputUrl = [NSURL fileURLWithPath:path]; NSString *path = TGComponentsPathForResource(@"blank", @"mp4"); AVAsset *avAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:path] options:nil]; @@ -895,11 +895,6 @@ return CGSizeMake(renderWidth, renderHeight); } -+ (NSURL *)_randomTemporaryURL -{ - return [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSString alloc] initWithFormat:@"%x.mp4", (int)arc4random()]]]; -} - + (NSUInteger)estimatedSizeForPreset:(TGMediaVideoConversionPreset)preset duration:(NSTimeInterval)duration hasAudio:(bool)hasAudio { NSInteger bitrate = [TGMediaVideoConversionPresetSettings _videoBitrateKbpsForPreset:preset]; diff --git a/submodules/LegacyComponents/Sources/TGPhotoQualityController.m b/submodules/LegacyComponents/Sources/TGPhotoQualityController.m index 30e065f806..0f1bd6a9e7 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoQualityController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoQualityController.m @@ -648,6 +648,11 @@ const NSTimeInterval TGPhotoQualityPreviewDuration = 15.0f; [(TGPhotoEditorController *)self.parentViewController setInfoString:fileSize]; } ++ (NSString *)_randomTemporaryPath +{ + return [NSTemporaryDirectory() stringByAppendingPathComponent:[[NSString alloc] initWithFormat:@"%x.mp4", (int)arc4random()]]; +} + - (void)generateVideoPreview { if (self.preset == _currentPreset) @@ -665,6 +670,8 @@ const NSTimeInterval TGPhotoQualityPreviewDuration = 15.0f; TGVideoEditAdjustments *adjustments = [self.photoEditor exportAdjustments]; adjustments = [adjustments editAdjustmentsWithPreset:self.preset maxDuration:TGPhotoQualityPreviewDuration]; + NSString *path = [TGPhotoQualityController _randomTemporaryPath]; + __block NSTimeInterval delay = 0.0; __weak TGPhotoQualityController *weakSelf = self; SSignal *convertSignal = [[assetSignal onNext:^(AVAsset *next) { @@ -680,7 +687,7 @@ const NSTimeInterval TGPhotoQualityPreviewDuration = 15.0f; { return [[[[[SSignal single:avAsset] delay:delay onQueue:[SQueue concurrentDefaultQueue]] mapToSignal:^SSignal *(AVAsset *avAsset) { - return [TGMediaVideoConverter convertAVAsset:avAsset adjustments:adjustments watcher:nil inhibitAudio:true entityRenderer:nil]; + return [TGMediaVideoConverter convertAVAsset:avAsset adjustments:adjustments path:path watcher:nil inhibitAudio:true entityRenderer:nil]; }] onError:^(__unused id error) { delay = 1.0; }] retryIf:^bool(__unused id error) diff --git a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift index 18f821da8a..1a334237b8 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift @@ -751,7 +751,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable { case .assets: signals = TGMediaAssetsController.resultSignals(for: controller.interaction?.selectionState, editingContext: controller.interaction?.editingState, intent: asFile ? TGMediaAssetsControllerSendFileIntent : TGMediaAssetsControllerSendMediaIntent, currentItem: nil, storeAssets: true, convertToJpeg: convertToJpeg, descriptionGenerator: legacyAssetPickerItemGenerator(), saveEditedPhotos: controller.saveEditedPhotos) case .media: - signals = TGMediaAssetsController.pasteboardResultSignals(for: controller.interaction?.selectionState, editingContext: controller.interaction?.editingState, intent: asFile ? TGMediaAssetsControllerSendFileIntent : TGMediaAssetsControllerSendMediaIntent, currentItem: nil, descriptionGenerator: legacyAssetPickerItemGenerator()) + signals = TGMediaAssetsController.pasteboardResultSignals(for: controller.interaction?.selectionState, editingContext: controller.interaction?.editingState, intent: asFile ? TGMediaAssetsControllerSendFileIntent : TGMediaAssetsControllerSendMediaIntent, currentItem: nil, descriptionGenerator: legacyAssetPickerItemGenerator()) } guard let signals = signals else { return diff --git a/submodules/SearchBarNode/Sources/SearchBarNode.swift b/submodules/SearchBarNode/Sources/SearchBarNode.swift index 798792cd55..dedc477309 100644 --- a/submodules/SearchBarNode/Sources/SearchBarNode.swift +++ b/submodules/SearchBarNode/Sources/SearchBarNode.swift @@ -1067,6 +1067,8 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { node.isHidden = true + self.textField.isUserInteractionEnabled = false + if !self.clearButton.isHidden { let xOffset = targetTextBackgroundFrame.width - self.textBackgroundNode.frame.width if !xOffset.isZero { @@ -1118,10 +1120,11 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate { var backgroundCompleted = false var separatorCompleted = false var textBackgroundCompleted = false - let intermediateCompletion: () -> Void = { [weak node] in + let intermediateCompletion: () -> Void = { [weak node, weak self] in if backgroundCompleted && separatorCompleted && textBackgroundCompleted { completion() node?.isHidden = false + self?.textField.isUserInteractionEnabled = true } } diff --git a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift index 3c33297a21..5e6d8a8cee 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/DataAndStorageSettingsController.swift @@ -30,6 +30,7 @@ private final class DataAndStorageControllerArguments { let openSaveIncoming: (AutomaticSaveIncomingPeerType) -> Void let toggleSaveEditedPhotos: (Bool) -> Void let togglePauseMusicOnRecording: (Bool) -> Void + let toggleRaiseToListen: (Bool) -> Void let toggleAutoplayGifs: (Bool) -> Void let toggleAutoplayVideos: (Bool) -> Void let toggleDownloadInBackground: (Bool) -> Void @@ -37,7 +38,7 @@ private final class DataAndStorageControllerArguments { let openIntents: () -> Void let toggleEnableSensitiveContent: (Bool) -> Void - init(openStorageUsage: @escaping () -> Void, openNetworkUsage: @escaping () -> Void, openProxy: @escaping () -> Void, openAutomaticDownloadConnectionType: @escaping (AutomaticDownloadConnectionType) -> Void, resetAutomaticDownload: @escaping () -> Void, toggleVoiceUseLessData: @escaping (Bool) -> Void, openSaveIncoming: @escaping (AutomaticSaveIncomingPeerType) -> Void, toggleSaveEditedPhotos: @escaping (Bool) -> Void, togglePauseMusicOnRecording: @escaping (Bool) -> Void, toggleAutoplayGifs: @escaping (Bool) -> Void, toggleAutoplayVideos: @escaping (Bool) -> Void, toggleDownloadInBackground: @escaping (Bool) -> Void, openBrowserSelection: @escaping () -> Void, openIntents: @escaping () -> Void, toggleEnableSensitiveContent: @escaping (Bool) -> Void) { + init(openStorageUsage: @escaping () -> Void, openNetworkUsage: @escaping () -> Void, openProxy: @escaping () -> Void, openAutomaticDownloadConnectionType: @escaping (AutomaticDownloadConnectionType) -> Void, resetAutomaticDownload: @escaping () -> Void, toggleVoiceUseLessData: @escaping (Bool) -> Void, openSaveIncoming: @escaping (AutomaticSaveIncomingPeerType) -> Void, toggleSaveEditedPhotos: @escaping (Bool) -> Void, togglePauseMusicOnRecording: @escaping (Bool) -> Void, toggleRaiseToListen: @escaping (Bool) -> Void, toggleAutoplayGifs: @escaping (Bool) -> Void, toggleAutoplayVideos: @escaping (Bool) -> Void, toggleDownloadInBackground: @escaping (Bool) -> Void, openBrowserSelection: @escaping () -> Void, openIntents: @escaping () -> Void, toggleEnableSensitiveContent: @escaping (Bool) -> Void) { self.openStorageUsage = openStorageUsage self.openNetworkUsage = openNetworkUsage self.openProxy = openProxy @@ -47,6 +48,7 @@ private final class DataAndStorageControllerArguments { self.openSaveIncoming = openSaveIncoming self.toggleSaveEditedPhotos = toggleSaveEditedPhotos self.togglePauseMusicOnRecording = togglePauseMusicOnRecording + self.toggleRaiseToListen = toggleRaiseToListen self.toggleAutoplayGifs = toggleAutoplayGifs self.toggleAutoplayVideos = toggleAutoplayVideos self.toggleDownloadInBackground = toggleDownloadInBackground @@ -74,6 +76,8 @@ public enum DataAndStorageEntryTag: ItemListItemTag, Equatable { case autoplayVideos case saveEditedPhotos case downloadInBackground + case pauseMusicOnRecording + case raiseToListen case autoSave(AutomaticSaveIncomingPeerType) public func isEqual(to other: ItemListItemTag) -> Bool { @@ -108,9 +112,11 @@ private enum DataAndStorageEntry: ItemListNodeEntry { case otherHeader(PresentationTheme, String) case shareSheet(PresentationTheme, String) case saveEditedPhotos(PresentationTheme, String, Bool) - case pauseMusicOnRecording(PresentationTheme, String, Bool) case openLinksIn(PresentationTheme, String, String) - + case pauseMusicOnRecording(PresentationTheme, String, Bool) + case raiseToListen(PresentationTheme, String, Bool) + case raiseToListenInfo(PresentationTheme, String) + case connectionHeader(PresentationTheme, String) case connectionProxy(PresentationTheme, String, String) case enableSensitiveContent(String, Bool) @@ -129,7 +135,7 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return DataAndStorageSection.voiceCalls.rawValue case .autoplayHeader, .autoplayGifs, .autoplayVideos: return DataAndStorageSection.autoPlay.rawValue - case .otherHeader, .shareSheet, .saveEditedPhotos, .pauseMusicOnRecording, .openLinksIn: + case .otherHeader, .shareSheet, .saveEditedPhotos, .openLinksIn, .pauseMusicOnRecording, .raiseToListen, .raiseToListenInfo: return DataAndStorageSection.other.rawValue case .connectionHeader, .connectionProxy: return DataAndStorageSection.connection.rawValue @@ -152,14 +158,12 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return 4 case .automaticDownloadReset: return 5 - case .autoSaveHeader: return 6 case let .autoSaveItem(index, _, _, _, _): return 7 + Int32(index) case .autoSaveInfo: return 20 - case .downloadInBackground: return 21 case .downloadInBackgroundInfo: @@ -180,16 +184,20 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return 29 case .saveEditedPhotos: return 31 - case .pauseMusicOnRecording: - return 32 case .openLinksIn: + return 32 + case .pauseMusicOnRecording: return 33 - case .connectionHeader: + case .raiseToListen: return 34 - case .connectionProxy: + case .raiseToListenInfo: return 35 - case .enableSensitiveContent: + case .connectionHeader: return 36 + case .connectionProxy: + return 37 + case .enableSensitiveContent: + return 38 } } @@ -297,14 +305,26 @@ private enum DataAndStorageEntry: ItemListNodeEntry { } else { return false } + case let .openLinksIn(lhsTheme, lhsText, lhsValue): + if case let .openLinksIn(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { + return true + } else { + return false + } case let .pauseMusicOnRecording(lhsTheme, lhsText, lhsValue): if case let .pauseMusicOnRecording(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { return true } else { return false } - case let .openLinksIn(lhsTheme, lhsText, lhsValue): - if case let .openLinksIn(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { + case let .raiseToListen(lhsTheme, lhsText, lhsValue): + if case let .raiseToListen(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue { + return true + } else { + return false + } + case let .raiseToListenInfo(lhsTheme, lhsText): + if case let .raiseToListenInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { return true } else { return false @@ -420,14 +440,20 @@ private enum DataAndStorageEntry: ItemListNodeEntry { return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleSaveEditedPhotos(value) }, tag: DataAndStorageEntryTag.saveEditedPhotos) - case let .pauseMusicOnRecording(_, text, value): - return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in - arguments.togglePauseMusicOnRecording(value) - }, tag: DataAndStorageEntryTag.saveEditedPhotos) case let .openLinksIn(_, text, value): return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, action: { arguments.openBrowserSelection() }) + case let .pauseMusicOnRecording(_, text, value): + return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in + arguments.togglePauseMusicOnRecording(value) + }, tag: DataAndStorageEntryTag.pauseMusicOnRecording) + case let .raiseToListen(_, text, value): + return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in + arguments.toggleRaiseToListen(value) + }, tag: DataAndStorageEntryTag.raiseToListen) + case let .raiseToListenInfo(_, text): + return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section) case let .downloadInBackground(_, text, value): return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { value in arguments.toggleDownloadInBackground(value) @@ -646,8 +672,10 @@ private func dataAndStorageControllerEntries(state: DataAndStorageControllerStat entries.append(.shareSheet(presentationData.theme, presentationData.strings.ChatSettings_IntentsSettings)) } entries.append(.saveEditedPhotos(presentationData.theme, presentationData.strings.Settings_SaveEditedPhotos, data.generatedMediaStoreSettings.storeEditedPhotos)) - entries.append(.pauseMusicOnRecording(presentationData.theme, presentationData.strings.Settings_PauseMusicOnRecording, data.mediaInputSettings.pauseMusicOnRecording)) entries.append(.openLinksIn(presentationData.theme, presentationData.strings.ChatSettings_OpenLinksIn, defaultWebBrowser)) + entries.append(.pauseMusicOnRecording(presentationData.theme, presentationData.strings.Settings_PauseMusicOnRecording, data.mediaInputSettings.pauseMusicOnRecording)) + entries.append(.raiseToListen(presentationData.theme, presentationData.strings.Settings_RaiseToListen, data.mediaInputSettings.enableRaiseToSpeak)) + entries.append(.raiseToListenInfo(presentationData.theme, presentationData.strings.Settings_RaiseToListenInfo)) let proxyValue: String if let proxySettings = data.proxySettings, let activeServer = proxySettings.activeServer, proxySettings.enabled { @@ -878,6 +906,10 @@ public func dataAndStorageController(context: AccountContext, focusOnItemTag: Da let _ = updateMediaInputSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in return current.withUpdatedPauseMusicOnRecording(value) }).start() + }, toggleRaiseToListen: { value in + let _ = updateMediaInputSettingsInteractively(accountManager: context.sharedContext.accountManager, { + $0.withUpdatedEnableRaiseToSpeak(value) + }).start() }, toggleAutoplayGifs: { value in let _ = updateMediaDownloadSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in var settings = settings diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index 10aa9a82f0..d97eca8d94 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -6296,6 +6296,8 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController return nil } } + + let tempFile = EngineTempBox.shared.tempFile(fileName: "video.mp4") let uploadInterface = LegacyLiveUploadInterface(context: context) let signal: SSignal if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer { @@ -6311,14 +6313,14 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController }) signal = durationSignal.map(toSignal: { duration -> SSignal in if let duration = duration as? Double { - return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: nil, entityRenderer: entityRenderer)! + return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, path: tempFile.path, watcher: nil, entityRenderer: entityRenderer)! } else { return SSignal.single(nil) } }) } else if let asset = asset as? AVAsset { - signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)! + signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, path: tempFile.path, watcher: uploadInterface, entityRenderer: entityRenderer)! } else { signal = SSignal.complete() } @@ -6344,6 +6346,8 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController } account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) subscriber.putNext(resource) + + EngineTempBox.shared.dispose(tempFile) } } subscriber.putCompletion() diff --git a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift index 600caaad12..990b07d8b0 100644 --- a/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift +++ b/submodules/TelegramStringFormatting/Sources/MessageContentKind.swift @@ -418,7 +418,7 @@ public func foldLineBreaks(_ text: NSAttributedString) -> NSAttributedString { while true { if let range = remainingString.string.range(of: "\n") { let mappedRange = NSRange(range, in: remainingString.string) - lines.append(remainingString.attributedSubstring(from: NSRange(location: 0, length: mappedRange.upperBound))) + lines.append(remainingString.attributedSubstring(from: NSRange(location: 0, length: mappedRange.upperBound - 1))) remainingString.replaceCharacters(in: NSRange(location: 0, length: mappedRange.upperBound), with: "") } else { if lines.isEmpty { diff --git a/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/BackgroundColorComponent.swift b/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/BackgroundColorComponent.swift index 4272226fd6..d56e398b9e 100644 --- a/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/BackgroundColorComponent.swift +++ b/submodules/TelegramUI/Components/AvatarEditorScreen/Sources/BackgroundColorComponent.swift @@ -77,7 +77,7 @@ final class BackgroundColorComponent: Component { let itemSize = CGSize(width: 30.0, height: 30.0) let sideInset: CGFloat = 12.0 let height: CGFloat = 50.0 - let delta = (availableSize.width - sideInset * 2.0 - CGFloat(values.count) * itemSize.width) / CGFloat(values.count - 1) + let delta = floorToScreenPixels((availableSize.width - sideInset * 2.0 - CGFloat(values.count) * itemSize.width) / CGFloat(values.count - 1)) for i in 0 ..< values.count { let view: ComponentView diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 23ec16609e..04b9b9f034 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -1136,7 +1136,7 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { } } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .regular) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .regular, associatedData: item.associatedData) var isReplyThread = false if case .replyThread = item.chatLocation { diff --git a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift index 3c61b94cf9..2ef2cd0fa2 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift @@ -391,7 +391,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { } } - let dateText = stringForMessageTimestampStatus(accountPeerId: context.account.peerId, message: message, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, strings: presentationData.strings) + let dateText = stringForMessageTimestampStatus(accountPeerId: context.account.peerId, message: message, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, strings: presentationData.strings, associatedData: associatedData) var webpageGalleryMediaCount: Int? for media in message.media { diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 0bbe5642f3..7504cde026 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -1800,7 +1800,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode } else { dateFormat = .regular } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: dateFormat) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: dateFormat, associatedData: item.associatedData) let statusType: ChatMessageDateAndStatusType if incoming { diff --git a/submodules/TelegramUI/Sources/ChatMessageCallBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageCallBubbleContentNode.swift index 1b8016db8c..25aa0d6d85 100644 --- a/submodules/TelegramUI/Sources/ChatMessageCallBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageCallBubbleContentNode.swift @@ -167,7 +167,7 @@ class ChatMessageCallBubbleContentNode: ChatMessageBubbleContentNode { } } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, associatedData: item.associatedData) let statusText: String if let callDuration = callDuration, callDuration > 1 { diff --git a/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift index 4e2679138f..e1810b597c 100644 --- a/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageContactBubbleContentNode.swift @@ -188,7 +188,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode { } } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, associatedData: item.associatedData) let statusType: ChatMessageDateAndStatusType? switch position { diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift index 8b9f9add4c..c1f0e3a66e 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveFileNode.swift @@ -815,7 +815,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode { edited = true } - let dateText = stringForMessageTimestampStatus(accountPeerId: arguments.context.account.peerId, message: arguments.message, dateTimeFormat: arguments.presentationData.dateTimeFormat, nameDisplayOrder: arguments.presentationData.nameDisplayOrder, strings: arguments.presentationData.strings) + let dateText = stringForMessageTimestampStatus(accountPeerId: arguments.context.account.peerId, message: arguments.message, dateTimeFormat: arguments.presentationData.dateTimeFormat, nameDisplayOrder: arguments.presentationData.nameDisplayOrder, strings: arguments.presentationData.strings, associatedData: arguments.associatedData) let displayReactionsInline = shouldDisplayInlineDateReactions(message: arguments.message, isPremium: arguments.associatedData.isPremium, forceInline: arguments.associatedData.forceInlineReactions) var reactionSettings: ChatMessageDateAndStatusNode.TrailingReactionSettings? diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index 48768e4926..1f69e1a1b3 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -487,7 +487,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { } } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .regular) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .regular, associatedData: item.associatedData) let maxDateAndStatusWidth: CGFloat if case .bubble = statusDisplayType { diff --git a/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift index e2709d08e8..b075a9b7e9 100644 --- a/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageMapBubbleContentNode.swift @@ -205,7 +205,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode { } } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, associatedData: item.associatedData) let statusType: ChatMessageDateAndStatusType? switch position { diff --git a/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift index 3a5f317d6c..b212162374 100644 --- a/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageMediaBubbleContentNode.swift @@ -237,8 +237,8 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { } } } - - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings) + + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, associatedData: item.associatedData) let statusType: ChatMessageDateAndStatusType? switch preparePosition { diff --git a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift index 692ee29ba9..84eab063fb 100644 --- a/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessagePollBubbleContentNode.swift @@ -1069,7 +1069,7 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode { } } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, associatedData: item.associatedData) let statusType: ChatMessageDateAndStatusType? switch position { diff --git a/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift index 2fe0f93251..437d1b8a93 100644 --- a/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageRestrictedBubbleContentNode.swift @@ -71,7 +71,7 @@ class ChatMessageRestrictedBubbleContentNode: ChatMessageBubbleContentNode { } } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, associatedData: item.associatedData) let statusType: ChatMessageDateAndStatusType? switch position { diff --git a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift index a3f24aa215..d1740be7a9 100644 --- a/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageStickerItemNode.swift @@ -561,7 +561,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .regular) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: .regular, associatedData: item.associatedData) var isReplyThread = false if case .replyThread = item.chatLocation { diff --git a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift index b1642c0a50..ebac741e74 100644 --- a/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageTextBubbleContentNode.swift @@ -181,7 +181,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } else { dateFormat = .regular } - let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: dateFormat) + let dateText = stringForMessageTimestampStatus(accountPeerId: item.context.account.peerId, message: item.message, dateTimeFormat: item.presentationData.dateTimeFormat, nameDisplayOrder: item.presentationData.nameDisplayOrder, strings: item.presentationData.strings, format: dateFormat, associatedData: item.associatedData) let statusType: ChatMessageDateAndStatusType? var displayStatus = false diff --git a/submodules/TelegramUI/Sources/ChatTranslationPanelNode.swift b/submodules/TelegramUI/Sources/ChatTranslationPanelNode.swift index a29233eb71..1ccf63ee3d 100644 --- a/submodules/TelegramUI/Sources/ChatTranslationPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTranslationPanelNode.swift @@ -226,8 +226,8 @@ final class ChatTranslationPanelNode: ASDisplayNode { } } - topLanguages.append(contentsOf: popularTranslationLanguages) - + topLanguages.append("") + var languages: [(String, String)] = [] let languageLocale = Locale(identifier: langCode) @@ -322,6 +322,8 @@ private final class TranslationContextReferenceContentSource: ContextReferenceCo } } +private let separatorHeight: CGFloat = 7.0 + private final class TranslationLanguagesContextMenuContent: ContextControllerItemsContent { private final class BackButtonNode: HighlightTrackingButtonNode { let highlightBackgroundNode: ASDisplayNode @@ -445,7 +447,7 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte self.addSubnode(self.titleLabelNode) self.highligthedChanged = { [weak self] highlighted in - guard let strongSelf = self else { + guard let strongSelf = self, let language = strongSelf.language, !language.isEmpty else { return } if highlighted { @@ -461,6 +463,9 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte } @objc private func pressed() { + guard let language = self.language, !language.isEmpty else { + return + } self.action() } @@ -476,7 +481,6 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte } self.highlightBackgroundNode.backgroundColor = presentationData.theme.contextMenu.itemHighlightedBackgroundColor - self.separatorNode.backgroundColor = presentationData.theme.contextMenu.itemSeparatorColor self.highlightBackgroundNode.frame = CGRect(origin: CGPoint(), size: size) @@ -487,8 +491,15 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte let titleFrame = CGRect(origin: CGPoint(x: sideInset, y: floor((size.height - titleSize.height) / 2.0)), size: titleSize) self.titleLabelNode.frame = titleFrame - self.separatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: size.height), size: CGSize(width: size.width, height: UIScreenPixel)) - self.separatorNode.isHidden = isLast + if language == "" { + self.separatorNode.backgroundColor = presentationData.theme.contextMenu.sectionSeparatorColor + self.separatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: separatorHeight)) + self.separatorNode.isHidden = false + } else { + self.separatorNode.backgroundColor = presentationData.theme.contextMenu.itemSeparatorColor + self.separatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: size.height), size: CGSize(width: size.width, height: UIScreenPixel)) + self.separatorNode.isHidden = isLast + } } } @@ -537,26 +548,6 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte self.scrollNode.view.delegate = self self.clipsToBounds = true - -// self.stateDisposable = (self.listContext.state -// |> deliverOnMainQueue).start(next: { [weak self] state in -// guard let strongSelf = self else { -// return -// } -// let updatedState = ItemsState(listState: state, readStats: strongSelf.state.readStats) -// var animateIn = false -// if strongSelf.state.item(at: 0) == nil && updatedState.item(at: 0) != nil { -// animateIn = true -// } -// strongSelf.state = updatedState -// strongSelf.animateIn = true -// strongSelf.requestUpdate(strongSelf, animateIn ? .animated(duration: 0.2, curve: .easeInOut) : .immediate) -// if animateIn { -// for (_, itemNode) in strongSelf.itemNodes { -// itemNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2) -// } -// } -// }) } func scrollViewDidScroll(_ scrollView: UIScrollView) { @@ -591,11 +582,23 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte let minVisibleIndex = max(0, Int(floor(visibleBounds.minY / itemHeight))) let maxVisibleIndex = Int(ceil(visibleBounds.maxY / itemHeight)) - + + var separatorIndex = 0 + for i in 0 ..< self.languages.count { + if self.languages[i].0.isEmpty { + separatorIndex = i + break + } + } + if minVisibleIndex <= maxVisibleIndex { for index in minVisibleIndex ... maxVisibleIndex { - let itemFrame = CGRect(origin: CGPoint(x: 0.0, y: CGFloat(index) * itemHeight), size: CGSize(width: size.width, height: itemHeight)) - + let height = self.languages[index].0.isEmpty ? separatorHeight : itemHeight + var itemFrame = CGRect(origin: CGPoint(x: 0.0, y: CGFloat(index) * itemHeight), size: CGSize(width: size.width, height: height)) + if index > separatorIndex { + itemFrame.origin.y += separatorHeight - itemHeight + } + if index < self.languages.count { let (languageCode, displayTitle) = self.languages[index] validIds.insert(index) @@ -612,7 +615,7 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte self.scrollNode.addSubnode(itemNode) } - itemNode.update(size: itemFrame.size, presentationData: presentationData, language: languageCode, displayTitle: displayTitle, isLast: index == self.languages.count - 1, syncronousLoad: syncronousLoad) + itemNode.update(size: itemFrame.size, presentationData: presentationData, language: languageCode, displayTitle: displayTitle, isLast: index == self.languages.count - 1 || index == separatorIndex - 1, syncronousLoad: syncronousLoad) itemNode.frame = itemFrame } } @@ -745,7 +748,7 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte topContentHeight += backButtonFrame.height } if let separatorNode = self.separatorNode { - let separatorFrame = CGRect(origin: CGPoint(x: 0.0, y: topContentHeight), size: CGSize(width: constrainedSize.width, height: 7.0)) + let separatorFrame = CGRect(origin: CGPoint(x: 0.0, y: topContentHeight), size: CGSize(width: constrainedSize.width, height: separatorHeight)) separatorNode.backgroundColor = self.presentationData.theme.contextMenu.sectionSeparatorColor transition.updateFrame(node: separatorNode, frame: separatorFrame) topContentHeight += separatorFrame.height diff --git a/submodules/TelegramUI/Sources/CreateChannelController.swift b/submodules/TelegramUI/Sources/CreateChannelController.swift index bc7c6c6290..39ce3b3b2e 100644 --- a/submodules/TelegramUI/Sources/CreateChannelController.swift +++ b/submodules/TelegramUI/Sources/CreateChannelController.swift @@ -534,6 +534,8 @@ public func createChannelController(context: AccountContext, mode: CreateChannel return nil } } + + let tempFile = EngineTempBox.shared.tempFile(fileName: "video.mp4") let uploadInterface = LegacyLiveUploadInterface(context: context) let signal: SSignal if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer { @@ -549,14 +551,14 @@ public func createChannelController(context: AccountContext, mode: CreateChannel }) signal = durationSignal.map(toSignal: { duration -> SSignal in if let duration = duration as? Double { - return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: nil, entityRenderer: entityRenderer)! + return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, path: tempFile.path, watcher: nil, entityRenderer: entityRenderer)! } else { return SSignal.single(nil) } }) } else if let asset = asset as? AVAsset { - signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)! + signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, path: tempFile.path, watcher: uploadInterface, entityRenderer: entityRenderer)! } else { signal = SSignal.complete() } @@ -582,6 +584,8 @@ public func createChannelController(context: AccountContext, mode: CreateChannel } context.account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) subscriber.putNext(resource) + + EngineTempBox.shared.dispose(tempFile) } } subscriber.putCompletion() diff --git a/submodules/TelegramUI/Sources/CreateGroupController.swift b/submodules/TelegramUI/Sources/CreateGroupController.swift index de1fca0a60..dae2f8f7bc 100644 --- a/submodules/TelegramUI/Sources/CreateGroupController.swift +++ b/submodules/TelegramUI/Sources/CreateGroupController.swift @@ -850,7 +850,6 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] } let signal = Signal { subscriber in - let entityRenderer: LegacyPaintEntityRenderer? = adjustments.flatMap { adjustments in if let paintingData = adjustments.paintingData, paintingData.hasAnimation { return LegacyPaintEntityRenderer(account: context.account, adjustments: adjustments) @@ -858,6 +857,8 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] return nil } } + + let tempFile = EngineTempBox.shared.tempFile(fileName: "video.mp4") let uploadInterface = LegacyLiveUploadInterface(context: context) let signal: SSignal if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer { @@ -873,14 +874,14 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] }) signal = durationSignal.map(toSignal: { duration -> SSignal in if let duration = duration as? Double { - return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: nil, entityRenderer: entityRenderer)! + return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, path: tempFile.path, watcher: nil, entityRenderer: entityRenderer)! } else { return SSignal.single(nil) } }) } else if let asset = asset as? AVAsset { - signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)! + signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, path: tempFile.path, watcher: uploadInterface, entityRenderer: entityRenderer)! } else { signal = SSignal.complete() } @@ -906,6 +907,8 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId] } context.account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) subscriber.putNext(resource) + + EngineTempBox.shared.dispose(tempFile) } } subscriber.putCompletion() diff --git a/submodules/TelegramUI/Sources/FetchVideoMediaResource.swift b/submodules/TelegramUI/Sources/FetchVideoMediaResource.swift index 315482de9b..6f35c73e81 100644 --- a/submodules/TelegramUI/Sources/FetchVideoMediaResource.swift +++ b/submodules/TelegramUI/Sources/FetchVideoMediaResource.swift @@ -265,7 +265,8 @@ public func fetchVideoLibraryMediaResource(account: Account, resource: VideoLibr return nil } } - let signal = TGMediaVideoConverter.convert(avAsset, adjustments: adjustments, watcher: VideoConversionWatcher(update: { path, size in + let tempFile = EngineTempBox.shared.tempFile(fileName: "video.mp4") + let signal = TGMediaVideoConverter.convert(avAsset, adjustments: adjustments, path: tempFile.path, watcher: VideoConversionWatcher(update: { path, size in var value = stat() if stat(path, &value) == 0 { if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: [.mappedRead]) { @@ -298,6 +299,8 @@ public func fetchVideoLibraryMediaResource(account: Account, resource: VideoLibr subscriber.putError(.generic) } subscriber.putCompletion() + + EngineTempBox.shared.dispose(tempFile) } }, error: { _ in subscriber.putError(.generic) @@ -342,6 +345,7 @@ func fetchLocalFileVideoMediaResource(account: Account, resource: LocalFileVideo adjustments = TGVideoEditAdjustments(dictionary: dict) } } + let tempFile = EngineTempBox.shared.tempFile(fileName: "video.mp4") let updatedSize = Atomic(value: 0) let entityRenderer: LegacyPaintEntityRenderer? = adjustments.flatMap { adjustments in if let paintingData = adjustments.paintingData, paintingData.hasAnimation { @@ -366,7 +370,7 @@ func fetchLocalFileVideoMediaResource(account: Account, resource: LocalFileVideo signal = durationSignal.map(toSignal: { duration -> SSignal in if let duration = duration as? Double { - return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: VideoConversionWatcher(update: { path, size in + return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, path: tempFile.path, watcher: VideoConversionWatcher(update: { path, size in var value = stat() if stat(path, &value) == 0 { if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: [.mappedRead]) { @@ -388,7 +392,7 @@ func fetchLocalFileVideoMediaResource(account: Account, resource: LocalFileVideo signal = SSignal.single(nil) } } else { - signal = TGMediaVideoConverter.convert(avAsset, adjustments: adjustments, watcher: VideoConversionWatcher(update: { path, size in + signal = TGMediaVideoConverter.convert(avAsset, adjustments: adjustments, path: tempFile.path, watcher: VideoConversionWatcher(update: { path, size in var value = stat() if stat(path, &value) == 0 { if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: [.mappedRead]) { @@ -430,6 +434,8 @@ func fetchLocalFileVideoMediaResource(account: Account, resource: LocalFileVideo subscriber.putNext(.dataPart(resourceOffset: range!.lowerBound, data: data, range: range!, complete: false)) subscriber.putNext(.replaceHeader(data: data, range: 0 ..< 1024)) subscriber.putNext(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: true)) + + EngineTempBox.shared.dispose(tempFile) } } subscriber.putCompletion() diff --git a/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift b/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift index 2827f864c0..6357439f1f 100644 --- a/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift +++ b/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift @@ -5,6 +5,7 @@ import Display import SwiftSignalKit import UniversalMediaPlayer import LegacyComponents +import UIKitRuntimeUtils private final class InstantVideoRadialStatusNodeParameters: NSObject { let color: UIColor @@ -124,6 +125,8 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele strongSelf.statusValue = status } }) + + self.view.disablesInteractiveTransitionGestureRecognizer = true } deinit { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index 250f353d63..e39997759f 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -2510,10 +2510,10 @@ final class PeerInfoHeaderNode: ASDisplayNode { func updateAvatarIsHidden(entry: AvatarGalleryEntry?) { if let entry = entry { self.avatarListNode.avatarContainerNode.containerNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first - self.editingContentNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first + self.editingContentNode.avatarNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first } else { self.avatarListNode.avatarContainerNode.containerNode.isHidden = false - self.editingContentNode.isHidden = false + self.editingContentNode.avatarNode.isHidden = false } self.avatarListNode.listContainerNode.updateEntryIsHidden(entry: entry) } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 91aee0591f..5c4c349eea 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -7058,6 +7058,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate return nil } } + + let tempFile = EngineTempBox.shared.tempFile(fileName: "video.mp4") let uploadInterface = LegacyLiveUploadInterface(context: context) let signal: SSignal if let url = asset as? URL, url.absoluteString.hasSuffix(".jpg"), let data = try? Data(contentsOf: url, options: [.mappedRead]), let image = UIImage(data: data), let entityRenderer = entityRenderer { @@ -7073,14 +7075,13 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate }) signal = durationSignal.map(toSignal: { duration -> SSignal in if let duration = duration as? Double { - return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, watcher: nil, entityRenderer: entityRenderer)! + return TGMediaVideoConverter.renderUIImage(image, duration: duration, adjustments: adjustments, path: tempFile.path, watcher: nil, entityRenderer: entityRenderer)! } else { return SSignal.single(nil) } }) - } else if let asset = asset as? AVAsset { - signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, watcher: uploadInterface, entityRenderer: entityRenderer)! + signal = TGMediaVideoConverter.convert(asset, adjustments: adjustments, path: tempFile.path, watcher: uploadInterface, entityRenderer: entityRenderer)! } else { signal = SSignal.complete() } @@ -7106,6 +7107,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate } account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true) subscriber.putNext(resource) + + EngineTempBox.shared.dispose(tempFile) } } subscriber.putCompletion() diff --git a/submodules/TelegramUI/Sources/StringForMessageTimestampStatus.swift b/submodules/TelegramUI/Sources/StringForMessageTimestampStatus.swift index 23b31c06be..2769155594 100644 --- a/submodules/TelegramUI/Sources/StringForMessageTimestampStatus.swift +++ b/submodules/TelegramUI/Sources/StringForMessageTimestampStatus.swift @@ -5,6 +5,7 @@ import TelegramPresentationData import TelegramUIPreferences import TelegramStringFormatting import LocalizedPeerData +import AccountContext enum MessageTimestampStatusFormat { case regular @@ -28,7 +29,7 @@ private func dateStringForDay(strings: PresentationStrings, dateTimeFormat: Pres } } -func stringForMessageTimestampStatus(accountPeerId: PeerId, message: Message, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, strings: PresentationStrings, format: MessageTimestampStatusFormat = .regular) -> String { +func stringForMessageTimestampStatus(accountPeerId: PeerId, message: Message, dateTimeFormat: PresentationDateTimeFormat, nameDisplayOrder: PresentationPersonNameOrder, strings: PresentationStrings, format: MessageTimestampStatusFormat = .regular, associatedData: ChatMessageItemAssociatedData) -> String { if let adAttribute = message.adAttribute { switch adAttribute.messageType { case .sponsored: @@ -86,6 +87,10 @@ func stringForMessageTimestampStatus(accountPeerId: PeerId, message: Message, da } } + if let subject = associatedData.subject, case .forwardedMessages = subject { + authorTitle = nil + } + if case .regular = format { if let authorTitle = authorTitle, !authorTitle.isEmpty { dateText = "\(authorTitle), \(dateText)" diff --git a/submodules/TelegramUIPreferences/Sources/MediaInputSettings.swift b/submodules/TelegramUIPreferences/Sources/MediaInputSettings.swift index b49f77ce31..85703b06da 100644 --- a/submodules/TelegramUIPreferences/Sources/MediaInputSettings.swift +++ b/submodules/TelegramUIPreferences/Sources/MediaInputSettings.swift @@ -8,7 +8,7 @@ public struct MediaInputSettings: Codable, Equatable { public let pauseMusicOnRecording: Bool public static var defaultSettings: MediaInputSettings { - return MediaInputSettings(enableRaiseToSpeak: true, pauseMusicOnRecording: false) + return MediaInputSettings(enableRaiseToSpeak: true, pauseMusicOnRecording: true) } public init(enableRaiseToSpeak: Bool, pauseMusicOnRecording: Bool) { @@ -20,14 +20,14 @@ public struct MediaInputSettings: Codable, Equatable { let container = try decoder.container(keyedBy: StringCodingKey.self) self.enableRaiseToSpeak = (try container.decode(Int32.self, forKey: "enableRaiseToSpeak")) != 0 - self.pauseMusicOnRecording = (try container.decodeIfPresent(Int32.self, forKey: "pauseMusicOnRecording") ?? 0) != 0 + self.pauseMusicOnRecording = (try container.decodeIfPresent(Int32.self, forKey: "pauseMusicOnRecording_v2") ?? 0) != 0 } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: StringCodingKey.self) try container.encode((self.enableRaiseToSpeak ? 1 : 0) as Int32, forKey: "enableRaiseToSpeak") - try container.encode((self.pauseMusicOnRecording ? 1 : 0) as Int32, forKey: "pauseMusicOnRecording") + try container.encode((self.pauseMusicOnRecording ? 1 : 0) as Int32, forKey: "pauseMusicOnRecording_v2") } public static func ==(lhs: MediaInputSettings, rhs: MediaInputSettings) -> Bool {