fix: WebSocket reconnect state refresh, listener leak fixes, pin container images
- F4: Fetch fresh server state after WebSocket reconnect - F5: Guard message polling timer with auth check, stop on logout - F6: Remove NIP-07 listener in appLauncher close() - F7: Initialize audio player once to prevent listener stacking - S3: Pin all container images to specific versions, create image-versions.sh Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,46 +7,52 @@ const playing = ref(false)
|
||||
const currentTime = ref(0)
|
||||
const duration = ref(0)
|
||||
const error = ref<string | null>(null)
|
||||
let initialized = false
|
||||
|
||||
/** Create the Audio element and attach listeners once */
|
||||
function init() {
|
||||
if (initialized) return
|
||||
initialized = true
|
||||
audio.value = new Audio()
|
||||
audio.value.addEventListener('timeupdate', () => {
|
||||
currentTime.value = audio.value?.currentTime ?? 0
|
||||
})
|
||||
audio.value.addEventListener('loadedmetadata', () => {
|
||||
duration.value = audio.value?.duration ?? 0
|
||||
error.value = null
|
||||
})
|
||||
audio.value.addEventListener('ended', () => {
|
||||
playing.value = false
|
||||
})
|
||||
audio.value.addEventListener('pause', () => {
|
||||
playing.value = false
|
||||
})
|
||||
audio.value.addEventListener('play', () => {
|
||||
playing.value = true
|
||||
error.value = null
|
||||
})
|
||||
audio.value.addEventListener('error', () => {
|
||||
playing.value = false
|
||||
error.value = 'Could not play audio. File Browser may not be running.'
|
||||
})
|
||||
}
|
||||
|
||||
function play(src: string, name: string) {
|
||||
if (!audio.value) {
|
||||
audio.value = new Audio()
|
||||
audio.value.addEventListener('timeupdate', () => {
|
||||
currentTime.value = audio.value?.currentTime ?? 0
|
||||
})
|
||||
audio.value.addEventListener('loadedmetadata', () => {
|
||||
duration.value = audio.value?.duration ?? 0
|
||||
error.value = null
|
||||
})
|
||||
audio.value.addEventListener('ended', () => {
|
||||
playing.value = false
|
||||
})
|
||||
audio.value.addEventListener('pause', () => {
|
||||
playing.value = false
|
||||
})
|
||||
audio.value.addEventListener('play', () => {
|
||||
playing.value = true
|
||||
error.value = null
|
||||
})
|
||||
audio.value.addEventListener('error', () => {
|
||||
playing.value = false
|
||||
error.value = 'Could not play audio. File Browser may not be running.'
|
||||
})
|
||||
}
|
||||
init()
|
||||
error.value = null
|
||||
|
||||
if (currentSrc.value === src && playing.value) {
|
||||
audio.value.pause()
|
||||
audio.value!.pause()
|
||||
return
|
||||
}
|
||||
|
||||
if (currentSrc.value !== src) {
|
||||
audio.value.src = src
|
||||
audio.value!.src = src
|
||||
currentSrc.value = src
|
||||
currentName.value = name
|
||||
}
|
||||
|
||||
audio.value.play()
|
||||
audio.value!.play()
|
||||
}
|
||||
|
||||
function pause() {
|
||||
|
||||
@@ -54,10 +54,21 @@ export function useMessageToast() {
|
||||
}
|
||||
}
|
||||
|
||||
function isAuthenticated(): boolean {
|
||||
return localStorage.getItem('neode-auth') === 'true'
|
||||
}
|
||||
|
||||
function startPolling() {
|
||||
if (pollTimer) return
|
||||
if (!isAuthenticated()) return
|
||||
loadReceivedMessages()
|
||||
pollTimer = setInterval(loadReceivedMessages, MESSAGE_POLL_INTERVAL)
|
||||
pollTimer = setInterval(() => {
|
||||
if (!isAuthenticated()) {
|
||||
stopPolling()
|
||||
return
|
||||
}
|
||||
loadReceivedMessages()
|
||||
}, MESSAGE_POLL_INTERVAL)
|
||||
}
|
||||
|
||||
function stopPolling() {
|
||||
|
||||
Reference in New Issue
Block a user