import type { LysandClient } from "@lysand-org/client"; import type { Status } from "~/types/mastodon/status"; export const useLocalTimeline = ( client: LysandClient | null, options: MaybeRef< Partial<{ only_media: boolean; max_id: string; since_id: string; min_id: string; limit: number; }> >, ): { timeline: Ref; loadNext: () => Promise; loadPrev: () => Promise; } => { if (!client) { return { timeline: ref([]), loadNext: async () => {}, loadPrev: async () => {}, }; } const fetchedNotes = ref([]); const fetchedNoteIds = new Set(); let nextMaxId: string | undefined = undefined; let prevMinId: string | undefined = undefined; const loadNext = async () => { const response = await client.getLocalTimeline({ ...ref(options).value, max_id: nextMaxId, limit: useConfig().NOTES_PER_PAGE, }); const newNotes = response.data.filter( (note) => !fetchedNoteIds.has(note.id), ); if (newNotes.length > 0) { fetchedNotes.value = [...fetchedNotes.value, ...newNotes]; nextMaxId = newNotes[newNotes.length - 1].id; for (const note of newNotes) { fetchedNoteIds.add(note.id); } } else { nextMaxId = undefined; } }; const loadPrev = async () => { const response = await client.getLocalTimeline({ ...ref(options).value, min_id: prevMinId, limit: useConfig().NOTES_PER_PAGE, }); const newNotes = response.data.filter( (note) => !fetchedNoteIds.has(note.id), ); if (newNotes.length > 0) { fetchedNotes.value = [...newNotes, ...fetchedNotes.value]; prevMinId = newNotes[0].id; for (const note of newNotes) { fetchedNoteIds.add(note.id); } } else { prevMinId = undefined; } }; watch( () => ref(options).value, async ({ max_id, min_id }) => { nextMaxId = max_id; prevMinId = min_id; await loadNext(); }, { immediate: true }, ); return { timeline: fetchedNotes, loadNext, loadPrev }; };