From 83db9f0c388087cbb73e0aa60312898fb86d9acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90?= Date: Mon, 9 Jan 2023 20:23:15 +0800 Subject: [PATCH 1/9] fix: group follow notification append current group before push a single item --- components/common/CommonPaginator.vue | 14 ++-- .../notification/NotificationPaginator.vue | 69 ++++++++----------- composables/paginator.ts | 4 +- types/index.ts | 2 +- 4 files changed, 37 insertions(+), 52 deletions(-) diff --git a/components/common/CommonPaginator.vue b/components/common/CommonPaginator.vue index 2cd07162..9e40c706 100644 --- a/components/common/CommonPaginator.vue +++ b/components/common/CommonPaginator.vue @@ -1,4 +1,4 @@ - @@ -143,12 +128,12 @@ const { formatNumber } = useHumanReadableNumber() /> diff --git a/composables/paginator.ts b/composables/paginator.ts index debdd563..3e78f0b9 100644 --- a/composables/paginator.ts +++ b/composables/paginator.ts @@ -1,11 +1,11 @@ import type { Paginator, WsEvents } from 'masto' import type { PaginatorState } from '~/types' -export function usePaginator( +export function usePaginator( paginator: Paginator, stream?: Promise, eventType: 'notification' | 'update' = 'update', - preprocess: (items: T[]) => T[] = (items: T[]) => items, + preprocess: (items: T[]) => U[] = (items: T[]) => items as unknown as U[], buffer = 10, ) { const state = ref(isMastoInitialised.value ? 'idle' : 'loading') diff --git a/types/index.ts b/types/index.ts index 2320951f..42e044d8 100644 --- a/types/index.ts +++ b/types/index.ts @@ -29,7 +29,7 @@ export type PaginatorState = 'idle' | 'loading' | 'done' | 'error' export interface GroupedNotifications { id: string - type: Exclude + type: 'grouped-follow' items: mastodon.v1.Notification[] } From 2de0974d6b3c737a2dbad0c6ce95e2eb3d668d47 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 9 Jan 2023 13:23:43 +0100 Subject: [PATCH 2/9] fix: nitro patch --- patches/nitropack@1.0.0.patch | 16 ++++++++-------- pnpm-lock.yaml | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/patches/nitropack@1.0.0.patch b/patches/nitropack@1.0.0.patch index 0f6e4501..3958fcf3 100644 --- a/patches/nitropack@1.0.0.patch +++ b/patches/nitropack@1.0.0.patch @@ -1,13 +1,13 @@ diff --git a/dist/shared/nitro.c8278d90.mjs b/dist/shared/nitro.c8278d90.mjs -index 9ba312fc248da3731720ee7e3b38ba2a85537657..3cd508f0720adb959d94e40c124382ec0110d92c 100644 +index 9ba312fc248da3731720ee7e3b38ba2a85537657..5ec9f06ccf60259820586715d73d41466daa8cff 100644 --- a/dist/shared/nitro.c8278d90.mjs +++ b/dist/shared/nitro.c8278d90.mjs -@@ -1298,7 +1298,7 @@ async function copyPublicAssets(nitro) { +@@ -1296,7 +1296,7 @@ async function copyPublicAssets(nitro) { + if (nitro.options.noPublicDir) { + return; } - for (const asset of nitro.options.publicAssets) { +- for (const asset of nitro.options.publicAssets) { ++ for (const asset of [...nitro.options.publicAssets].reverse()) { if (await isDirectory(asset.dir)) { -- await fse.copy(asset.dir, join(nitro.options.output.publicDir, asset.baseURL)); -+ await fse.copy(asset.dir, join(nitro.options.output.publicDir, asset.baseURL), { override: false }); - } - } - if (nitro.options.compressPublicAssets) { \ No newline at end of file + await fse.copy(asset.dir, join(nitro.options.output.publicDir, asset.baseURL)); + } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 74754348..1c60a0b5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,7 @@ patchedDependencies: hash: afe7v34zn4lohdq7767l3tlrje path: patches/mlly@1.0.0.patch nitropack@1.0.0: - hash: 5rbw6wsrpkguwhgdzu2jwggidq + hash: k66pyfgyevhmomc3yledfrjhru path: patches/nitropack@1.0.0.patch importers: @@ -8581,7 +8581,7 @@ packages: - utf-8-validate dev: true - /nitropack/1.0.0_5rbw6wsrpkguwhgdzu2jwggidq: + /nitropack/1.0.0_k66pyfgyevhmomc3yledfrjhru: resolution: {integrity: sha512-788lHgNgC+NKqecwFgMkAQTuTXwuh2hEgOk2sLwV3qPVUogxrl6P3m5eKdt6Mtzx+mlXIw0G/P90B5TNWEqDSQ==} engines: {node: ^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0} hasBin: true @@ -8911,7 +8911,7 @@ packages: knitwork: 1.0.0 magic-string: 0.26.7 mlly: 1.0.0_afe7v34zn4lohdq7767l3tlrje - nitropack: 1.0.0_5rbw6wsrpkguwhgdzu2jwggidq + nitropack: 1.0.0_k66pyfgyevhmomc3yledfrjhru nuxi: 3.0.0 ofetch: 1.0.0 ohash: 1.0.0 From 675a14db802e2734ff22378ada642395a3db0fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?= Date: Mon, 9 Jan 2023 21:22:19 +0800 Subject: [PATCH 3/9] fix: replace a tag with NuxtLink (#906) --- .eslintrc | 8 +++++++- components/account/AccountBigCard.vue | 8 ++++---- components/help/HelpPreview.vue | 8 ++++---- components/nav/NavFooter.vue | 12 +++++++++--- components/status/StatusCard.vue | 4 ++-- components/status/StatusPreviewCard.vue | 1 + components/status/StatusPreviewGitHub.vue | 12 ++++++------ components/timeline/TimelinePaginator.vue | 6 +++--- components/user/UserSignIn.vue | 2 +- 9 files changed, 37 insertions(+), 24 deletions(-) diff --git a/.eslintrc b/.eslintrc index 9bb598a2..f56d6544 100644 --- a/.eslintrc +++ b/.eslintrc @@ -8,5 +8,11 @@ "jsonc/sort-keys": "error" } } - ] + ], + "rules": { + "vue/no-restricted-syntax":["error", { + "selector": "VElement[name='a']", + "message": "Use NuxtLink instead." + }] + } } diff --git a/components/account/AccountBigCard.vue b/components/account/AccountBigCard.vue index 1abab8ce..7116d9fe 100644 --- a/components/account/AccountBigCard.vue +++ b/components/account/AccountBigCard.vue @@ -28,9 +28,9 @@ defineOptions({
- + - +
@@ -46,9 +46,9 @@ defineOptions({
- +
diff --git a/components/help/HelpPreview.vue b/components/help/HelpPreview.vue index b7d31232..c412537c 100644 --- a/components/help/HelpPreview.vue +++ b/components/help/HelpPreview.vue @@ -23,17 +23,17 @@ const emit = defineEmits<{

{{ $t('help.desc_para4') }} - + {{ $t('help.desc_para5') }} - + {{ $t('help.desc_para6') }}

{{ $t('help.desc_para3') }}

diff --git a/components/nav/NavFooter.vue b/components/nav/NavFooter.vue index 328b9069..a14a72f6 100644 --- a/components/nav/NavFooter.vue +++ b/components/nav/NavFooter.vue @@ -55,11 +55,17 @@ function toggleDark() { {{ $t('settings.about.label') }} · - Mastodon + + Mastodon + · - Discord + + Discord + · - GitHub + + GitHub + diff --git a/components/status/StatusCard.vue b/components/status/StatusCard.vue index 5748be67..3831e8d0 100644 --- a/components/status/StatusCard.vue +++ b/components/status/StatusCard.vue @@ -168,11 +168,11 @@ const showReplyTo = $computed(() => !replyToMain && !directReply)

diff --git a/components/status/StatusPreviewCard.vue b/components/status/StatusPreviewCard.vue index 9df7ced7..b8edb7c6 100644 --- a/components/status/StatusPreviewCard.vue +++ b/components/status/StatusPreviewCard.vue @@ -46,6 +46,7 @@ const cardTypeIconMap: Record = { 'rounded-lg border border-base': !root, }" target="_blank" + external >
{
diff --git a/components/timeline/TimelinePaginator.vue b/components/timeline/TimelinePaginator.vue index c3146093..723fa1b2 100644 --- a/components/timeline/TimelinePaginator.vue +++ b/components/timeline/TimelinePaginator.vue @@ -41,14 +41,14 @@ const showOriginSite = $computed(() => diff --git a/components/user/UserSignIn.vue b/components/user/UserSignIn.vue index 0c9af5d4..e4138ee7 100644 --- a/components/user/UserSignIn.vue +++ b/components/user/UserSignIn.vue @@ -175,7 +175,7 @@ onClickOutside($$(input), () => {
- {{ $t('user.tip_register_account') }} + {{ $t('user.tip_register_account') }}
From 9721bbf12b0c66fa22da5018ad417f5ccebd3800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90?= Date: Mon, 9 Jan 2023 22:31:30 +0800 Subject: [PATCH 4/9] refactor: change publish button text for replying --- components/publish/PublishWidget.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/publish/PublishWidget.vue b/components/publish/PublishWidget.vue index c740c7e0..2ac061e2 100644 --- a/components/publish/PublishWidget.vue +++ b/components/publish/PublishWidget.vue @@ -364,7 +364,9 @@ const isPublishDisabled = computed(() => { aria-describedby="publish-tooltip" @click="publish" > - {{ !draft.editingStatus ? $t('action.publish') : $t('action.save_changes') }} + {{ $t('action.save_changes') }} + {{ $t('action.reply') }} + {{ $t('action.publish') }}
From 0651c50a43769cec5509b580e32d20a199c648fe Mon Sep 17 00:00:00 2001 From: patak Date: Mon, 9 Jan 2023 15:42:13 +0100 Subject: [PATCH 5/9] chore: remove unused buffer prop --- components/common/CommonPaginator.vue | 5 ----- 1 file changed, 5 deletions(-) diff --git a/components/common/CommonPaginator.vue b/components/common/CommonPaginator.vue index 9e40c706..8bf06c2e 100644 --- a/components/common/CommonPaginator.vue +++ b/components/common/CommonPaginator.vue @@ -10,7 +10,6 @@ const { keyProp = 'id', virtualScroller = false, eventType = 'update', - buffer = 10, preprocess, } = defineProps<{ paginator: Paginator @@ -18,10 +17,6 @@ const { virtualScroller?: boolean stream?: Promise eventType?: 'notification' | 'update' - // When preprocess is used, buffer is the number of items that will be hidden - // until the next pagination to avoid border effect between pages when reordering - // and grouping items - buffer?: number preprocess?: (items: T[]) => U[] }>() From 162b56f5cb8a97070219556a339bfc620dd27e37 Mon Sep 17 00:00:00 2001 From: jviide Date: Mon, 9 Jan 2023 16:47:41 +0200 Subject: [PATCH 6/9] fix: add nofollow noreferrer noopener to Twitter mentions (#910) --- composables/content-parse.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composables/content-parse.ts b/composables/content-parse.ts index e88f2083..0692adfc 100644 --- a/composables/content-parse.ts +++ b/composables/content-parse.ts @@ -322,7 +322,7 @@ const _markdownReplacements: [RegExp, (c: (string | Node)[]) => Node][] = [ [/~~(.*?)~~/g, c => h('del', null, c)], [/`([^`]+?)`/g, c => h('code', null, c)], // transform @username@twitter.com as links - [/\B@([a-zA-Z0-9_]+)@twitter\.com\b/gi, c => h('a', { href: `https://twitter.com/${c}`, target: '_blank', class: 'mention external' }, `@${c}@twitter.com`)], + [/\B@([a-zA-Z0-9_]+)@twitter\.com\b/gi, c => h('a', { href: `https://twitter.com/${c}`, target: '_blank', rel: 'nofollow noopener noreferrer', class: 'mention external' }, `@${c}@twitter.com`)], ] function _markdownProcess(value: string) { From 01a24a60157d0416fc11915559af3b4edd4fbc72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90?= Date: Mon, 9 Jan 2023 23:04:09 +0800 Subject: [PATCH 7/9] refactor: optimize paginator typings --- composables/paginator.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/composables/paginator.ts b/composables/paginator.ts index 3e78f0b9..2b85bb16 100644 --- a/composables/paginator.ts +++ b/composables/paginator.ts @@ -1,16 +1,16 @@ -import type { Paginator, WsEvents } from 'masto' +import type { Paginator, WsEvents, mastodon } from 'masto' import type { PaginatorState } from '~/types' export function usePaginator( paginator: Paginator, stream?: Promise, eventType: 'notification' | 'update' = 'update', - preprocess: (items: T[]) => U[] = (items: T[]) => items as unknown as U[], + preprocess: (items: T[]) => U[] = items => items as unknown as U[], buffer = 10, ) { const state = ref(isMastoInitialised.value ? 'idle' : 'loading') - const items = ref([]) - const nextItems = ref([]) + const items = ref([]) + const nextItems = ref([]) const prevItems = ref([]) const endAnchor = ref() @@ -20,7 +20,7 @@ export function usePaginator( const deactivated = useDeactivated() async function update() { - items.value.unshift(...preprocess(prevItems.value as any) as any) + (items.value as U[]).unshift(...preprocess(prevItems.value as T[])) prevItems.value = [] } @@ -40,17 +40,19 @@ export function usePaginator( s.on('status.update', (status) => { cacheStatus(status, undefined, true) - const index = items.value.findIndex((s: any) => s.id === status.id) + const data = items.value as mastodon.v1.Status[] + const index = data.findIndex(s => s.id === status.id) if (index >= 0) - items.value[index] = status as any + data[index] = status }) s.on('delete', (id) => { removeCachedStatus(id) - const index = items.value.findIndex((s: any) => s.id === id) + const data = items.value as mastodon.v1.Status[] + const index = data.findIndex(s => s.id === id) if (index >= 0) - items.value.splice(index, 1) + data.splice(index, 1) }) }) From 333cab0858a4383ed0bb683955018a09e4f2eb95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90?= Date: Mon, 9 Jan 2023 23:20:54 +0800 Subject: [PATCH 8/9] fix(paginator): item count less than buffer --- composables/paginator.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/composables/paginator.ts b/composables/paginator.ts index 2b85bb16..62861b0c 100644 --- a/composables/paginator.ts +++ b/composables/paginator.ts @@ -66,7 +66,10 @@ export function usePaginator( if (result.value?.length) { const preprocessedItems = preprocess([...nextItems.value, ...result.value]) as any - const itemsToShowCount = preprocessedItems.length - buffer + const itemsToShowCount + = preprocessedItems.length < buffer + ? preprocessedItems.length + : preprocessedItems.length - buffer nextItems.value = preprocessedItems.slice(itemsToShowCount) items.value.push(...preprocessedItems.slice(0, itemsToShowCount)) state.value = 'idle' From 8d77f9e9fb5d8eb06c13199313e2d2d0f825a8cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90?= Date: Mon, 9 Jan 2023 23:39:59 +0800 Subject: [PATCH 9/9] fix: repeat preprocessing notifications removed some logic of a8e0e06d84d95788b92f2bb7f0fb130f3d568e39 before, re-add it now --- components/common/CommonPaginator.vue | 2 +- .../notification/NotificationPaginator.vue | 24 ++++++++++++++++++- composables/paginator.ts | 10 ++++---- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/components/common/CommonPaginator.vue b/components/common/CommonPaginator.vue index 8bf06c2e..1191f17d 100644 --- a/components/common/CommonPaginator.vue +++ b/components/common/CommonPaginator.vue @@ -17,7 +17,7 @@ const { virtualScroller?: boolean stream?: Promise eventType?: 'notification' | 'update' - preprocess?: (items: T[]) => U[] + preprocess?: (items: (U | T)[]) => U[] }>() defineSlots<{ diff --git a/components/notification/NotificationPaginator.vue b/components/notification/NotificationPaginator.vue index 2e071e36..7e2fcbaa 100644 --- a/components/notification/NotificationPaginator.vue +++ b/components/notification/NotificationPaginator.vue @@ -23,7 +23,7 @@ const groupId = (item: mastodon.v1.Notification): string => { return JSON.stringify(id) } -function preprocess(items: mastodon.v1.Notification[]): NotificationSlot[] { +function groupItems(items: mastodon.v1.Notification[]): NotificationSlot[] { const results: NotificationSlot[] = [] let id = 0 @@ -108,6 +108,28 @@ function preprocess(items: mastodon.v1.Notification[]): NotificationSlot[] { return results } +function preprocess(items: NotificationSlot[]): NotificationSlot[] { + const flattenedNotifications: mastodon.v1.Notification[] = [] + for (const item of items) { + if (item.type === 'grouped-reblogs-and-favourites') { + const group = item + for (const like of group.likes) { + if (like.reblog) + flattenedNotifications.push(like.reblog) + if (like.favourite) + flattenedNotifications.push(like.favourite) + } + } + else if (item.type === 'grouped-follow') { + flattenedNotifications.push(...item.items) + } + else { + flattenedNotifications.push(item) + } + } + return groupItems(flattenedNotifications) +} + const { clearNotifications } = useNotifications() const { formatNumber } = useHumanReadableNumber() diff --git a/composables/paginator.ts b/composables/paginator.ts index 62861b0c..90950cc2 100644 --- a/composables/paginator.ts +++ b/composables/paginator.ts @@ -5,7 +5,7 @@ export function usePaginator( paginator: Paginator, stream?: Promise, eventType: 'notification' | 'update' = 'update', - preprocess: (items: T[]) => U[] = items => items as unknown as U[], + preprocess: (items: (T | U)[]) => U[] = items => items as unknown as U[], buffer = 10, ) { const state = ref(isMastoInitialised.value ? 'idle' : 'loading') @@ -64,14 +64,14 @@ export function usePaginator( try { const result = await paginator.next() - if (result.value?.length) { - const preprocessedItems = preprocess([...nextItems.value, ...result.value]) as any + if (!result.done && result.value.length) { + const preprocessedItems = preprocess([...nextItems.value, ...result.value] as (U | T)[]) const itemsToShowCount = preprocessedItems.length < buffer ? preprocessedItems.length : preprocessedItems.length - buffer - nextItems.value = preprocessedItems.slice(itemsToShowCount) - items.value.push(...preprocessedItems.slice(0, itemsToShowCount)) + ;(nextItems.value as U[]) = preprocessedItems.slice(itemsToShowCount) + ;(items.value as U[]).push(...preprocessedItems.slice(0, itemsToShowCount)) state.value = 'idle' } else {