From 734c41aba5b3a7e41a1d65796f34d68da77248f8 Mon Sep 17 00:00:00 2001 From: tamaina Date: Sun, 2 Jul 2023 13:46:49 +0900 Subject: perf(frontend): MkImgWithBlurhashでblurhash描画に使うcanvasは再利用するようにする (#10966) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * blurhashを描画するためのcanvasは再利用する * Revert "perf(frontend): WebGL contextの数を減らす" This reverts commit aeb8955ca2600e801d44dcac2005fc994e665a6c. * MkAvatarは平均色だけにする * clean up * fix --- .../frontend/src/components/MkImgWithBlurhash.vue | 51 ++++++++++++++-------- .../frontend/src/components/global/MkAvatar.vue | 3 +- 2 files changed, 34 insertions(+), 20 deletions(-) (limited to 'packages/frontend/src/components') diff --git a/packages/frontend/src/components/MkImgWithBlurhash.vue b/packages/frontend/src/components/MkImgWithBlurhash.vue index 672a28f6d0..cb229fa241 100644 --- a/packages/frontend/src/components/MkImgWithBlurhash.vue +++ b/packages/frontend/src/components/MkImgWithBlurhash.vue @@ -22,10 +22,13 @@ import TestWebGL2 from '@/workers/test-webgl2?worker'; import { WorkerMultiDispatch } from '@/scripts/worker-multi-dispatch'; import { extractAvgColorFromBlurhash } from '@/scripts/extract-avg-color-from-blurhash'; -const workerPromise = new Promise(resolve => { +const canvasPromise = new Promise(resolve => { // テスト環境で Web Worker インスタンスは作成できない if (import.meta.env.MODE === 'test') { - resolve(null); + const canvas = document.createElement('canvas'); + canvas.width = 64; + canvas.height = 64; + resolve(canvas); return; } const testWorker = new TestWebGL2(); @@ -38,7 +41,10 @@ const workerPromise = new Promise(resolve => { resolve(workers); if (_DEV_) console.log('WebGL2 in worker is supported!'); } else { - resolve(null); + const canvas = document.createElement('canvas'); + canvas.width = 64; + canvas.height = 64; + resolve(canvas); if (_DEV_) console.log('WebGL2 in worker is not supported...'); } testWorker.terminate(); @@ -70,6 +76,7 @@ const props = withDefaults(defineProps<{ width?: number; cover?: boolean; forceBlurhash?: boolean; + onlyAvgColor?: boolean; // 軽量化のためにBlurhashを使わずに平均色だけを描画 }>(), { transition: null, src: null, @@ -79,6 +86,7 @@ const props = withDefaults(defineProps<{ width: 64, cover: true, forceBlurhash: false, + onlyAvgColor: false, }); const viewId = uuid(); @@ -139,8 +147,8 @@ function drawImage(bitmap: CanvasImageSource) { ctx.drawImage(bitmap, 0, 0, canvasWidth, canvasHeight); } -async function draw() { - if (!canvas.value || props.hash == null) return; +function drawAvg() { + if (!canvas.value || !props.hash) return; const ctx = canvas.value.getContext('2d'); if (!ctx) return; @@ -149,25 +157,28 @@ async function draw() { ctx.beginPath(); ctx.fillStyle = extractAvgColorFromBlurhash(props.hash) ?? '#888'; ctx.fillRect(0, 0, canvasWidth, canvasHeight); +} + +async function draw() { + if (props.hash == null) return; - const workers = await workerPromise; - if (workers) { - workers.postMessage( + drawAvg(); + + if (props.onlyAvgColor) return; + + const work = await canvasPromise; + if (work instanceof WorkerMultiDispatch) { + work.postMessage( { id: viewId, hash: props.hash, - width: canvasWidth, - height: canvasHeight, }, undefined, ); } else { try { - const work = document.createElement('canvas'); - work.width = canvasWidth; - work.height = canvasHeight; render(props.hash, work); - ctx.drawImage(work, 0, 0, canvasWidth, canvasHeight); + drawImage(work); } catch (error) { console.error('Error occured during drawing blurhash', error); } @@ -179,9 +190,9 @@ function workerOnMessage(event: MessageEvent) { drawImage(event.data.bitmap as ImageBitmap); } -workerPromise.then(worker => { - if (worker) { - worker.addListener(workerOnMessage); +canvasPromise.then(work => { + if (work instanceof WorkerMultiDispatch) { + work.addListener(workerOnMessage); } draw(); @@ -204,8 +215,10 @@ onMounted(() => { }); onUnmounted(() => { - workerPromise.then(worker => { - worker?.removeListener(workerOnMessage); + canvasPromise.then(work => { + if (work instanceof WorkerMultiDispatch) { + work.removeListener(workerOnMessage); + } }); }); diff --git a/packages/frontend/src/components/global/MkAvatar.vue b/packages/frontend/src/components/global/MkAvatar.vue index efe74b7cc3..1952ba9811 100644 --- a/packages/frontend/src/components/global/MkAvatar.vue +++ b/packages/frontend/src/components/global/MkAvatar.vue @@ -1,6 +1,6 @@ - - diff --git a/packages/frontend/src/pages/my-lists/index.vue b/packages/frontend/src/pages/my-lists/index.vue index cee241c489..0f59ca0b36 100644 --- a/packages/frontend/src/pages/my-lists/index.vue +++ b/packages/frontend/src/pages/my-lists/index.vue @@ -3,38 +3,43 @@
+
+
+ +
{{ i18n.ts.nothing }}
+
+
+ {{ i18n.ts.createList }} - -
- -
{{ list.name }}
- -
-
-
+
+ +
{{ list.name }}
+ +
+
diff --git a/packages/frontend/src/const.ts b/packages/frontend/src/const.ts index ad7fa372e9..1d883c038e 100644 --- a/packages/frontend/src/const.ts +++ b/packages/frontend/src/const.ts @@ -57,6 +57,9 @@ export const ROLE_POLICIES = [ 'ltlAvailable', 'canPublicNote', 'canInvite', + 'inviteLimit', + 'inviteLimitCycle', + 'inviteExpirationTime', 'canManageCustomEmojis', 'canSearchNotes', 'canHideAds', diff --git a/packages/frontend/src/pages/admin/index.vue b/packages/frontend/src/pages/admin/index.vue index 226eb8d026..e91f65b5d5 100644 --- a/packages/frontend/src/pages/admin/index.vue +++ b/packages/frontend/src/pages/admin/index.vue @@ -80,7 +80,7 @@ const menuDef = $computed(() => [{ }, ...(instance.disableRegistration ? [{ type: 'button', icon: 'ti ti-user-plus', - text: i18n.ts.invite, + text: i18n.ts.createInviteCode, action: invite, }] : [])], }, { @@ -95,6 +95,11 @@ const menuDef = $computed(() => [{ text: i18n.ts.users, to: '/admin/users', active: currentPage?.route.name === 'users', + }, { + icon: 'ti ti-user-plus', + text: i18n.ts.invite, + to: '/admin/invites', + active: currentPage?.route.name === 'invites', }, { icon: 'ti ti-badges', text: i18n.ts.roles, @@ -240,10 +245,10 @@ provideMetadataReceiver((info) => { }); const invite = () => { - os.api('invite').then(x => { + os.api('admin/invite/create').then(x => { os.alert({ type: 'info', - text: x.code, + text: x?.[0].code, }); }).catch(err => { os.alert({ diff --git a/packages/frontend/src/pages/admin/invites.vue b/packages/frontend/src/pages/admin/invites.vue new file mode 100644 index 0000000000..70a9c93713 --- /dev/null +++ b/packages/frontend/src/pages/admin/invites.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue index 02a2d4366a..7fe5624fb5 100644 --- a/packages/frontend/src/pages/admin/roles.editor.vue +++ b/packages/frontend/src/pages/admin/roles.editor.vue @@ -171,6 +171,65 @@ + + + +
+ + + + + + + + +
+
+ + + + +
+ + + + + + + + + +
+
+ + + + +
+ + + + + + + + + +
+
+