feat: Web-GUI Live-Refresh via SSE
FilesView abonniert beim Mount die SSE-Events des Backends. Lock/ Unlock, Create, Update oder Delete durch andere Clients loest einen debounced Reload der aktuellen Ordner-Ansicht aus. EventSource reconnected automatisch; wird beim Unmount sauber geschlossen. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b33e66cad9
commit
28fb1c47c2
|
|
@ -241,7 +241,7 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onMounted } from 'vue'
|
||||
import { ref, watch, onMounted, onUnmounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useAuthStore } from '../stores/auth'
|
||||
import { useFilesStore } from '../stores/files'
|
||||
|
|
@ -718,8 +718,39 @@ watch(() => route.params.folderId, () => {
|
|||
filesStore.loadFiles(currentParentId())
|
||||
})
|
||||
|
||||
// Live updates: subscribe to server-sent events so that lock changes /
|
||||
// uploads / deletions by other users or clients refresh the current
|
||||
// folder automatically.
|
||||
let eventSource = null
|
||||
let reloadDebounce = null
|
||||
|
||||
function scheduleReload() {
|
||||
if (reloadDebounce) return
|
||||
reloadDebounce = setTimeout(() => {
|
||||
reloadDebounce = null
|
||||
filesStore.loadFiles(currentParentId())
|
||||
}, 300)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
filesStore.loadFiles(currentParentId())
|
||||
|
||||
if (auth.accessToken) {
|
||||
const url = `/api/sync/events?token=${encodeURIComponent(auth.accessToken)}`
|
||||
try {
|
||||
eventSource = new EventSource(url)
|
||||
// Lock/unlock/create/update/delete all warrant a refresh of the list
|
||||
const handler = () => scheduleReload()
|
||||
eventSource.addEventListener('file', handler)
|
||||
eventSource.addEventListener('message', handler)
|
||||
eventSource.onerror = () => { /* browser auto-reconnects */ }
|
||||
} catch { /* SSE not available - fall back to manual refresh */ }
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (reloadDebounce) { clearTimeout(reloadDebounce); reloadDebounce = null }
|
||||
if (eventSource) { eventSource.close(); eventSource = null }
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue