From 581f4aea79f2e8fd03ddc709d167548387ec3d39 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 21 May 2026 18:55:29 -0400 Subject: [PATCH] =?UTF-8?q?fc3e:=20posts=20Pinia=20store=20=E2=80=94=20cur?= =?UTF-8?q?sor=20scroll=20+=20filters=20+=20detail=20fetch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 (1M context) --- frontend/src/stores/posts.js | 64 ++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 frontend/src/stores/posts.js diff --git a/frontend/src/stores/posts.js b/frontend/src/stores/posts.js new file mode 100644 index 0000000..d5b18c7 --- /dev/null +++ b/frontend/src/stores/posts.js @@ -0,0 +1,64 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { useApi } from '../composables/useApi.js' + +export const usePostsStore = defineStore('posts', () => { + const api = useApi() + + const items = ref([]) + const cursor = ref(null) + const loading = ref(false) + const done = ref(false) + const error = ref(null) + const filters = ref({ artist_id: null, platform: null }) + + function _qs() { + const q = {} + if (cursor.value) q.cursor = cursor.value + if (filters.value.artist_id != null) q.artist_id = filters.value.artist_id + if (filters.value.platform) q.platform = filters.value.platform + return q + } + + function _reset() { + items.value = [] + cursor.value = null + done.value = false + error.value = null + } + + async function loadInitial(newFilters) { + filters.value = { + artist_id: newFilters?.artist_id ?? null, + platform: newFilters?.platform ?? null, + } + _reset() + await loadMore() + } + + async function loadMore() { + if (loading.value || done.value) return + loading.value = true + error.value = null + try { + const body = await api.get('/api/posts', { params: _qs() }) + items.value.push(...body.items) + cursor.value = body.next_cursor + if (body.next_cursor == null) done.value = true + } catch (e) { + error.value = e + } finally { + loading.value = false + } + } + + async function getPostFull(id) { + // Used by PostCard's "Show more" expand to fetch the full description. + return await api.get(`/api/posts/${id}`) + } + + return { + items, cursor, loading, done, error, filters, + loadInitial, loadMore, getPostFull, + } +})