From 0d2ffee84129056d10b534274e7575fc44fc153b Mon Sep 17 00:00:00 2001 From: josedario87 <71241187+josedario87@users.noreply.github.com> Date: Mon, 9 Jun 2025 22:27:29 -0600 Subject: [PATCH 1/4] feat(ui): use view transitions for realtime feed --- ui/src/components/realtime/RealtimeEventCard.vue | 1 + ui/src/stores/useRealtime.js | 13 ++++++++++--- ui/src/views/RealtimeFeedView.vue | 15 +++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ui/src/components/realtime/RealtimeEventCard.vue b/ui/src/components/realtime/RealtimeEventCard.vue index be49024..9f2223c 100644 --- a/ui/src/components/realtime/RealtimeEventCard.vue +++ b/ui/src/components/realtime/RealtimeEventCard.vue @@ -114,6 +114,7 @@ const operationClass = computed(() => { .realtime-event { margin-bottom: 1rem; padding: 0.5rem; + view-transition-name: auto; } .old-card, diff --git a/ui/src/stores/useRealtime.js b/ui/src/stores/useRealtime.js index bf3f8b3..4ea171d 100644 --- a/ui/src/stores/useRealtime.js +++ b/ui/src/stores/useRealtime.js @@ -34,8 +34,15 @@ export const useRealtimeStore = defineStore('realtime', { console.log('๐Ÿ“ฆ Payload parseado:', payload); console.log('๐Ÿงช Tabla recibida:', payload.table); - // store event for feed - this.events.unshift({ ...payload, receivedAt: new Date().toISOString() }); + // store event for feed with View Transition if available + const addEvent = () => { + this.events.unshift({ ...payload, receivedAt: new Date().toISOString() }); + }; + if (document.startViewTransition) { + document.startViewTransition(addEvent); + } else { + addEvent(); + } // mark badge for module and operation if (this.badges[payload.table]) { @@ -64,7 +71,7 @@ export const useRealtimeStore = defineStore('realtime', { this._sse.onerror = () => { console.warn('SSE connection lost, reloading...'); }; - } + }, clearBadgesForTable(table) { if (this.badges[table]) { this.badges[table].INSERT = false; diff --git a/ui/src/views/RealtimeFeedView.vue b/ui/src/views/RealtimeFeedView.vue index 2392f31..072f5ef 100644 --- a/ui/src/views/RealtimeFeedView.vue +++ b/ui/src/views/RealtimeFeedView.vue @@ -79,4 +79,19 @@ onMounted(() => { .feed-list::-webkit-scrollbar { display: none; /* Chrome, Safari */ } + +:global(::view-transition-old(.realtime-event)), +:global(::view-transition-new(.realtime-event)) { + animation: slide 0.25s ease both; +} +@keyframes slide { + from { + transform: translateY(var(--view-transition-slide-y, 0)); + opacity: 0; + } + to { + transform: none; + opacity: 1; + } +} From 9ce53007418d1bd08b119595741a71414e744ec0 Mon Sep 17 00:00:00 2001 From: josedario87 <71241187+josedario87@users.noreply.github.com> Date: Tue, 10 Jun 2025 00:02:05 -0600 Subject: [PATCH 2/4] Fix feed transition keys --- ui/src/stores/useRealtime.js | 7 ++++++- ui/src/views/RealtimeFeedView.vue | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ui/src/stores/useRealtime.js b/ui/src/stores/useRealtime.js index 4ea171d..55cb36d 100644 --- a/ui/src/stores/useRealtime.js +++ b/ui/src/stores/useRealtime.js @@ -36,7 +36,12 @@ export const useRealtimeStore = defineStore('realtime', { // store event for feed with View Transition if available const addEvent = () => { - this.events.unshift({ ...payload, receivedAt: new Date().toISOString() }); + const event = { + id: crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(36) + Math.random().toString(36).slice(2), + ...payload, + receivedAt: new Date().toISOString(), + }; + this.events.unshift(event); }; if (document.startViewTransition) { document.startViewTransition(addEvent); diff --git a/ui/src/views/RealtimeFeedView.vue b/ui/src/views/RealtimeFeedView.vue index 072f5ef..aca7a60 100644 --- a/ui/src/views/RealtimeFeedView.vue +++ b/ui/src/views/RealtimeFeedView.vue @@ -23,8 +23,8 @@ onMounted(() => { style="max-height: calc(100vh - 160px); min-width: 60vw;" > From e04936c6372fd7a65ced7314570b7130f82f1b6a Mon Sep 17 00:00:00 2001 From: josedario87 <71241187+josedario87@users.noreply.github.com> Date: Tue, 10 Jun 2025 00:02:09 -0600 Subject: [PATCH 3/4] chore(debug): add logs for realtime feed --- ui/src/stores/useRealtime.js | 4 ++++ ui/src/views/RealtimeFeedView.vue | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ui/src/stores/useRealtime.js b/ui/src/stores/useRealtime.js index 55cb36d..d344046 100644 --- a/ui/src/stores/useRealtime.js +++ b/ui/src/stores/useRealtime.js @@ -41,11 +41,15 @@ export const useRealtimeStore = defineStore('realtime', { ...payload, receivedAt: new Date().toISOString(), }; + console.log('๐Ÿ”„ Adding realtime event', event); this.events.unshift(event); + console.log('๐Ÿ“Š Events in feed:', this.events.length); }; if (document.startViewTransition) { + console.log('๐ŸŽฌ Using View Transition API for new event'); document.startViewTransition(addEvent); } else { + console.log('โš ๏ธ View Transition API not supported'); addEvent(); } diff --git a/ui/src/views/RealtimeFeedView.vue b/ui/src/views/RealtimeFeedView.vue index aca7a60..e822db2 100644 --- a/ui/src/views/RealtimeFeedView.vue +++ b/ui/src/views/RealtimeFeedView.vue @@ -1,10 +1,17 @@