add postprocess

This commit is contained in:
Shinigami92 2023-04-02 16:56:13 +02:00
parent 21db78a314
commit 8d9e59b2a6
5 changed files with 60 additions and 39 deletions

View file

@ -11,6 +11,7 @@ const {
virtualScroller = false, virtualScroller = false,
eventType = 'update', eventType = 'update',
preprocess, preprocess,
postprocess = items => items,
noEndMessage = false, noEndMessage = false,
} = defineProps<{ } = defineProps<{
paginator: Paginator<T[], O> paginator: Paginator<T[], O>
@ -19,6 +20,7 @@ const {
stream?: Promise<WsEvents> stream?: Promise<WsEvents>
eventType?: 'notification' | 'update' eventType?: 'notification' | 'update'
preprocess?: (items: (U | T)[]) => U[] preprocess?: (items: (U | T)[]) => U[]
postprocess?: (items: U[]) => U[]
noEndMessage?: boolean noEndMessage?: boolean
}>() }>()
@ -47,11 +49,18 @@ const nuxtApp = useNuxtApp()
const { items, prevItems, update, state, endAnchor, error } = usePaginator(paginator, $$(stream), eventType, preprocess) const { items, prevItems, update, state, endAnchor, error } = usePaginator(paginator, $$(stream), eventType, preprocess)
const postProcessedItems = computedWithControl(() => postprocess(items.value as U[]), () => items.value)
nuxtApp.hook('elk-logo:click', () => { nuxtApp.hook('elk-logo:click', () => {
update() update()
nuxtApp.$scrollToTop() nuxtApp.$scrollToTop()
}) })
nuxtApp.hook('elk-timeline-home-filter:change', () => {
postProcessedItems.trigger()
nuxtApp.$scrollToTop()
})
function createEntry(item: any) { function createEntry(item: any) {
items.value = [...items.value, preprocess?.([item]) ?? item] items.value = [...items.value, preprocess?.([item]) ?? item]
} }
@ -73,11 +82,11 @@ defineExpose({ createEntry, removeEntry, updateEntry })
<template> <template>
<div> <div>
<slot v-if="prevItems.length" name="updater" v-bind="{ number: prevItems.length, update }" /> <slot v-if="prevItems.length" name="updater" v-bind="{ number: prevItems.length, update }" />
<slot name="items" :items="items"> <slot name="items" :items="postProcessedItems">
<template v-if="virtualScroller"> <template v-if="virtualScroller">
<DynamicScroller <DynamicScroller
v-slot="{ item, active, index }" v-slot="{ item, active, index }"
:items="items" :items="postProcessedItems"
:min-item-size="200" :min-item-size="200"
:key-field="keyProp" :key-field="keyProp"
page-mode page-mode
@ -86,22 +95,22 @@ defineExpose({ createEntry, removeEntry, updateEntry })
:key="item[keyProp]" :key="item[keyProp]"
:item="item" :item="item"
:active="active" :active="active"
:older="items[index + 1]" :older="postProcessedItems[index + 1]"
:newer="items[index - 1]" :newer="postProcessedItems[index - 1]"
:index="index" :index="index"
:items="items" :items="postProcessedItems"
/> />
</DynamicScroller> </DynamicScroller>
</template> </template>
<template v-else> <template v-else>
<slot <slot
v-for="item, index of items" v-for="item, index of postProcessedItems"
:key="(item as any)[keyProp]" :key="(item as any)[keyProp]"
:item="item" :item="item"
:older="items[index + 1]" :older="postProcessedItems[index + 1]"
:newer="items[index - 1]" :newer="postProcessedItems[index - 1]"
:index="index" :index="index"
:items="items" :items="postProcessedItems"
/> />
</template> </template>
</slot> </slot>

View file

