forked from Mirrors/elk
add postprocess
This commit is contained in:
parent
21db78a314
commit
8d9e59b2a6
5 changed files with 60 additions and 39 deletions
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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) } }) }}
|
||||||
|
|
|
@ -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') {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue