From ee3f408c7d25accb5812c4f442ba7f4531e4b681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Acid=20Chicken=20=28=E7=A1=AB=E9=85=B8=E9=B6=8F=29?= Date: Sat, 20 May 2023 03:38:07 +0900 Subject: [PATCH 01/10] feat: impl IdlingRenderScheduler (#10547) * feat: impl IdleRender * test: pin time on Chromatic * test: pin time on Chromatic * fix: typo * style: rename * style: rename * chore: back to setTimeout * style: linebreak * refactor: remove unused budget option * refactor: use raw unix time * fix: conflict error * fix: floor * fix: subtract * Revert "fix: subtract" This reverts commit 2ef4afaafc69d2fb8329b04c1b124dfa97b7e863. * Revert "fix: floor" This reverts commit bef8ecdf45c6afc52138921d16e2caca78cfd38d. * Revert "refactor: use raw unix time" This reverts commit 5199e13cb2829f3036101f95445cca3cb9c83703. --- packages/frontend/.storybook/generate.tsx | 1 + .../components/MkAnalogClock.stories.impl.ts | 2 +- .../frontend/src/components/MkAnalogClock.vue | 34 ++++++++--------- .../components/MkDigitalClock.stories.impl.ts | 32 ++++++++++++++++ .../src/components/MkDigitalClock.vue | 21 +++++----- .../frontend/src/components/global/MkTime.vue | 1 - packages/frontend/src/scripts/idle-render.ts | 38 +++++++++++++++++++ 7 files changed, 100 insertions(+), 29 deletions(-) create mode 100644 packages/frontend/src/components/MkDigitalClock.stories.impl.ts create mode 100644 packages/frontend/src/scripts/idle-render.ts diff --git a/packages/frontend/.storybook/generate.tsx b/packages/frontend/.storybook/generate.tsx index 7c51d4c00c..f442422109 100644 --- a/packages/frontend/.storybook/generate.tsx +++ b/packages/frontend/.storybook/generate.tsx @@ -397,6 +397,7 @@ function toStories(component: string): string { Promise.all([ glob('src/components/global/*.vue'), glob('src/components/Mk{A,B}*.vue'), + glob('src/components/MkDigitalClock.vue'), glob('src/components/MkGalleryPostPreview.vue'), glob('src/components/MkSignupServerRules.vue'), glob('src/components/MkUserSetupDialog.vue'), diff --git a/packages/frontend/src/components/MkAnalogClock.stories.impl.ts b/packages/frontend/src/components/MkAnalogClock.stories.impl.ts index e7fbb47284..0aebdccf4f 100644 --- a/packages/frontend/src/components/MkAnalogClock.stories.impl.ts +++ b/packages/frontend/src/components/MkAnalogClock.stories.impl.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { StoryObj } from '@storybook/vue3'; +import isChromatic from 'chromatic/isChromatic'; import MkAnalogClock from './MkAnalogClock.vue'; -import isChromatic from 'chromatic'; export const Default = { render(args) { return { diff --git a/packages/frontend/src/components/MkAnalogClock.vue b/packages/frontend/src/components/MkAnalogClock.vue index f12020f810..05caffe7d0 100644 --- a/packages/frontend/src/components/MkAnalogClock.vue +++ b/packages/frontend/src/components/MkAnalogClock.vue @@ -39,6 +39,7 @@ --> diff --git a/packages/frontend/src/components/MkDigitalClock.stories.impl.ts b/packages/frontend/src/components/MkDigitalClock.stories.impl.ts new file mode 100644 index 0000000000..344f6de47c --- /dev/null +++ b/packages/frontend/src/components/MkDigitalClock.stories.impl.ts @@ -0,0 +1,32 @@ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ +import { StoryObj } from '@storybook/vue3'; +import isChromatic from 'chromatic/isChromatic'; +import MkDigitalClock from './MkDigitalClock.vue'; +export const Default = { + render(args) { + return { + components: { + MkDigitalClock, + }, + setup() { + return { + args, + }; + }, + computed: { + props() { + return { + ...this.args, + }; + }, + }, + template: '', + }; + }, + args: { + now: isChromatic() ? () => new Date('2023-01-01T10:10:30') : undefined, + }, + parameters: { + layout: 'centered', + }, +} satisfies StoryObj; diff --git a/packages/frontend/src/components/MkDigitalClock.vue b/packages/frontend/src/components/MkDigitalClock.vue index 278dc8a5e7..aea20f2489 100644 --- a/packages/frontend/src/components/MkDigitalClock.vue +++ b/packages/frontend/src/components/MkDigitalClock.vue @@ -11,19 +11,21 @@ diff --git a/packages/frontend/src/components/global/MkTime.vue b/packages/frontend/src/components/global/MkTime.vue index 261cc0ee18..dfc3c89798 100644 --- a/packages/frontend/src/components/global/MkTime.vue +++ b/packages/frontend/src/components/global/MkTime.vue @@ -58,7 +58,6 @@ function tick() { if (props.mode === 'relative' || props.mode === 'detail') { tick(); - onUnmounted(() => { window.clearTimeout(tickId); }); diff --git a/packages/frontend/src/scripts/idle-render.ts b/packages/frontend/src/scripts/idle-render.ts new file mode 100644 index 0000000000..ccce8b02bf --- /dev/null +++ b/packages/frontend/src/scripts/idle-render.ts @@ -0,0 +1,38 @@ +class IdlingRenderScheduler { + #renderers: Set; + #rafId: number; + #ricId: number; + + constructor() { + this.#renderers = new Set(); + this.#rafId = 0; + this.#ricId = requestIdleCallback((deadline) => this.#schedule(deadline)); + } + + #schedule(deadline: IdleDeadline): void { + if (deadline.timeRemaining()) { + this.#rafId = requestAnimationFrame((time) => { + for (const renderer of this.#renderers) { + renderer(time); + } + }); + } + this.#ricId = requestIdleCallback((arg) => this.#schedule(arg)); + } + + add(renderer: FrameRequestCallback): void { + this.#renderers.add(renderer); + } + + delete(renderer: FrameRequestCallback): void { + this.#renderers.delete(renderer); + } + + dispose(): void { + this.#renderers.clear(); + cancelAnimationFrame(this.#rafId); + cancelIdleCallback(this.#ricId); + } +} + +export const defaultIdlingRenderScheduler = new IdlingRenderScheduler(); From c685989e670b1945bb0ba2391a49ebcf3ee484aa Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 20 May 2023 10:05:35 +0900 Subject: [PATCH 02/10] refactor --- packages/frontend/src/ui/deck.vue | 77 +++++++++++-------- packages/frontend/src/ui/deck/column-core.vue | 38 --------- 2 files changed, 46 insertions(+), 69 deletions(-) delete mode 100644 packages/frontend/src/ui/deck/column-core.vue diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue index 585f727698..df695b9f4b 100644 --- a/packages/frontend/src/ui/deck.vue +++ b/packages/frontend/src/ui/deck.vue @@ -4,27 +4,24 @@
-
- +
{{ i18n.ts._deck.introduction }}
{{ i18n.ts._deck.addColumn }} @@ -87,7 +84,6 @@ import { computed, defineAsyncComponent, ref, watch } from 'vue'; import { v4 as uuid } from 'uuid'; import XCommon from './_common_/common.vue'; import { deckStore, addColumn as addColumnToStore, loadDeck, getProfiles, deleteProfile as deleteProfile_ } from './deck/deck-store'; -import DeckColumnCore from '@/ui/deck/column-core.vue'; import XSidebar from '@/ui/_common_/navbar.vue'; import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue'; import MkButton from '@/components/MkButton.vue'; @@ -100,8 +96,31 @@ import { mainRouter } from '@/router'; import { unisonReload } from '@/scripts/unison-reload'; import { deviceKind } from '@/scripts/device-kind'; import { defaultStore } from '@/store'; +import XMainColumn from '@/ui/deck/main-column.vue'; +import XTlColumn from '@/ui/deck/tl-column.vue'; +import XAntennaColumn from '@/ui/deck/antenna-column.vue'; +import XListColumn from '@/ui/deck/list-column.vue'; +import XChannelColumn from '@/ui/deck/channel-column.vue'; +import XNotificationsColumn from '@/ui/deck/notifications-column.vue'; +import XWidgetsColumn from '@/ui/deck/widgets-column.vue'; +import XMentionsColumn from '@/ui/deck/mentions-column.vue'; +import XDirectColumn from '@/ui/deck/direct-column.vue'; +import XRoleTimelineColumn from '@/ui/deck/role-timeline-column.vue'; const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue')); +const columnComponents = { + main: XMainColumn, + widgets: XWidgetsColumn, + notifications: XNotificationsColumn, + tl: XTlColumn, + list: XListColumn, + channel: XChannelColumn, + antenna: XAntennaColumn, + mentions: XMentionsColumn, + direct: XDirectColumn, + roleTimeline: XRoleTimelineColumn, +}; + mainRouter.navHook = (path, flag): boolean => { if (flag === 'forcePage') return false; const noMainColumn = !deckStore.state.columns.some(x => x.type === 'main'); @@ -286,18 +305,18 @@ async function deleteProfile() { flex-direction: column; } -.columns { +.sections { flex: 1; display: flex; overflow-x: auto; overflow-y: clip; &.center { - > .column:first-of-type { + > .section:first-of-type { margin-left: auto; } - > .column:last-of-type { + > .section:last-of-type { margin-right: auto; } } @@ -307,7 +326,9 @@ async function deleteProfile() { } } -.column { +.section { + display: flex; + flex-direction: column; scroll-snap-align: start; flex-shrink: 0; border-right: solid var(--deckDividerThickness) var(--deckDivider); @@ -315,14 +336,8 @@ async function deleteProfile() { &:first-of-type { border-left: solid var(--deckDividerThickness) var(--deckDivider); } -} -.folder { - composes: column; - display: flex; - flex-direction: column; - - > *:not(:last-of-type) { + > .column:not(:last-of-type) { border-bottom: solid var(--deckDividerThickness) var(--deckDivider); } } diff --git a/packages/frontend/src/ui/deck/column-core.vue b/packages/frontend/src/ui/deck/column-core.vue deleted file mode 100644 index 29299cdcdb..0000000000 --- a/packages/frontend/src/ui/deck/column-core.vue +++ /dev/null @@ -1,38 +0,0 @@ - - - From d177f97928c7223349f65820b931c6884dafe2f7 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 20 May 2023 10:12:18 +0900 Subject: [PATCH 03/10] refactor --- packages/frontend/src/ui/deck.vue | 6 +--- .../frontend/src/ui/deck/antenna-column.vue | 3 +- .../frontend/src/ui/deck/channel-column.vue | 3 +- packages/frontend/src/ui/deck/column.vue | 33 ++++++------------- .../frontend/src/ui/deck/direct-column.vue | 3 +- packages/frontend/src/ui/deck/list-column.vue | 3 +- packages/frontend/src/ui/deck/main-column.vue | 3 +- .../frontend/src/ui/deck/mentions-column.vue | 3 +- .../src/ui/deck/notifications-column.vue | 3 +- .../src/ui/deck/role-timeline-column.vue | 3 +- packages/frontend/src/ui/deck/tl-column.vue | 3 +- .../frontend/src/ui/deck/widgets-column.vue | 3 +- 12 files changed, 21 insertions(+), 48 deletions(-) diff --git a/packages/frontend/src/ui/deck.vue b/packages/frontend/src/ui/deck.vue index df695b9f4b..b91d6d7675 100644 --- a/packages/frontend/src/ui/deck.vue +++ b/packages/frontend/src/ui/deck.vue @@ -19,7 +19,6 @@ :class="$style.column" :column="columns.find(c => c.id === id)" :isStacked="ids.length > 1" - @parentFocus="moveFocus(id, $event)" />
@@ -206,11 +205,8 @@ window.addEventListener('wheel', (ev) => { columnsEl.scrollLeft += ev.deltaY; } }); -loadDeck(); -function moveFocus(id: string, direction: 'up' | 'down' | 'left' | 'right') { - // TODO?? -} +loadDeck(); function changeProfile(ev: MouseEvent) { const items = ref([{ diff --git a/packages/frontend/src/ui/deck/antenna-column.vue b/packages/frontend/src/ui/deck/antenna-column.vue index 661f4cab82..d35fa58638 100644 --- a/packages/frontend/src/ui/deck/antenna-column.vue +++ b/packages/frontend/src/ui/deck/antenna-column.vue @@ -1,5 +1,5 @@