From cacfcac86a0b91eb2dffd2d2e36b130e24aee8c9 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sun, 26 Apr 2026 12:22:51 -0400 Subject: [PATCH] fix(journal): restore weather + events panels; hide daily-prep system msg in chat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The journal UI was over-stripped earlier — weather panel, current-conditions poll, and the upcoming-events sidebar were all dropped. Restored those (calls the new /api/journal/weather, /api/journal/weather/current, /api/journal/weather/refresh, /api/journal/weather/geocode endpoints). Also: the daily-prep system message was rendering as flat text inside ChatPanel because there's no .role-system bubble styling. Added a hideMessage guard in ChatMessage so daily-prep system messages don't render in the chat stream — they're already shown above as a structured prep card. News / RSS reactions / article-discuss are intentionally NOT in the journal (scoped out per user direction). The broader RSS infrastructure cleanup is a separate, larger task. Co-Authored-By: Claude Opus 4.7 --- frontend/src/api/client.ts | 15 +- frontend/src/components/ChatMessage.vue | 10 +- frontend/src/views/JournalView.vue | 416 +++++++++++++------ src/fabledassistant/routes/journal.py | 103 ++++- src/fabledassistant/services/journal_prep.py | 10 +- 5 files changed, 405 insertions(+), 149 deletions(-) diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 7f0e0df..ba582d6 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -303,6 +303,13 @@ export function apiSSEStream( // Journal // --------------------------------------------------------------------------- +export interface JournalLocation { + label: string; + address: string; + lat?: number; + lon?: number; +} + export interface JournalConfig { prep_enabled: boolean; prep_hour: number; @@ -310,9 +317,15 @@ export interface JournalConfig { day_rollover_hour: number; morning_end_hour?: number; midday_end_hour?: number; + // Ambient-context fields (carried forward from the briefing config schema) + locations?: { home?: JournalLocation; work?: JournalLocation }; + temp_unit?: 'C' | 'F'; + use_caldav_event_locations?: boolean; + enabled?: boolean; [key: string]: unknown; } + export interface JournalConversation { id: number; title: string; @@ -410,7 +423,7 @@ export async function openArticleInChat( export async function geocodeAddress(address: string): Promise<{ lat: number; lon: number; display_name: string } | null> { try { - const r = await apiPost<{ lat: number; lon: number; label: string }>('/api/geocode', { query: address }); + const r = await apiPost<{ lat: number; lon: number; label: string }>('/api/journal/weather/geocode', { query: address }); return { lat: r.lat, lon: r.lon, display_name: r.label }; } catch { return null; diff --git a/frontend/src/components/ChatMessage.vue b/frontend/src/components/ChatMessage.vue index cec152a..2652f94 100644 --- a/frontend/src/components/ChatMessage.vue +++ b/frontend/src/components/ChatMessage.vue @@ -42,7 +42,13 @@ function formatMs(ms: number | null | undefined): string { } const metadata = computed(() => (props.message.metadata ?? {}) as Record); -void metadata; + +// Hide daily-prep system messages — they're rendered separately as a structured +// card in JournalView. Without this filter they render as a flat unstyled block +// inside the chat (no .role-system bubble styling exists). +const hideMessage = computed(() => + props.message.role === "system" && metadata.value.kind === "daily_prep" +); const timingParts = computed((): string[] => { const t = props.message.timing; @@ -60,7 +66,7 @@ const timingParts = computed((): string[] => {