diff options
| author | Adam Mathes <adam@adammathes.com> | 2026-02-15 18:01:57 -0800 |
|---|---|---|
| committer | Adam Mathes <adam@adammathes.com> | 2026-02-15 18:01:57 -0800 |
| commit | 50d01525ac9f67c5a3e680a3f807c204f6a1cdbd (patch) | |
| tree | 066df58d556ed8a7573f4bc8b7141a528957a3cf /frontend-vanilla/src/store.ts | |
| parent | c652ac6a2cd23ef29f48465be09c2b674783e8e9 (diff) | |
| download | neko-50d01525ac9f67c5a3e680a3f807c204f6a1cdbd.tar.gz neko-50d01525ac9f67c5a3e680a3f807c204f6a1cdbd.tar.bz2 neko-50d01525ac9f67c5a3e680a3f807c204f6a1cdbd.zip | |
Vanilla JS (v3): Implement Tags, Filters, and Infinite Scroll
Diffstat (limited to 'frontend-vanilla/src/store.ts')
| -rw-r--r-- | frontend-vanilla/src/store.ts | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/frontend-vanilla/src/store.ts b/frontend-vanilla/src/store.ts index d274c5d..c978fd2 100644 --- a/frontend-vanilla/src/store.ts +++ b/frontend-vanilla/src/store.ts @@ -1,38 +1,70 @@ -import type { Feed, Item } from './types.ts'; +import type { Feed, Item, Category } from './types.ts'; -export type StoreEvent = 'feeds-updated' | 'items-updated' | 'active-feed-updated' | 'loading-state-changed'; +export type StoreEvent = 'feeds-updated' | 'tags-updated' | 'items-updated' | 'active-feed-updated' | 'active-tag-updated' | 'loading-state-changed' | 'filter-updated'; + +export type FilterType = 'unread' | 'all' | 'starred'; export class Store extends EventTarget { feeds: Feed[] = []; + tags: Category[] = []; items: Item[] = []; activeFeedId: number | null = null; + activeTagName: string | null = null; + filter: FilterType = 'unread'; loading: boolean = false; + hasMore: boolean = true; setFeeds(feeds: Feed[]) { this.feeds = feeds; this.emit('feeds-updated'); } - setItems(items: Item[]) { - this.items = items; + setTags(tags: Category[]) { + this.tags = tags; + this.emit('tags-updated'); + } + + setItems(items: Item[], append: boolean = false) { + if (append) { + this.items = [...this.items, ...items]; + } else { + this.items = items; + } this.emit('items-updated'); } setActiveFeed(id: number | null) { this.activeFeedId = id; + this.activeTagName = null; this.emit('active-feed-updated'); } + setActiveTag(name: string | null) { + this.activeTagName = name; + this.activeFeedId = null; + this.emit('active-tag-updated'); + } + + setFilter(filter: FilterType) { + if (this.filter !== filter) { + this.filter = filter; + this.emit('filter-updated'); + } + } + setLoading(loading: boolean) { this.loading = loading; this.emit('loading-state-changed'); } + setHasMore(hasMore: boolean) { + this.hasMore = hasMore; + } + private emit(type: StoreEvent, detail?: any) { this.dispatchEvent(new CustomEvent(type, { detail })); } - // Helper to add typed listeners on(type: StoreEvent, callback: (e: CustomEvent) => void) { this.addEventListener(type, callback as EventListener); } |
