From 9f1f1b49e7fbfb8875e50bef097d84023ed8ea3c Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Tue, 27 Oct 2020 07:02:47 +0400 Subject: [PATCH] Various fixes --- .../Sources/LocationViewControllerNode.swift | 4 +- .../ChatMessageAnimatedStickerItemNode.swift | 107 ++++++++++++++---- .../TelegramUI/Sources/PrefetchManager.swift | 43 +------ 3 files changed, 88 insertions(+), 66 deletions(-) diff --git a/submodules/LocationUI/Sources/LocationViewControllerNode.swift b/submodules/LocationUI/Sources/LocationViewControllerNode.swift index 0c5e13ece2..1968bfa591 100644 --- a/submodules/LocationUI/Sources/LocationViewControllerNode.swift +++ b/submodules/LocationUI/Sources/LocationViewControllerNode.swift @@ -202,7 +202,6 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan private var disposable: Disposable? private var state: LocationViewState private let statePromise: Promise - private var geocodingDisposable = MetaDisposable() private var validLayout: (layout: ContainerViewLayout, navigationHeight: CGFloat)? private var listOffset: CGFloat? @@ -271,7 +270,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan return messages } - setupProximityNotificationImpl = { reset in + setupProximityNotificationImpl = { [weak self] reset in let _ = (liveLocations |> take(1) |> deliverOnMainQueue).start(next: { [weak self] messages in @@ -540,7 +539,6 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan deinit { self.disposable?.dispose() - self.geocodingDisposable.dispose() self.locationManager.manager.stopUpdatingHeading() } diff --git a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift index 182fcddcea..89b99b10de 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAnimatedStickerItemNode.swift @@ -20,6 +20,7 @@ import Emoji import Markdown import ManagedAnimationNode import SlotMachineAnimationNode +import UniversalMediaPlayer private let nameFont = Font.medium(14.0) private let inlineBotPrefixFont = Font.regular(14.0) @@ -1229,30 +1230,54 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { let beatingHearts: [UInt32] = [0x2764, 0x1F90E, 0x1F9E1, 0x1F499, 0x1F49A, 0x1F49C, 0x1F49B, 0x1F5A4, 0x1F90D] let peach = 0x1F351 - if let text = self.item?.message.text, let firstScalar = text.unicodeScalars.first, beatingHearts.contains(firstScalar.value) || firstScalar.value == peach { - return .optionalAction({ - let _ = startTime.start(next: { [weak self] time in - guard let strongSelf = self else { - return - } - - var haptic: EmojiHaptic - if let current = strongSelf.haptic { - haptic = current - } else { - if beatingHearts.contains(firstScalar.value) { - haptic = HeartbeatHaptic() - } else { - haptic = PeachHaptic() + let appConfiguration = item.context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration]) + |> take(1) + |> map { view in + return view.values[PreferencesKeys.appConfiguration] as? AppConfiguration ?? .defaultValue + } + + if let text = self.item?.message.text, let firstScalar = text.unicodeScalars.first { + if beatingHearts.contains(firstScalar.value) || firstScalar.value == peach { + return .optionalAction({ + let _ = startTime.start(next: { [weak self] time in + guard let strongSelf = self else { + return } - haptic.enabled = true - strongSelf.haptic = haptic - } - if !haptic.active { - haptic.start(time: time) - } + + var haptic: EmojiHaptic + if let current = strongSelf.haptic { + haptic = current + } else { + if beatingHearts.contains(firstScalar.value) { + haptic = HeartbeatHaptic() + } else { + haptic = PeachHaptic() + } + haptic.enabled = true + strongSelf.haptic = haptic + } + if !haptic.active { + haptic.start(time: time) + } + }) }) - }) + } else { + return .optionalAction({ + let _ = (appConfiguration + |> deliverOnMainQueue).start(next: { [weak self] appConfiguration in + let emojiSounds = AnimatedEmojiSoundsConfiguration.with(appConfiguration: appConfiguration, account: item.context.account) + for (emoji, file) in emojiSounds.sounds { + if emoji.unicodeScalars.first == firstScalar { + let mediaManager = item.context.sharedContext.mediaManager + let mediaPlayer = MediaPlayer(audioSessionManager: mediaManager.audioSession, postbox: item.context.account.postbox, resourceReference: .standalone(resource: file.resource), streamable: .none, video: false, preferSoftwareDecoding: false, enableSound: true, fetchAutomatically: true) + mediaPlayer.togglePlayPause() + self?.mediaPlayer = mediaPlayer + break + } + } + }) + }) + } } } } @@ -1268,6 +1293,8 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { return nil } + private var mediaPlayer: MediaPlayer? + @objc private func shareButtonPressed() { if let item = self.item { if case .pinnedMessages = item.associatedData.subject { @@ -1512,3 +1539,39 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView { self.contextSourceNode.contentNode.addSubnode(accessoryItemNode) } } + +struct AnimatedEmojiSoundsConfiguration { + static var defaultValue: AnimatedEmojiSoundsConfiguration { + return AnimatedEmojiSoundsConfiguration(sounds: [:]) + } + + public let sounds: [String: TelegramMediaFile] + + fileprivate init(sounds: [String: TelegramMediaFile]) { + self.sounds = sounds + } + + static func with(appConfiguration: AppConfiguration, account: Account) -> AnimatedEmojiSoundsConfiguration { + if let data = appConfiguration.data, let values = data["emojies_sounds"] as? [String: Any] { + var sounds: [String: TelegramMediaFile] = [:] + for (key, value) in values { + if let dict = value as? [String: String], var fileReferenceString = dict["file_reference_base64"] { + fileReferenceString = fileReferenceString.replacingOccurrences(of: "-", with: "+") + fileReferenceString = fileReferenceString.replacingOccurrences(of: "_", with: "/") + while fileReferenceString.count % 4 != 0 { + fileReferenceString.append("=") + } + + if let idString = dict["id"], let id = Int64(idString), let accessHashString = dict["access_hash"], let accessHash = Int64(accessHashString), let fileReference = Data(base64Encoded: fileReferenceString) { + let resource = CloudDocumentMediaResource(datacenterId: 1, fileId: id, accessHash: accessHash, size: nil, fileReference: fileReference, fileName: nil) + let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: nil, attributes: []) + sounds[key] = file + } + } + } + return AnimatedEmojiSoundsConfiguration(sounds: sounds) + } else { + return .defaultValue + } + } +} diff --git a/submodules/TelegramUI/Sources/PrefetchManager.swift b/submodules/TelegramUI/Sources/PrefetchManager.swift index 856176a275..6c0fa0a1e7 100644 --- a/submodules/TelegramUI/Sources/PrefetchManager.swift +++ b/submodules/TelegramUI/Sources/PrefetchManager.swift @@ -20,42 +20,6 @@ public enum PrefetchMediaItem { case animatedEmojiSticker(TelegramMediaFile) } -private struct AnimatedEmojiSoundsConfiguration { - static var defaultValue: AnimatedEmojiSoundsConfiguration { - return AnimatedEmojiSoundsConfiguration(sounds: [:]) - } - - public let sounds: [String: TelegramMediaFile] - - fileprivate init(sounds: [String: TelegramMediaFile]) { - self.sounds = sounds - } - - static func with(appConfiguration: AppConfiguration) -> AnimatedEmojiSoundsConfiguration { - if let data = appConfiguration.data, let values = data["emojies_sounds"] as? [String: Any] { - var sounds: [String: TelegramMediaFile] = [:] - for (key, value) in values { - if let dict = value as? [String: String], var fileReferenceString = dict["file_reference_base64"] { - fileReferenceString = fileReferenceString.replacingOccurrences(of: "-", with: "+") - fileReferenceString = fileReferenceString.replacingOccurrences(of: "_", with: "/") - while fileReferenceString.count % 4 != 0 { - fileReferenceString.append("=") - } - - if let idString = dict["id"], let id = Int64(idString), let accessHashString = dict["access_hash"], let accessHash = Int64(accessHashString), let fileReference = Data(base64Encoded: fileReferenceString) { - let resource = CloudDocumentMediaResource(datacenterId: 0, fileId: id, accessHash: accessHash, size: nil, fileReference: fileReference, fileName: nil) - let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "audio/ogg", size: nil, attributes: []) - sounds[key] = file - } - } - } - return AnimatedEmojiSoundsConfiguration(sounds: sounds) - } else { - return .defaultValue - } - } -} - private final class PrefetchManagerImpl { private let queue: Queue private let account: Account @@ -89,12 +53,9 @@ private final class PrefetchManagerImpl { let orderedPreloadMedia = combineLatest(account.viewTracker.orderedPreloadMedia, loadedStickerPack(postbox: account.postbox, network: account.network, reference: .animatedEmoji, forceActualized: false), appConfiguration) |> map { orderedPreloadMedia, stickerPack, appConfiguration -> [PrefetchMediaItem] in - let emojiSounds = AnimatedEmojiSoundsConfiguration.with(appConfiguration: appConfiguration) + let emojiSounds = AnimatedEmojiSoundsConfiguration.with(appConfiguration: appConfiguration, account: account) let chatHistoryMediaItems = orderedPreloadMedia.map { PrefetchMediaItem.chatHistory($0) } var stickerItems: [PrefetchMediaItem] = [] - - var prefetchItems: [PrefetchMediaItem] = [] - switch stickerPack { case let .result(_, items, _): var animatedEmojiStickers: [String: StickerPackItem] = [:] @@ -113,11 +74,11 @@ private final class PrefetchManagerImpl { } } } - return stickerItems default: break } + var prefetchItems: [PrefetchMediaItem] = [] prefetchItems.append(contentsOf: chatHistoryMediaItems) prefetchItems.append(contentsOf: stickerItems) prefetchItems.append(contentsOf: emojiSounds.sounds.values.map { .animatedEmojiSticker($0) })