diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ChatRecentWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ChatRecentWidget.svelte index bed74f264..43a1699bf 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ChatRecentWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ChatRecentWidget.svelte @@ -1,66 +1,24 @@ @@ -73,49 +31,32 @@ - {#if state === 'loading'} - - {:else if state === 'error'} - - {:else if data.length === 0} + {#if conversations.loading} +
+ {#each Array(3) as _} +
+ {/each} +
+ {:else if (conversations.value ?? []).length === 0}
-
πŸ’­
-

- {$_('dashboard.widgets.chat.empty')} -

- - Chat starten - +
πŸ’¬
+

{$_('dashboard.widgets.chat.empty')}

{:else} -
- {#each data as conversation} + diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ClockTimersWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ClockTimersWidget.svelte index bb0774d71..080655643 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ClockTimersWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ClockTimersWidget.svelte @@ -1,190 +1,99 @@
-
+

⏰ {$_('dashboard.widgets.clock.title')}

- {#if state === 'loading'} - - {:else if state === 'error'} - - {:else if timers.length === 0 && alarms.length === 0} -
-
πŸ•
-

- {$_('dashboard.widgets.clock.empty')} -

- - {$_('dashboard.widgets.clock.open')} - + {#if alarms.loading && timers.loading} +
+ {#each Array(3) as _} +
+ {/each}
{:else} - - {#if stats && stats.pomodorosToday > 0} -
-
- πŸ… - {stats.pomodorosToday} - Pomodoros -
-
- ⏱️ - {stats.focusTimeToday} - min -
-
- {/if} - - - {#if timers.length > 0} -
-
- {$_('dashboard.widgets.clock.active_timers')} -
-
- {#each timers as timer} -
-
- {#if timer.isRunning} - - - - - {:else} - - {/if} - {timer.name || 'Timer'} -
- - {formatTime(timer.remaining)} - -
- {/each} -
+ + {#if (timers.value ?? []).length > 0} +
+ {#each timers.value ?? [] as timer (timer.id)} +
+ {timer.label || 'Timer'} + + {formatRemaining(timer.remainingSeconds)} + +
+ {/each}
{/if} - {#if alarms.length > 0} -
-
- {$_('dashboard.widgets.clock.alarms')} -
-
- {#each alarms as alarm} -
-
-
{alarm.time}
-
- {alarm.name || formatAlarmDays(alarm.days)} -
-
-
πŸ””
+ {#if (alarms.value ?? []).length > 0} +
+ {#each (alarms.value ?? []).slice(0, 3) as alarm (alarm.id)} +
+
+ {alarm.time} + {#if alarm.label} + {alarm.label} + {/if}
- {/each} -
+ + {formatRepeatDays(alarm.repeatDays)} + +
+ {/each}
{/if} - + {#if (alarms.value ?? []).length === 0 && (timers.value ?? []).length === 0} +
+
⏰
+

{$_('dashboard.widgets.clock.empty')}

+
+ {/if} + + + Uhr ΓΆffnen β†’ + {/if}
diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ContextDocsWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ContextDocsWidget.svelte index 5fdd3ac3a..ebe76619b 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ContextDocsWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ContextDocsWidget.svelte @@ -1,162 +1,75 @@
-
+

- 🧠 + πŸ“ {$_('dashboard.widgets.context.title')}

- {#if spaces.length > 0} - - {spaces.length} Spaces - - {/if}
- {#if state === 'loading'} - - {:else if state === 'error'} - - {:else if documents.length === 0 && spaces.length === 0} + {#if docs.loading} +
+ {#each Array(3) as _} +
+ {/each} +
+ {:else if (docs.value ?? []).length === 0}
-
πŸ“š
-

- {$_('dashboard.widgets.context.empty')} -

- - Space erstellen - +
πŸ“
+

{$_('dashboard.widgets.context.empty')}

{:else} - - {#if documents.length > 0} - - {:else} - - - {/if} - - diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ManadeckProgressWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ManadeckProgressWidget.svelte index f1d3c96b9..e1dd47fa3 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ManadeckProgressWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ManadeckProgressWidget.svelte @@ -1,161 +1,61 @@
-
+

🎴 {$_('dashboard.widgets.manadeck.title')}

- {#if state === 'loading'} - - {:else if state === 'error'} - - {:else if !progress || decks.length === 0} -
-
πŸ“š
-

- {$_('dashboard.widgets.manadeck.empty')} -

+ {#if progress.loading} +
+ {#each Array(3) as _} +
+ {/each} +
+ {:else} +
+
+
{progress.value.totalCards}
+
Karten
+
+
+
{progress.value.cardsLearned}
+
Gelernt
+
+
+
{progress.value.totalDecks}
+
Decks
+
+
+
{progress.value.dueForReview}
+
FΓ€llig
+
+
+ + {#if progress.value.dueForReview > 0} - {$_('dashboard.widgets.manadeck.create_deck')} + {progress.value.dueForReview} Karten wiederholen β†’ -
- {:else} - -
-
-
{progress.streakDays}
-
{$_('dashboard.widgets.manadeck.streak')}
-
-
-
{totalDue}
-
{$_('dashboard.widgets.manadeck.due')}
-
-
-
{progress.reviewsToday}
-
{$_('dashboard.widgets.manadeck.today')}
-
-
- - -
-
- {$_('dashboard.widgets.manadeck.learned')} - {progressPercent}% -
-
-
-
-
- - - {#if decksWithDue.length > 0} - - {/if} - - {#if totalDue > 0} - {/if} {/if}
diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/MukkeLibraryWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/MukkeLibraryWidget.svelte index bfc327b4f..2dd662460 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/MukkeLibraryWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/MukkeLibraryWidget.svelte @@ -1,107 +1,55 @@
-
+

🎡 {$_('dashboard.widgets.mukke.title')}

- {#if state === 'loading'} - - {:else if state === 'error'} - - {:else if !stats || stats.totalSongs === 0} -
-
🎢
-

- {$_('dashboard.widgets.mukke.empty')} -

- - Musik entdecken - + {#if stats.loading} +
+ {#each Array(3) as _} +
+ {/each}
{:else} - -
-
-
{stats.totalSongs}
-
Songs
+
+
+ {stats.value.totalSongs} + Songs
-
-
{stats.totalPlaylists}
-
Playlists
+
+ {stats.value.totalPlaylists} + Playlists
-
-
{stats.favoriteCount}
-
Favoriten
+
+ {stats.value.favoriteCount} + ⭐
- - {#if recentSongs.length > 0} + {#if stats.value.recentSongs.length > 0}
- {#each recentSongs as song} -
- {song.favorite ? '❀️' : '🎡'} + {#each stats.value.recentSongs as song (song.id)} +
+ 🎡

{song.title}

{#if song.artist} @@ -110,7 +58,7 @@
{#if song.duration} - {mukkeService.formatDuration(song.duration)} + {formatDuration(song.duration)} {/if}
@@ -118,15 +66,6 @@
{/if} - +

Mukke

{/if}
diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/PictureRecentWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/PictureRecentWidget.svelte index 78e17e1bd..65607cfa2 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/PictureRecentWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/PictureRecentWidget.svelte @@ -1,73 +1,16 @@
@@ -78,59 +21,37 @@
- {#if state === 'loading'} - - {:else if state === 'error'} - - {:else if data.length === 0} + {#if images.loading} +
+ {#each Array(6) as _} +
+ {/each} +
+ {:else if (images.value ?? []).length === 0}
-
πŸ–ΌοΈ
-

- {$_('dashboard.widgets.picture.empty')} -

- - {$_('dashboard.widgets.picture.create')} - +
🎨
+

{$_('dashboard.widgets.picture.empty')}

{:else} - {/if}
diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/PresiDecksWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/PresiDecksWidget.svelte index 7ca3842b0..2b614bc06 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/PresiDecksWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/PresiDecksWidget.svelte @@ -1,107 +1,53 @@
-
+

πŸ“Š {$_('dashboard.widgets.presi.title')}

- {#if decks.length > 0} - - {decks.length} - - {/if}
- {#if state === 'loading'} - - {:else if state === 'error'} - - {:else if decks.length === 0} + {#if decks.loading} +
+ {#each Array(3) as _} +
+ {/each} +
+ {:else if (decks.value ?? []).length === 0}
-
🎨
-

- {$_('dashboard.widgets.presi.empty')} -

- - PrΓ€sentation erstellen - +
πŸ“Š
+

{$_('dashboard.widgets.presi.empty')}

{:else} - - {/if}
diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/StorageUsageWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/StorageUsageWidget.svelte index feba5e29b..c284255c7 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/StorageUsageWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/StorageUsageWidget.svelte @@ -1,115 +1,83 @@
-

- πŸ’Ύ - {$_('dashboard.widgets.storage.title')} -

+
+

+ πŸ’Ύ + {$_('dashboard.widgets.storage.title')} +

+
- {#if state === 'loading'} - - {:else if state === 'error'} - - {:else if data} -
- -
-
-

{$_('dashboard.widgets.storage.total_size')}

-

{formatSize(data.totalSize)}

-
-
-

{$_('dashboard.widgets.storage.files')}

-

{data.totalFiles}

-
-
- - - {#if data.recentFiles && data.recentFiles.length > 0} -
-

- {$_('dashboard.widgets.storage.recent')} -

-
    - {#each data.recentFiles.slice(0, 3) as file} -
  • - {getFileIcon(file.mimeType)} - {file.name} - {formatSize(file.size)} -
  • - {/each} -
-
- {:else} -

{$_('dashboard.widgets.storage.empty')}

- {/if} - - - {$_('dashboard.widgets.storage.open')} - + {#if stats.loading} +
+ {#each Array(3) as _} +
+ {/each}
+ {:else} +
+
+ {stats.value.totalFiles} + Dateien +
+
+ {formatSize(stats.value.totalSize)} + gesamt +
+
+ + {#if stats.value.recentFiles.length > 0} +
+ {#each stats.value.recentFiles as file (file.id)} +
+ {getFileIcon(file.mimeType)} + {file.name} + + {formatSize(file.size || 0)} + +
+ {/each} +
+ {/if} + + + Storage ΓΆffnen β†’ + {/if}
diff --git a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ZitareQuoteWidget.svelte b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ZitareQuoteWidget.svelte index f223f0ba5..0477f9abd 100644 --- a/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ZitareQuoteWidget.svelte +++ b/apps/manacore/apps/web/src/lib/components/dashboard/widgets/ZitareQuoteWidget.svelte @@ -1,117 +1,51 @@
-
+

- =οΏ½ + πŸ’‘ {$_('dashboard.widgets.zitare.title')}

- {#if state === 'success' && data} - - {/if}
- {#if state === 'loading'} - - {:else if state === 'error'} - - {:else if !data} + {#if favorite.loading} +
+ {:else if !favorite.value}
-
(
-

- {$_('dashboard.widgets.zitare.empty')} -

+
πŸ’‘
+

{$_('dashboard.widgets.zitare.empty')}

- {$_('dashboard.widgets.zitare.explore')} + Zitate entdecken
{:else} -
- -
-

- "{data.quoteId}" -

-
- - - - - {$_('dashboard.widgets.zitare.view_all')} οΏ½ - -
+ +

+ Favorit #{favorite.value.quoteId} +

+
{/if}
diff --git a/apps/manacore/apps/web/src/lib/data/cross-app-queries.ts b/apps/manacore/apps/web/src/lib/data/cross-app-queries.ts index 3205c919f..7d6f066e0 100644 --- a/apps/manacore/apps/web/src/lib/data/cross-app-queries.ts +++ b/apps/manacore/apps/web/src/lib/data/cross-app-queries.ts @@ -11,9 +11,35 @@ import { crossTaskCollection, crossEventCollection, crossContactCollection, + crossConversationCollection, + crossFavoriteCollection, + crossImageCollection, + crossAlarmCollection, + crossTimerCollection, + crossFileCollection, + crossSongCollection, + crossPlaylistCollection, + crossPresiDeckCollection, + crossSpaceCollection, + crossDocumentCollection, + crossManadeckDeckCollection, + crossManadeckCardCollection, type CrossAppTask, type CrossAppEvent, type CrossAppContact, + type CrossAppConversation, + type CrossAppFavorite, + type CrossAppImage, + type CrossAppAlarm, + type CrossAppTimer, + type CrossAppFile, + type CrossAppSong, + type CrossAppPlaylist, + type CrossAppDeck, + type CrossAppSpace, + type CrossAppDocument, + type CrossAppManadeckDeck, + type CrossAppManadeckCard, } from './cross-app-stores'; // ─── Todo Queries ─────────────────────────────────────────── @@ -112,3 +138,170 @@ export function useFavoriteContacts(limit = 5) { return all.filter((c) => c.isFavorite && !c.isArchived && !c.deletedAt).slice(0, limit); }, [] as CrossAppContact[]); } + +// ─── Chat Queries ─────────────────────────────────────────── + +/** Recent conversations, sorted by updatedAt desc. */ +export function useRecentConversations(limit = 5) { + return useLiveQueryWithDefault(async () => { + const all = await crossConversationCollection.getAll(undefined, { + sortBy: 'updatedAt', + sortDirection: 'desc', + }); + return all.filter((c) => !c.isArchived && !c.deletedAt).slice(0, limit); + }, [] as CrossAppConversation[]); +} + +// ─── Zitare Queries ───────────────────────────────────────── + +/** A random favorite quote. */ +export function useRandomFavorite() { + return useLiveQueryWithDefault( + async () => { + const all = await crossFavoriteCollection.getAll(); + const active = all.filter((f) => !f.deletedAt); + if (active.length === 0) return null; + return active[Math.floor(Math.random() * active.length)]; + }, + null as CrossAppFavorite | null + ); +} + +// ─── Picture Queries ──────────────────────────────────────── + +/** Recent generated images. */ +export function useRecentImages(limit = 6) { + return useLiveQueryWithDefault(async () => { + const all = await crossImageCollection.getAll(undefined, { + sortBy: 'createdAt', + sortDirection: 'desc', + }); + return all.filter((i) => !i.archivedAt && !i.deletedAt).slice(0, limit); + }, [] as CrossAppImage[]); +} + +// ─── Clock Queries ────────────────────────────────────────── + +/** Enabled alarms. */ +export function useEnabledAlarms() { + return useLiveQueryWithDefault(async () => { + const all = await crossAlarmCollection.getAll(); + return all.filter((a) => a.enabled && !a.deletedAt); + }, [] as CrossAppAlarm[]); +} + +/** Active/running timers. */ +export function useActiveTimers() { + return useLiveQueryWithDefault(async () => { + const all = await crossTimerCollection.getAll(); + return all.filter((t) => (t.status === 'running' || t.status === 'paused') && !t.deletedAt); + }, [] as CrossAppTimer[]); +} + +// ─── Storage Queries ──────────────────────────────────────── + +/** Storage stats: total files and total size. */ +export function useStorageStats() { + return useLiveQueryWithDefault( + async () => { + const files = await crossFileCollection.getAll(); + const active = files.filter((f) => !f.isDeleted && !f.deletedAt); + const totalSize = active.reduce((sum, f) => sum + (f.size || 0), 0); + const recent = active + .sort((a, b) => (b.updatedAt ?? '').localeCompare(a.updatedAt ?? '')) + .slice(0, 5); + return { totalFiles: active.length, totalSize, recentFiles: recent }; + }, + { totalFiles: 0, totalSize: 0, recentFiles: [] as CrossAppFile[] } + ); +} + +// ─── Mukke Queries ────────────────────────────────────────── + +/** Mukke library stats + recent songs. */ +export function useMukkeStats() { + return useLiveQueryWithDefault( + async () => { + const songs = await crossSongCollection.getAll(); + const playlists = await crossPlaylistCollection.getAll(); + const activeSongs = songs.filter((s) => !s.deletedAt); + const activePlaylists = playlists.filter((p) => !p.deletedAt); + const recent = activeSongs + .sort((a, b) => (b.updatedAt ?? '').localeCompare(a.updatedAt ?? '')) + .slice(0, 5); + return { + totalSongs: activeSongs.length, + totalPlaylists: activePlaylists.length, + favoriteCount: activeSongs.filter((s) => s.favorite).length, + recentSongs: recent, + }; + }, + { totalSongs: 0, totalPlaylists: 0, favoriteCount: 0, recentSongs: [] as CrossAppSong[] } + ); +} + +// ─── Presi Queries ────────────────────────────────────────── + +/** Recent presentation decks. */ +export function useRecentDecks(limit = 5) { + return useLiveQueryWithDefault(async () => { + const all = await crossPresiDeckCollection.getAll(undefined, { + sortBy: 'updatedAt', + sortDirection: 'desc', + }); + return all.filter((d) => !d.deletedAt).slice(0, limit); + }, [] as CrossAppDeck[]); +} + +// ─── Context Queries ──────────────────────────────────────── + +/** Recent documents + spaces. */ +export function useRecentDocuments(limit = 5) { + return useLiveQueryWithDefault(async () => { + const all = await crossDocumentCollection.getAll(undefined, { + sortBy: 'updatedAt', + sortDirection: 'desc', + }); + return all.filter((d) => !d.deletedAt).slice(0, limit); + }, [] as CrossAppDocument[]); +} + +export function useSpaces() { + return useLiveQueryWithDefault(async () => { + const all = await crossSpaceCollection.getAll(undefined, { + sortBy: 'pinned', + sortDirection: 'desc', + }); + return all.filter((s) => !s.deletedAt); + }, [] as CrossAppSpace[]); +} + +// ─── ManaDeck Queries ─────────────────────────────────────── + +/** ManaDeck learning progress. */ +export function useManadeckProgress() { + return useLiveQueryWithDefault( + async () => { + const decks = await crossManadeckDeckCollection.getAll(); + const cards = await crossManadeckCardCollection.getAll(); + const activeDecks = decks.filter((d) => !d.deletedAt); + const activeCards = cards.filter((c) => !c.deletedAt); + const now = new Date().toISOString(); + const dueCards = activeCards.filter((c) => c.nextReview && c.nextReview <= now); + return { + totalDecks: activeDecks.length, + totalCards: activeCards.length, + cardsLearned: activeCards.filter((c) => (c.reviewCount ?? 0) > 0).length, + dueForReview: dueCards.length, + decks: activeDecks, + }; + }, + { + totalDecks: 0, + totalCards: 0, + cardsLearned: 0, + dueForReview: 0, + decks: [] as CrossAppManadeckDeck[], + } + ); +} diff --git a/apps/manacore/apps/web/src/lib/data/cross-app-stores.ts b/apps/manacore/apps/web/src/lib/data/cross-app-stores.ts index e9ad9fc74..eade3c346 100644 --- a/apps/manacore/apps/web/src/lib/data/cross-app-stores.ts +++ b/apps/manacore/apps/web/src/lib/data/cross-app-stores.ts @@ -76,6 +76,144 @@ export interface CrossAppContact extends BaseRecord { isArchived?: boolean; } +// ─── Chat Types ───────────────────────────────────────────── + +export interface CrossAppConversation extends BaseRecord { + title?: string; + modelId?: string; + isArchived?: boolean; + isPinned?: boolean; + spaceId?: string; +} + +export interface CrossAppMessage extends BaseRecord { + conversationId: string; + sender: 'user' | 'assistant' | 'system'; + messageText: string; +} + +// ─── Zitare Types ─────────────────────────────────────────── + +export interface CrossAppFavorite extends BaseRecord { + quoteId: string; +} + +// ─── Picture Types ────────────────────────────────────────── + +export interface CrossAppImage extends BaseRecord { + prompt?: string; + publicUrl?: string; + storagePath?: string; + filename?: string; + width?: number; + height?: number; + isFavorite?: boolean; + isPublic?: boolean; + archivedAt?: string | null; +} + +// ─── Clock Types ──────────────────────────────────────────── + +export interface CrossAppAlarm extends BaseRecord { + label?: string; + time: string; + enabled: boolean; + repeatDays?: number[]; +} + +export interface CrossAppTimer extends BaseRecord { + label?: string; + durationSeconds: number; + remainingSeconds: number; + status: 'idle' | 'running' | 'paused' | 'finished'; + startedAt?: string; +} + +// ─── Storage Types ────────────────────────────────────────── + +export interface CrossAppFile extends BaseRecord { + name: string; + originalName?: string; + mimeType?: string; + size?: number; + parentFolderId?: string | null; + isFavorite?: boolean; + isDeleted?: boolean; +} + +export interface CrossAppFolder extends BaseRecord { + name: string; + parentFolderId?: string | null; + path?: string; + depth?: number; + isFavorite?: boolean; + isDeleted?: boolean; +} + +// ─── Mukke Types ──────────────────────────────────────────── + +export interface CrossAppSong extends BaseRecord { + title: string; + artist?: string; + album?: string; + duration?: number; + favorite?: boolean; +} + +export interface CrossAppPlaylist extends BaseRecord { + name: string; + description?: string; +} + +// ─── Presi Types ──────────────────────────────────────────── + +export interface CrossAppDeck extends BaseRecord { + title: string; + description?: string; + isPublic?: boolean; +} + +export interface CrossAppSlide extends BaseRecord { + deckId: string; + order: number; + content?: unknown; +} + +// ─── Context Types ────────────────────────────────────────── + +export interface CrossAppSpace extends BaseRecord { + name: string; + description?: string; + pinned?: boolean; +} + +export interface CrossAppDocument extends BaseRecord { + spaceId: string; + title: string; + type?: 'text' | 'context' | 'prompt'; + pinned?: boolean; +} + +// ─── ManaDeck Types ───────────────────────────────────────── + +export interface CrossAppManadeckDeck extends BaseRecord { + name: string; + description?: string; + color?: string; + cardCount?: number; + lastStudied?: string; + isPublic?: boolean; +} + +export interface CrossAppManadeckCard extends BaseRecord { + deckId: string; + front: string; + back: string; + difficulty?: number; + nextReview?: string; + reviewCount?: number; +} + // ─── Store Instances ──────────────────────────────────────── // These open existing IndexedDB databases created by other apps. // No sync config β€” ManaCore only reads, the owning app handles sync. @@ -126,9 +264,119 @@ export const contactsReader = createLocalStore({ ], }); -// Typed collection accessors +export const chatReader = createLocalStore({ + appId: 'chat', + collections: [ + { name: 'conversations', indexes: ['isArchived', 'isPinned', 'spaceId'] }, + { name: 'messages', indexes: ['conversationId', 'sender', '[conversationId+sender]'] }, + ], +}); + +export const zitareReader = createLocalStore({ + appId: 'zitare', + collections: [{ name: 'favorites', indexes: ['quoteId'] }], +}); + +export const pictureReader = createLocalStore({ + appId: 'picture', + collections: [{ name: 'images', indexes: ['isFavorite', 'isPublic', 'archivedAt', 'prompt'] }], +}); + +export const clockReader = createLocalStore({ + appId: 'clock', + collections: [ + { name: 'alarms', indexes: ['enabled', 'time'] }, + { name: 'timers', indexes: ['status'] }, + ], +}); + +export const storageReader = createLocalStore({ + appId: 'storage', + collections: [ + { + name: 'files', + indexes: ['parentFolderId', 'mimeType', 'isFavorite', 'isDeleted', 'name'], + }, + { name: 'folders', indexes: ['parentFolderId', 'path', 'depth', 'isFavorite', 'isDeleted'] }, + ], +}); + +export const mukkeReader = createLocalStore({ + appId: 'mukke', + collections: [ + { name: 'songs', indexes: ['artist', 'album', 'genre', 'favorite', 'title'] }, + { name: 'playlists', indexes: ['name'] }, + ], +}); + +export const presiReader = createLocalStore({ + appId: 'presi', + collections: [ + { name: 'decks', indexes: ['isPublic'] }, + { name: 'slides', indexes: ['deckId', 'order', '[deckId+order]'] }, + ], +}); + +export const contextReader = createLocalStore({ + appId: 'context', + collections: [ + { name: 'spaces', indexes: ['pinned', 'prefix'] }, + { name: 'documents', indexes: ['spaceId', 'type', 'pinned', 'title', '[spaceId+type]'] }, + ], +}); + +export const manadeckReader = createLocalStore({ + appId: 'manadeck', + collections: [ + { name: 'decks', indexes: ['isPublic'] }, + { name: 'cards', indexes: ['deckId', 'difficulty', 'nextReview', 'order', '[deckId+order]'] }, + ], +}); + +// ─── Typed Collection Accessors ───────────────────────────── + +// Todo export const crossTaskCollection = todoReader.collection('tasks'); export const crossProjectCollection = todoReader.collection('projects'); + +// Calendar export const crossEventCollection = calendarReader.collection('events'); export const crossCalendarCollection = calendarReader.collection('calendars'); + +// Contacts export const crossContactCollection = contactsReader.collection('contacts'); + +// Chat +export const crossConversationCollection = + chatReader.collection('conversations'); +export const crossMessageCollection = chatReader.collection('messages'); + +// Zitare +export const crossFavoriteCollection = zitareReader.collection('favorites'); + +// Picture +export const crossImageCollection = pictureReader.collection('images'); + +// Clock +export const crossAlarmCollection = clockReader.collection('alarms'); +export const crossTimerCollection = clockReader.collection('timers'); + +// Storage +export const crossFileCollection = storageReader.collection('files'); +export const crossFolderCollection = storageReader.collection('folders'); + +// Mukke +export const crossSongCollection = mukkeReader.collection('songs'); +export const crossPlaylistCollection = mukkeReader.collection('playlists'); + +// Presi +export const crossPresiDeckCollection = presiReader.collection('decks'); +export const crossSlideCollection = presiReader.collection('slides'); + +// Context +export const crossSpaceCollection = contextReader.collection('spaces'); +export const crossDocumentCollection = contextReader.collection('documents'); + +// ManaDeck +export const crossManadeckDeckCollection = manadeckReader.collection('decks'); +export const crossManadeckCardCollection = manadeckReader.collection('cards'); diff --git a/apps/manacore/apps/web/src/routes/(app)/+layout.svelte b/apps/manacore/apps/web/src/routes/(app)/+layout.svelte index 21a205ae5..678b564d8 100644 --- a/apps/manacore/apps/web/src/routes/(app)/+layout.svelte +++ b/apps/manacore/apps/web/src/routes/(app)/+layout.svelte @@ -10,7 +10,20 @@ import type { PillNavItem, PillDropdownItem } from '@manacore/shared-ui'; import { tagLocalStore, tagMutations, useAllTags } from '$lib/stores/tags.svelte'; import { manacoreStore } from '$lib/data/local-store'; - import { todoReader, calendarReader, contactsReader } from '$lib/data/cross-app-stores'; + import { + todoReader, + calendarReader, + contactsReader, + chatReader, + zitareReader, + pictureReader, + clockReader, + storageReader, + mukkeReader, + presiReader, + contextReader, + manadeckReader, + } from '$lib/data/cross-app-stores'; import { dashboardStore } from '$lib/stores/dashboard.svelte'; import { THEME_DEFINITIONS, @@ -211,6 +224,15 @@ todoReader.initialize(), calendarReader.initialize(), contactsReader.initialize(), + chatReader.initialize(), + zitareReader.initialize(), + pictureReader.initialize(), + clockReader.initialize(), + storageReader.initialize(), + mukkeReader.initialize(), + presiReader.initialize(), + contextReader.initialize(), + manadeckReader.initialize(), ]); // Start syncing to server