feat: use POST /notes/feed for following tab with server-side DID filtering
This commit is contained in:
55
src/hooks/useFollowingNoteList.hook.ts
Normal file
55
src/hooks/useFollowingNoteList.hook.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { Author, getAuthors } from "@/modules/atproto/getAuthor"
|
||||||
|
import { PublicNoteListItem } from "@/modules/note/models/Note"
|
||||||
|
import { computedAsync } from "@vueuse/core"
|
||||||
|
import { computed, ref, Ref, watch } from "vue"
|
||||||
|
|
||||||
|
export function useFollowingNoteList(dids: Ref<Set<string>>) {
|
||||||
|
const isLoading = ref(false)
|
||||||
|
const notes = ref<PublicNoteListItem[]>([])
|
||||||
|
const cursor = ref<string | null | undefined>(null)
|
||||||
|
const canLoadMore = computed(() => dids.value.size > 0 && cursor.value !== undefined)
|
||||||
|
|
||||||
|
const onLoadMore = async () => {
|
||||||
|
if (isLoading.value) return
|
||||||
|
if (dids.value.size === 0) return
|
||||||
|
|
||||||
|
isLoading.value = true
|
||||||
|
|
||||||
|
const body: { dids: string[]; limit: number; cursor?: string } = {
|
||||||
|
dids: [...dids.value],
|
||||||
|
limit: 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor.value) {
|
||||||
|
body.cursor = cursor.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch("https://api.litenote.li212.fr/notes/feed", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
})
|
||||||
|
|
||||||
|
const data: { notes: PublicNoteListItem[]; cursor?: string } = await response.json()
|
||||||
|
|
||||||
|
notes.value.push(...data.notes)
|
||||||
|
cursor.value = data.cursor
|
||||||
|
isLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(dids, (newDids) => {
|
||||||
|
if (newDids.size > 0 && notes.value.length === 0) {
|
||||||
|
onLoadMore()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const authors = computedAsync<Map<string, Author>>(async () => {
|
||||||
|
if (notes.value.length === 0) return new Map()
|
||||||
|
return getAuthors(new Set(notes.value.map((n) => n.did)))
|
||||||
|
}, new Map())
|
||||||
|
|
||||||
|
const getAuthor = (did: string) =>
|
||||||
|
authors.value.has(did) ? authors.value.get(did)!.handle : ""
|
||||||
|
|
||||||
|
return { notes, isLoading, canLoadMore, onLoadMore, getAuthor }
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ import { computed, ref, Ref } from "vue"
|
|||||||
|
|
||||||
interface UsePublicNoteListOptions {
|
interface UsePublicNoteListOptions {
|
||||||
did?: Ref<string | undefined>
|
did?: Ref<string | undefined>
|
||||||
followsFilter?: Ref<Set<string>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function usePublicNoteList(options?: UsePublicNoteListOptions) {
|
export function usePublicNoteList(options?: UsePublicNoteListOptions) {
|
||||||
@@ -45,14 +44,8 @@ export function usePublicNoteList(options?: UsePublicNoteListOptions) {
|
|||||||
const getAuthor = (did: string) =>
|
const getAuthor = (did: string) =>
|
||||||
authors.value.has(did) ? authors.value.get(did)!.handle : ""
|
authors.value.has(did) ? authors.value.get(did)!.handle : ""
|
||||||
|
|
||||||
const filteredNotes = computed(() => {
|
|
||||||
const filter = options?.followsFilter?.value
|
|
||||||
if (!filter || filter.size === 0) return notes.value
|
|
||||||
return notes.value.filter((n) => filter.has(n.did))
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
notes: filteredNotes,
|
notes,
|
||||||
isLoading,
|
isLoading,
|
||||||
canLoadMore,
|
canLoadMore,
|
||||||
onLoadMore,
|
onLoadMore,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import PublicNoteList from "@/components/PublicNoteList.vue"
|
|||||||
import SignInAtproto from "@/components/SignInAtproto.vue"
|
import SignInAtproto from "@/components/SignInAtproto.vue"
|
||||||
import { useATProtoLogin } from "@/hooks/useATProtoLogin.hook"
|
import { useATProtoLogin } from "@/hooks/useATProtoLogin.hook"
|
||||||
import { useFollows } from "@/hooks/useFollows.hook"
|
import { useFollows } from "@/hooks/useFollows.hook"
|
||||||
|
import { useFollowingNoteList } from "@/hooks/useFollowingNoteList.hook"
|
||||||
import { usePublicNoteList } from "@/hooks/usePublicNoteList.hook"
|
import { usePublicNoteList } from "@/hooks/usePublicNoteList.hook"
|
||||||
import { computed } from "vue"
|
import { computed } from "vue"
|
||||||
import { useRoute, useRouter } from "vue-router"
|
import { useRoute, useRouter } from "vue-router"
|
||||||
@@ -23,7 +24,7 @@ const tab = computed<"all" | "following">({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const all = usePublicNoteList()
|
const all = usePublicNoteList()
|
||||||
const following = usePublicNoteList({ followsFilter: follows })
|
const following = useFollowingNoteList(follows)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
Reference in New Issue
Block a user