diff --git a/Signal/src/ViewControllers/ConversationView/CV/CVAudioPlayback.swift b/Signal/src/ViewControllers/ConversationView/CV/CVAudioPlayback.swift index bff12fec34..7711779ed7 100644 --- a/Signal/src/ViewControllers/ConversationView/CV/CVAudioPlayback.swift +++ b/Signal/src/ViewControllers/ConversationView/CV/CVAudioPlayback.swift @@ -114,7 +114,17 @@ public class CVAudioPlayer: NSObject { audioPlayback.setPlaybackRate(1) } audioPlayback.delegate = self + + let oldAudioPlayback = self.audioPlayback self.audioPlayback = audioPlayback + + // Let the existing player know its state has changed. + if let oldId = oldAudioPlayback?.attachmentId { + for listener in listeners.elements { + listener.audioPlayerStateDidChange(attachmentId: oldId) + } + } + return audioPlayback } diff --git a/Signal/src/ViewControllers/MessageDetailViewController.swift b/Signal/src/ViewControllers/MessageDetailViewController.swift index ee287c5a29..a667a03d54 100644 --- a/Signal/src/ViewControllers/MessageDetailViewController.swift +++ b/Signal/src/ViewControllers/MessageDetailViewController.swift @@ -246,6 +246,8 @@ class MessageDetailViewController: OWSTableViewController2 { let cellContainer = UIView() cellContainer.layoutMargins = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0) + cellContainer.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapCell))) + cellContainer.addSubview(cellView) cellView.autoPinHeightToSuperviewMargins() @@ -324,6 +326,16 @@ class MessageDetailViewController: OWSTableViewController2 { return section } + @objc private func didTapCell(_ sender: UITapGestureRecognizer) { + // For now, only allow tapping on audio cells. The full gamut of cell types + // might result in unexpected behaviors if made tappable from the detail view. + guard renderItem?.componentState.audioAttachment != nil else { + return + } + + _ = cellView.handleTap(sender: sender, componentDelegate: self) + } + private func buildSenderSection() -> OWSTableSection { guard let incomingMessage = message as? TSIncomingMessage else { owsFailDebug("Unexpected message type") @@ -764,23 +776,35 @@ extension MessageDetailViewController: DatabaseChangeDelegate { refreshContentForDatabaseUpdate() } - private func refreshContentForDatabaseUpdate() { - guard databaseUpdateTimer == nil else { return } + /// ForceImmediately should only be used based on user input, since it ignores any debouncing + /// and makes an update happen right away (killing any scheduled/debounced updates) + private func refreshContentForDatabaseUpdate(forceImmediately: Bool = false) { // Updating this view is slightly expensive and there will be tons of relevant // database updates when sending to a large group. Update latency isn't that // imporant, so we de-bounce to never update this view more than once every N seconds. - self.databaseUpdateTimer = Timer.scheduledTimer( - withTimeInterval: 2.0, - repeats: false - ) { [weak self] _ in + + let updateBlock = { [weak self] in guard let self = self else { return } - assert(self.databaseUpdateTimer != nil) self.databaseUpdateTimer?.invalidate() self.databaseUpdateTimer = nil self.refreshContent() } + if forceImmediately { + updateBlock() + return + } + + guard databaseUpdateTimer == nil else { return } + + self.databaseUpdateTimer = Timer.scheduledTimer( + withTimeInterval: 2.0, + repeats: false + ) { _ in + assert(self.databaseUpdateTimer != nil) + updateBlock() + } } private func refreshContent() { @@ -886,7 +910,7 @@ extension MessageDetailViewController: CVComponentDelegate { } func cvc_enqueueReloadWithoutCaches() { - self.refreshContentForDatabaseUpdate() + self.refreshContentForDatabaseUpdate(forceImmediately: true) } // MARK: - Body Text Items