@ -3,14 +3,51 @@ import type { mastodon } from 'masto'
const paginator = useMastoClient().v1.timelines.listHome({ limit: 30 }) const paginator = useMastoClient().v1.timelines.listHome({ limit: 30 })
const stream = $(useStreaming(client => client.v1.stream.streamUser())) const stream = $(useStreaming(client => client.v1.stream.streamUser()))
function reorderAndFilter(items: mastodon.v1.Status[]) { function reorderAndFilter(items: mastodon.v1.Status[]) {
return reorderedTimeline(items, 'home') return reorderedTimeline(items, 'home')
} }
const homeFilter = useHomeFilter()
function clientSideFilter(items: mastodon.v1.Status[]) {
const { bot, sensitive, repost, mutual, tag } = $(homeFilter.value)
return items.filter((item) => {
if (bot && sensitive && repost && mutual && tag)
return true
if (!bot && item.account.bot)
return false
if (!sensitive && item.sensitive)
return false
if (!repost && item.reblog != null)
return false
// if (!mutual && ??)
// This would require a lookup of the user's followers
// return false
// if (!tag && ??)
// This would require a lookup of the user's tags
// return false
return true
})
}
const nuxtApp = useNuxtApp()
watch(homeFilter, () => {
nuxtApp.hooks.callHook('elk-timeline-home-filter:change')
})
</script> </script>
<template> <template>
<div> <div>
<PublishWidget draft-key="home" border="b base" /> <PublishWidget draft-key="home" border="b base" />
<TimelinePaginator v-bind="{ paginator, stream }" :preprocess="reorderAndFilter" context="home" /> <TimelinePaginator v-bind="{ paginator, stream }" :preprocess="reorderAndFilter" :postprocess="clientSideFilter" context="home" />
</div> </div>
</template> </template>

View file

@ -10,6 +10,7 @@ const { paginator, stream, account, buffer = 10 } = defineProps<{
context?: mastodon.v2.FilterContext context?: mastodon.v2.FilterContext
account?: mastodon.v1.Account account?: mastodon.v1.Account
preprocess?: (items: mastodon.v1.Status[]) => mastodon.v1.Status[] preprocess?: (items: mastodon.v1.Status[]) => mastodon.v1.Status[]
postprocess?: (items: mastodon.v1.Status[]) => mastodon.v1.Status[]
buffer?: number buffer?: number
}>() }>()
@ -22,7 +23,7 @@ const showOriginSite = $computed(() =>
</script> </script>
<template> <template>
<CommonPaginator v-bind="{ paginator, stream, preprocess, buffer }" :virtual-scroller="virtualScroller"> <CommonPaginator v-bind="{ paginator, stream, preprocess, postprocess, buffer }" :virtual-scroller="virtualScroller">
<template #updater="{ number, update }"> <template #updater="{ number, update }">
<button py-4 border="b base" flex="~ col" p-3 w-full text-primary font-bold @click="update"> <button py-4 border="b base" flex="~ col" p-3 w-full text-primary font-bold @click="update">
{{ $t('timeline.show_new_items', number, { named: { v: formatNumber(number) } }) }} {{ $t('timeline.show_new_items', number, { named: { v: formatNumber(number) } }) }}

View file

@ -14,34 +14,7 @@ function removeFilteredItems(items: mastodon.v1.Status[], context: mastodon.v1.F
const isFiltered = (item: mastodon.v1.Status) => (item.account.id === currentUser.value?.account.id) || !item.filtered?.find(isStrict) const isFiltered = (item: mastodon.v1.Status) => (item.account.id === currentUser.value?.account.id) || !item.filtered?.find(isStrict)
const isReblogFiltered = (item: mastodon.v1.Status) => !item.reblog?.filtered?.find(isStrict) const isReblogFiltered = (item: mastodon.v1.Status) => !item.reblog?.filtered?.find(isStrict)
const homeFilter = useHomeFilter() return [...items].filter(isFiltered).filter(isReblogFiltered)
const { bot, sensitive, repost, mutual, tag } = homeFilter.value
const isClientSideHomeFiltered = (item: mastodon.v1.Status) => {
if (bot && sensitive && repost && mutual && tag)
return true
if (!bot && item.account.bot)
return false
if (!sensitive && item.sensitive)
return false
if (!repost && item.reblog != null)
return false
// if (!mutual && ??)
// This would require a lookup of the user's followers
// return false
// if (!tag && ??)
// This would require a lookup of the user's tags
// return false
return true
}
return [...items].filter(isFiltered).filter(isReblogFiltered).filter(isClientSideHomeFiltered)
} }
export function reorderedTimeline(items: mastodon.v1.Status[], context: mastodon.v1.FilterContext = 'public') { export function reorderedTimeline(items: mastodon.v1.Status[], context: mastodon.v1.FilterContext = 'public') {

View file

@ -257,5 +257,6 @@ declare global {
declare module 'nuxt/dist/app' { declare module 'nuxt/dist/app' {
interface RuntimeNuxtHooks { interface RuntimeNuxtHooks {
'elk-logo:click': () => void 'elk-logo:click': () => void
'elk-timeline-home-filter:change': () => void
} }
} }