mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 22:25:20 +00:00
Fix UI freeze when receiving voice notes
Problem: AVAudioPlayer initialization in VoiceNotePlaybackController.init() was running synchronously on main thread during view creation, blocking UI for 50-200ms per voice note. Solution: - Remove eager preparePlayer() call from init - Load duration asynchronously on background queue - Player is only prepared when playback is actually requested via ensurePlayerReady() This prevents UI freezes when voice notes appear in the chat.
This commit is contained in:
@@ -16,7 +16,23 @@ final class VoiceNotePlaybackController: NSObject, ObservableObject, AVAudioPlay
|
|||||||
init(url: URL) {
|
init(url: URL) {
|
||||||
self.url = url
|
self.url = url
|
||||||
super.init()
|
super.init()
|
||||||
preparePlayer(for: url)
|
// Load duration asynchronously to avoid blocking main thread
|
||||||
|
loadDurationAsync()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func loadDurationAsync() {
|
||||||
|
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
do {
|
||||||
|
let player = try AVAudioPlayer(contentsOf: self.url)
|
||||||
|
let duration = player.duration
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.duration = duration
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
SecureLogger.error("Failed to load audio duration for \(self.url.lastPathComponent): \(error)", category: .session)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@@ -27,7 +43,8 @@ final class VoiceNotePlaybackController: NSObject, ObservableObject, AVAudioPlay
|
|||||||
guard url != self.url else { return }
|
guard url != self.url else { return }
|
||||||
stop()
|
stop()
|
||||||
self.url = url
|
self.url = url
|
||||||
preparePlayer(for: url)
|
player = nil
|
||||||
|
loadDurationAsync()
|
||||||
}
|
}
|
||||||
|
|
||||||
func togglePlayback() {
|
func togglePlayback() {
|
||||||
@@ -83,6 +100,7 @@ final class VoiceNotePlaybackController: NSObject, ObservableObject, AVAudioPlay
|
|||||||
// MARK: - Private Helpers
|
// MARK: - Private Helpers
|
||||||
|
|
||||||
private func preparePlayer(for url: URL) {
|
private func preparePlayer(for url: URL) {
|
||||||
|
// Prepare player synchronously (only called when playback is requested)
|
||||||
do {
|
do {
|
||||||
let player = try AVAudioPlayer(contentsOf: url)
|
let player = try AVAudioPlayer(contentsOf: url)
|
||||||
player.delegate = self
|
player.delegate = self
|
||||||
|
|||||||
+23406
-23372
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user