Merge branch 'develop' into mkjs-n
This commit is contained in:
@@ -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<WorkerMultiDispatch | null>(resolve => {
|
||||
const canvasPromise = new Promise<WorkerMultiDispatch | HTMLCanvasElement>(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<WorkerMultiDispatch | null>(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);
|
||||
}
|
||||
|
||||
const workers = await workerPromise;
|
||||
if (workers) {
|
||||
workers.postMessage(
|
||||
async function draw() {
|
||||
if (props.hash == null) return;
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@@ -32,7 +32,8 @@
|
||||
</path>
|
||||
</svg>
|
||||
-->
|
||||
<svg v-for="particle in particles" :key="particle.id" :width="width" :height="height" :viewBox="`0 0 ${width} ${height}`" xmlns="http://www.w3.org/2000/svg" style="position: absolute; top: -32px; left: -32px;">
|
||||
<!-- MFMで上位レイヤーに表示されるため、リンクをクリックできるようにstyleにpointer-events: none;を付与。 -->
|
||||
<svg v-for="particle in particles" :key="particle.id" :width="width" :height="height" :viewBox="`0 0 ${width} ${height}`" xmlns="http://www.w3.org/2000/svg" style="position: absolute; top: -32px; left: -32px; pointer-events: none;">
|
||||
<path
|
||||
style="transform-origin: center; transform-box: fill-box;"
|
||||
:transform="`translate(${particle.x} ${particle.y})`"
|
||||
@@ -115,6 +116,5 @@ onUnmounted(() => {
|
||||
.root {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<component :is="link ? MkA : 'span'" v-user-preview="preview ? user.id : undefined" v-bind="bound" class="_noSelect" :class="[$style.root, { [$style.animation]: animation, [$style.cat]: user.isCat, [$style.square]: squareAvatars }]" :style="{ color }" :title="acct(user)" @click="onClick">
|
||||
<img :class="$style.inner" :src="url" :hash="user?.avatarBlurhash" :cover="true"/>
|
||||
<MkImgWithBlurhash :class="$style.inner" :src="url" :hash="user?.avatarBlurhash" :cover="true" :onlyAvgColor="true"/>
|
||||
<MkUserOnlineIndicator v-if="indicator" :class="$style.indicator" :user="user"/>
|
||||
<div v-if="user.isCat" :class="[$style.ears]">
|
||||
<div :class="$style.earLeft">
|
||||
@@ -24,6 +24,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { watch } from 'vue';
|
||||
import * as misskey from 'misskey-js';
|
||||
import MkImgWithBlurhash from '../MkImgWithBlurhash.vue';
|
||||
import MkA from './MkA.vue';
|
||||
import { getStaticImageUrl } from '@/scripts/media-proxy';
|
||||
import { extractAvgColorFromBlurhash } from '@/scripts/extract-avg-color-from-blurhash';
|
||||
|
@@ -4,6 +4,14 @@
|
||||
<MkSpacer :contentMax="700" :marginMin="16" :marginMax="32">
|
||||
<FormSuspense :p="init">
|
||||
<div class="_gaps_s">
|
||||
<MkSwitch v-model="enableServerMachineStats">
|
||||
<template #label>{{ i18n.ts.enableServerMachineStats }}</template>
|
||||
</MkSwitch>
|
||||
|
||||
<MkSwitch v-model="enableIdenticonGeneration">
|
||||
<template #label>{{ i18n.ts.enableIdenticonGeneration }}</template>
|
||||
</MkSwitch>
|
||||
|
||||
<MkSwitch v-model="enableChartsForRemoteUser">
|
||||
<template #label>{{ i18n.ts.enableChartsForRemoteUser }}</template>
|
||||
</MkSwitch>
|
||||
@@ -27,17 +35,23 @@ import { i18n } from '@/i18n';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
|
||||
let enableServerMachineStats: boolean = $ref(false);
|
||||
let enableIdenticonGeneration: boolean = $ref(false);
|
||||
let enableChartsForRemoteUser: boolean = $ref(false);
|
||||
let enableChartsForFederatedInstances: boolean = $ref(false);
|
||||
|
||||
async function init() {
|
||||
const meta = await os.api('admin/meta');
|
||||
enableServerMachineStats = meta.enableServerMachineStats;
|
||||
enableIdenticonGeneration = meta.enableIdenticonGeneration;
|
||||
enableChartsForRemoteUser = meta.enableChartsForRemoteUser;
|
||||
enableChartsForFederatedInstances = meta.enableChartsForFederatedInstances;
|
||||
}
|
||||
|
||||
function save() {
|
||||
os.apiWithDialog('admin/update-meta', {
|
||||
enableServerMachineStats,
|
||||
enableIdenticonGeneration,
|
||||
enableChartsForRemoteUser,
|
||||
enableChartsForFederatedInstances,
|
||||
}).then(() => {
|
||||
|
@@ -62,7 +62,7 @@ const { widgetProps, configure, save } = useWidgetPropsManager(name,
|
||||
|
||||
const meta = ref(null);
|
||||
|
||||
os.api('server-info', {}).then(res => {
|
||||
os.apiGet('server-info', {}).then(res => {
|
||||
meta.value = res;
|
||||
});
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
import { render } from 'buraha';
|
||||
|
||||
const canvas = new OffscreenCanvas(64, 64);
|
||||
|
||||
onmessage = (event) => {
|
||||
// console.log(event.data);
|
||||
if (!('id' in event.data && typeof event.data.id === 'string')) {
|
||||
@@ -8,8 +10,8 @@ onmessage = (event) => {
|
||||
if (!('hash' in event.data && typeof event.data.hash === 'string')) {
|
||||
return;
|
||||
}
|
||||
const work = new OffscreenCanvas(event.data.width ?? 64, event.data.height ?? 64);
|
||||
render(event.data.hash, work);
|
||||
const bitmap = work.transferToImageBitmap();
|
||||
|
||||
render(event.data.hash, canvas);
|
||||
const bitmap = canvas.transferToImageBitmap();
|
||||
postMessage({ id: event.data.id, bitmap });
|
||||
};
|
||||
|
Reference in New Issue
Block a user