mirror of
https://github.com/misskey-dev/misskey.git
synced 2026-05-14 09:55:38 +02:00
Merge branch 'develop' into room
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
"@rollup/plugin-json": "6.1.0",
|
||||
"@rollup/plugin-replace": "6.0.3",
|
||||
"@rollup/pluginutils": "5.3.0",
|
||||
"@sentry/vue": "10.38.0",
|
||||
"@sentry/vue": "10.40.0",
|
||||
"@syuilo/aiscript": "1.2.1",
|
||||
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
|
||||
"@twemoji/parser": "16.0.0",
|
||||
@@ -43,13 +43,13 @@
|
||||
"chartjs-chart-matrix": "3.0.0",
|
||||
"chartjs-plugin-gradient": "0.6.1",
|
||||
"chartjs-plugin-zoom": "2.2.0",
|
||||
"chromatic": "15.1.0",
|
||||
"chromatic": "15.2.0",
|
||||
"compare-versions": "6.1.1",
|
||||
"cropperjs": "2.1.0",
|
||||
"date-fns": "4.1.0",
|
||||
"eventemitter3": "5.0.4",
|
||||
"execa": "9.6.1",
|
||||
"exifreader": "4.36.1",
|
||||
"exifreader": "4.36.2",
|
||||
"frontend-shared": "workspace:*",
|
||||
"i18n": "workspace:*",
|
||||
"icons-subsetter": "workspace:*",
|
||||
@@ -59,7 +59,7 @@
|
||||
"is-file-animated": "1.0.2",
|
||||
"json5": "2.2.3",
|
||||
"matter-js": "0.20.0",
|
||||
"mediabunny": "1.34.2",
|
||||
"mediabunny": "1.35.1",
|
||||
"mfm-js": "0.25.0",
|
||||
"misskey-bubble-game": "workspace:*",
|
||||
"misskey-js": "workspace:*",
|
||||
@@ -68,38 +68,38 @@
|
||||
"punycode.js": "2.3.1",
|
||||
"qr-code-styling": "1.9.2",
|
||||
"qr-scanner": "1.4.2",
|
||||
"rollup": "4.57.1",
|
||||
"sanitize-html": "2.17.0",
|
||||
"rollup": "4.59.0",
|
||||
"sanitize-html": "2.17.1",
|
||||
"sass": "1.97.3",
|
||||
"shiki": "3.22.0",
|
||||
"shiki": "3.23.0",
|
||||
"textarea-caret": "3.1.0",
|
||||
"three": "0.182.0",
|
||||
"three": "0.183.2",
|
||||
"throttle-debounce": "5.0.2",
|
||||
"tinycolor2": "1.6.0",
|
||||
"v-code-diff": "1.13.1",
|
||||
"vite": "7.3.1",
|
||||
"vue": "3.5.28",
|
||||
"vue": "3.5.29",
|
||||
"wanakana": "5.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@misskey-dev/summaly": "5.2.5",
|
||||
"@storybook/addon-essentials": "8.6.15",
|
||||
"@storybook/addon-interactions": "8.6.15",
|
||||
"@storybook/addon-links": "10.2.8",
|
||||
"@storybook/addon-mdx-gfm": "8.6.15",
|
||||
"@storybook/addon-storysource": "8.6.15",
|
||||
"@storybook/blocks": "8.6.15",
|
||||
"@storybook/components": "8.6.15",
|
||||
"@storybook/core-events": "8.6.15",
|
||||
"@storybook/manager-api": "8.6.15",
|
||||
"@storybook/preview-api": "8.6.15",
|
||||
"@storybook/react": "10.2.8",
|
||||
"@storybook/react-vite": "10.2.8",
|
||||
"@storybook/test": "8.6.15",
|
||||
"@storybook/theming": "8.6.15",
|
||||
"@storybook/types": "8.6.15",
|
||||
"@storybook/vue3": "10.2.8",
|
||||
"@storybook/vue3-vite": "10.2.8",
|
||||
"@storybook/addon-essentials": "8.6.17",
|
||||
"@storybook/addon-interactions": "8.6.17",
|
||||
"@storybook/addon-links": "10.2.13",
|
||||
"@storybook/addon-mdx-gfm": "8.6.17",
|
||||
"@storybook/addon-storysource": "8.6.17",
|
||||
"@storybook/blocks": "8.6.17",
|
||||
"@storybook/components": "8.6.17",
|
||||
"@storybook/core-events": "8.6.17",
|
||||
"@storybook/manager-api": "8.6.17",
|
||||
"@storybook/preview-api": "8.6.17",
|
||||
"@storybook/react": "10.2.13",
|
||||
"@storybook/react-vite": "10.2.13",
|
||||
"@storybook/test": "8.6.17",
|
||||
"@storybook/theming": "8.6.17",
|
||||
"@storybook/types": "8.6.17",
|
||||
"@storybook/vue3": "10.2.13",
|
||||
"@storybook/vue3-vite": "10.2.13",
|
||||
"@tabler/icons-webfont": "3.35.0",
|
||||
"@testing-library/vue": "8.1.0",
|
||||
"@types/canvas-confetti": "1.9.0",
|
||||
@@ -107,46 +107,46 @@
|
||||
"@types/insert-text-at-cursor": "0.3.2",
|
||||
"@types/matter-js": "0.20.2",
|
||||
"@types/micromatch": "4.0.10",
|
||||
"@types/node": "24.10.13",
|
||||
"@types/node": "24.11.0",
|
||||
"@types/punycode.js": "npm:@types/punycode@2.1.4",
|
||||
"@types/sanitize-html": "2.16.0",
|
||||
"@types/seedrandom": "3.0.8",
|
||||
"@types/textarea-caret": "3.0.4",
|
||||
"@types/throttle-debounce": "5.0.2",
|
||||
"@types/tinycolor2": "1.4.6",
|
||||
"@typescript-eslint/eslint-plugin": "8.55.0",
|
||||
"@typescript-eslint/parser": "8.55.0",
|
||||
"@typescript-eslint/eslint-plugin": "8.56.1",
|
||||
"@typescript-eslint/parser": "8.56.1",
|
||||
"@vitest/coverage-v8": "4.0.18",
|
||||
"@vue/compiler-core": "3.5.28",
|
||||
"acorn": "8.15.0",
|
||||
"@vue/compiler-core": "3.5.29",
|
||||
"acorn": "8.16.0",
|
||||
"astring": "1.9.0",
|
||||
"cross-env": "10.1.0",
|
||||
"cypress": "15.10.0",
|
||||
"cypress": "15.11.0",
|
||||
"eslint-plugin-import": "2.32.0",
|
||||
"eslint-plugin-vue": "10.8.0",
|
||||
"estree-walker": "3.0.3",
|
||||
"happy-dom": "20.6.1",
|
||||
"happy-dom": "20.7.0",
|
||||
"intersection-observer": "0.12.2",
|
||||
"magic-string": "0.30.21",
|
||||
"micromatch": "4.0.8",
|
||||
"minimatch": "10.2.2",
|
||||
"minimatch": "10.2.4",
|
||||
"msw": "2.12.10",
|
||||
"msw-storybook-addon": "2.0.6",
|
||||
"nodemon": "3.1.11",
|
||||
"nodemon": "3.1.14",
|
||||
"prettier": "3.8.1",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"seedrandom": "3.0.5",
|
||||
"start-server-and-test": "2.1.3",
|
||||
"storybook": "10.2.8",
|
||||
"start-server-and-test": "2.1.5",
|
||||
"storybook": "10.2.13",
|
||||
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
||||
"tsx": "4.21.0",
|
||||
"vite-plugin-glsl": "1.5.5",
|
||||
"vite-plugin-turbosnap": "1.0.3",
|
||||
"vitest": "4.0.18",
|
||||
"vitest-fetch-mock": "0.4.5",
|
||||
"vue-component-type-helpers": "3.2.4",
|
||||
"vue-component-type-helpers": "3.2.5",
|
||||
"vue-eslint-parser": "10.4.0",
|
||||
"vue-tsc": "3.2.4"
|
||||
"vue-tsc": "3.2.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ function onDragstart(ev: DragEvent, item: T) {
|
||||
|
||||
// Chromeのバグで、Dragstartハンドラ内ですぐにDOMを変更する(=リアクティブなプロパティを変更する)とDragが終了してしまう
|
||||
// SEE: https://stackoverflow.com/questions/19639969/html5-dragend-event-firing-immediately
|
||||
// SEE: https://issues.chromium.org/issues/41150279
|
||||
window.setTimeout(() => {
|
||||
dragging.value = true;
|
||||
}, 10);
|
||||
|
||||
@@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div v-if="Object.keys(form).filter(item => !form[item].hidden).length > 0" class="_gaps_m">
|
||||
<div v-if="Object.values(form).filter(item => typeof item.hidden !== 'boolean' || item.hidden === true).length > 0" class="_gaps_m">
|
||||
<template v-for="v, k in form">
|
||||
<template v-if="typeof v.hidden == 'function' ? v.hidden(values) : v.hidden"></template>
|
||||
<MkInput v-else-if="v.type === 'number'" v-model="values[k]" type="number" :step="v.step || 1" :manualSave="v.manualSave" @savingStateChange="(changed, invalid) => onSavingStateChange(k, changed, invalid)">
|
||||
|
||||
@@ -233,7 +233,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
|
||||
if (!useAnim) {
|
||||
return genEl(token.children, scale);
|
||||
}
|
||||
return h(MkSparkle, {}, genEl(token.children, scale));
|
||||
return h(MkSparkle, {}, { default: () => genEl(token.children, scale) });
|
||||
}
|
||||
case 'rotate': {
|
||||
const degrees = safeParseFloat(token.props.args.deg) ?? 90;
|
||||
@@ -363,7 +363,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
|
||||
url: token.props.url,
|
||||
rel: 'nofollow noopener',
|
||||
navigationBehavior: props.linkNavigationBehavior,
|
||||
}, genEl(token.children, scale, true))];
|
||||
}, { default: () => genEl(token.children, scale, true) })];
|
||||
}
|
||||
|
||||
case 'mention': {
|
||||
@@ -381,7 +381,7 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
|
||||
to: isNote ? `/tags/${encodeURIComponent(token.props.hashtag)}` : `/user-tags/${encodeURIComponent(token.props.hashtag)}`,
|
||||
style: 'color:var(--MI_THEME-hashtag);',
|
||||
behavior: props.linkNavigationBehavior,
|
||||
}, `#${token.props.hashtag}`)];
|
||||
}, { default: () => `#${token.props.hashtag}` })];
|
||||
}
|
||||
|
||||
case 'blockCode': {
|
||||
|
||||
@@ -82,8 +82,10 @@ export class Pizzax<T extends StateDef> {
|
||||
this.r = {} as ReactiveState<T>;
|
||||
|
||||
for (const [k, v] of Object.entries(def) as [keyof T, T[keyof T]['default']][]) {
|
||||
this.s[k] = v.default;
|
||||
this.r[k] = ref(v.default);
|
||||
// 参照渡しになるのを防ぐためclone
|
||||
const defaultValue = deepClone(v.default);
|
||||
this.s[k] = defaultValue;
|
||||
this.r[k] = ref(defaultValue);
|
||||
}
|
||||
|
||||
this.ready = this.init();
|
||||
@@ -120,7 +122,8 @@ export class Pizzax<T extends StateDef> {
|
||||
} else if (v.where === 'deviceAccount' && Object.prototype.hasOwnProperty.call(deviceAccountState, k)) {
|
||||
this.r[k].value = this.s[k] = this.mergeState<T[keyof T]['default']>(deviceAccountState[k], v.default);
|
||||
} else {
|
||||
this.r[k].value = this.s[k] = v.default;
|
||||
// 参照渡しになるのを防ぐためclone
|
||||
this.r[k].value = this.s[k] = deepClone(v.default);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +151,8 @@ export class Pizzax<T extends StateDef> {
|
||||
this.r[k].value = this.s[k] = (kvs as Partial<T>)[k];
|
||||
cache[k] = (kvs as Partial<T>)[k];
|
||||
} else {
|
||||
this.r[k].value = this.s[k] = v.default;
|
||||
// 参照渡しになるのを防ぐためclone
|
||||
this.r[k].value = this.s[k] = deepClone(v.default);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,8 +222,10 @@ export class Pizzax<T extends StateDef> {
|
||||
}
|
||||
|
||||
public reset(key: keyof T) {
|
||||
this.set(key, this.def[key].default);
|
||||
return this.def[key].default;
|
||||
// 参照渡しになるのを防ぐためclone
|
||||
const defaultValue = deepClone(this.def[key].default);
|
||||
this.set(key, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
>
|
||||
<template #default="{ item, dragStart }">
|
||||
<div :class="$style.item">
|
||||
<!-- divが無いとエラーになる https://github.com/SortableJS/vue.draggable.next/issues/189 -->
|
||||
<!-- divが無いとエラーになる -->
|
||||
<RolesEditorFormula
|
||||
:modelValue="item"
|
||||
:dragStartCallback="dragStart"
|
||||
|
||||
@@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
>
|
||||
<template #default="{ item }">
|
||||
<div>
|
||||
<!-- divが無いとエラーになる https://github.com/SortableJS/vue.draggable.next/issues/189 -->
|
||||
<!-- divが無いとエラーになる -->
|
||||
<component :is="getComponent(item.type) as any" :modelValue="item" @update:modelValue="updateItem" @remove="() => removeItem(item)"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -51,10 +51,12 @@ import { enableAutoBackup, getPreferencesProfileMenu } from '@/preferences/utili
|
||||
import { store } from '@/store.js';
|
||||
import { signout } from '@/signout.js';
|
||||
import { genSearchIndexes } from '@/utility/inapp-search.js';
|
||||
import { enableStoragePersistence, storagePersisted, storagePersistenceSupported, skipStoragePersistence } from '@/utility/storage.js';
|
||||
import { enableStoragePersistence, getStoragePersistenceStatusRef, storagePersistenceSupported, skipStoragePersistence } from '@/utility/storage.js';
|
||||
|
||||
const searchIndex = await import('search-index:settings').then(({ searchIndexes }) => genSearchIndexes(searchIndexes));
|
||||
|
||||
const storagePersisted = await getStoragePersistenceStatusRef();
|
||||
|
||||
const indexInfo = {
|
||||
title: i18n.ts.settings,
|
||||
icon: 'ti ti-settings',
|
||||
|
||||
@@ -165,7 +165,7 @@ import MkKeyValue from '@/components/MkKeyValue.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import FormSlot from '@/components/form/slot.vue';
|
||||
import * as os from '@/os.js';
|
||||
import { enableStoragePersistence, storagePersisted, storagePersistenceSupported } from '@/utility/storage.js';
|
||||
import { enableStoragePersistence, getStoragePersistenceStatusRef, storagePersistenceSupported } from '@/utility/storage.js';
|
||||
import { ensureSignin } from '@/i.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
@@ -180,6 +180,8 @@ import { cloudBackup } from '@/preferences/utility.js';
|
||||
|
||||
const $i = ensureSignin();
|
||||
|
||||
const storagePersisted = await getStoragePersistenceStatusRef();
|
||||
|
||||
const reportError = prefer.model('reportError');
|
||||
const enableCondensedLine = prefer.model('enableCondensedLine');
|
||||
const skipNoteRender = prefer.model('skipNoteRender');
|
||||
|
||||
@@ -14,6 +14,7 @@ import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import * as os from '@/os.js';
|
||||
import { deepEqual } from '@/utility/deep-equal.js';
|
||||
import { deepClone } from '@/utility/clone.js';
|
||||
|
||||
// NOTE: 明示的な設定値のひとつとして null もあり得るため、設定が存在しないかどうかを判定する目的で null で比較したり ?? を使ってはいけない
|
||||
|
||||
@@ -122,7 +123,8 @@ export function getInitialPrefValue<K extends keyof PREF>(k: K): ValueOf<K> {
|
||||
if (typeof _default === 'function') { // factory
|
||||
return _default() as ValueOf<K>;
|
||||
} else {
|
||||
return _default as unknown as ValueOf<K>;
|
||||
// 参照渡しになるのを防ぐためclone
|
||||
return deepClone(_default as unknown as ValueOf<K>);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,10 @@ const float PI = 3.141592653589793;
|
||||
const float TWO_PI = 6.283185307179586;
|
||||
const float HALF_PI = 1.5707963267948966;
|
||||
|
||||
const float goldenAngle = 2.39996323;
|
||||
const int sampleCount = 256;
|
||||
const float sampleCountF = float(sampleCount);
|
||||
|
||||
in vec2 in_uv;
|
||||
uniform sampler2D in_texture;
|
||||
uniform vec2 in_resolution;
|
||||
@@ -18,7 +22,6 @@ uniform vec2 u_scale;
|
||||
uniform bool u_ellipse;
|
||||
uniform float u_angle;
|
||||
uniform float u_radius;
|
||||
uniform int u_samples;
|
||||
out vec4 out_color;
|
||||
|
||||
float rand(vec2 value) {
|
||||
@@ -51,17 +54,7 @@ void main() {
|
||||
|
||||
vec4 result = vec4(0.0);
|
||||
float totalSamples = 0.0;
|
||||
|
||||
// Make blur radius resolution-independent by using a percentage of image size
|
||||
float referenceSize = min(in_resolution.x, in_resolution.y);
|
||||
float normalizedRadius = u_radius / 100.0;
|
||||
float radiusPx = normalizedRadius * referenceSize;
|
||||
vec2 texelSize = 1.0 / in_resolution;
|
||||
|
||||
int sampleCount = max(u_samples, 1);
|
||||
float sampleCountF = float(sampleCount);
|
||||
float jitter = rand(in_uv * in_resolution);
|
||||
float goldenAngle = 2.39996323;
|
||||
float jitter = rand(in_uv);
|
||||
|
||||
// Sample in a circular pattern to avoid axis-aligned artifacts
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
@@ -69,15 +62,11 @@ void main() {
|
||||
float radius = sqrt((fi + 0.5) / sampleCountF);
|
||||
float theta = (fi + jitter) * goldenAngle;
|
||||
vec2 direction = vec2(cos(theta), sin(theta));
|
||||
vec2 offset = direction * (radiusPx * radius) * texelSize;
|
||||
vec2 sampleUV = in_uv + offset;
|
||||
|
||||
if (sampleUV.x >= 0.0 && sampleUV.x <= 1.0 && sampleUV.y >= 0.0 && sampleUV.y <= 1.0) {
|
||||
float weight = exp(-radius * radius * 4.0);
|
||||
result += texture(in_texture, sampleUV) * weight;
|
||||
totalSamples += weight;
|
||||
}
|
||||
vec2 offset = direction * (u_radius * radius);
|
||||
float weight = exp(-radius * radius * 4.0);
|
||||
result += texture(in_texture, in_uv + offset) * weight;
|
||||
totalSamples += weight;
|
||||
}
|
||||
|
||||
out_color = totalSamples > 0.0 ? result / totalSamples : texture(in_texture, in_uv);
|
||||
out_color = result / totalSamples;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ export const fn = defineImageCompositorFunction<{
|
||||
gl.uniform1i(u.ellipse, params.ellipse ? 1 : 0);
|
||||
gl.uniform1f(u.angle, params.angle / 2);
|
||||
gl.uniform1f(u.radius, params.radius);
|
||||
gl.uniform1i(u.samples, 256);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -84,10 +83,10 @@ export const uiDefinition = {
|
||||
radius: {
|
||||
label: i18n.ts._imageEffector._fxProps.strength,
|
||||
type: 'number',
|
||||
default: 10.0,
|
||||
default: 0.15,
|
||||
min: 0.0,
|
||||
max: 20.0,
|
||||
step: 0.5,
|
||||
max: 0.3,
|
||||
step: 0.01,
|
||||
},
|
||||
},
|
||||
} satisfies ImageEffectorUiDefinition<typeof fn>;
|
||||
|
||||
@@ -14,12 +14,15 @@ uniform sampler2D in_texture;
|
||||
uniform vec2 in_resolution;
|
||||
uniform vec2 u_pos;
|
||||
uniform float u_frequency;
|
||||
uniform bool u_thresholdEnabled;
|
||||
uniform float u_threshold;
|
||||
uniform float u_outlineThickness;
|
||||
uniform float u_maskSize;
|
||||
uniform bool u_black;
|
||||
out vec4 out_color;
|
||||
|
||||
float remap(float value, float inputMin, float inputMax, float outputMin, float outputMax) {
|
||||
return outputMin + (outputMax - outputMin) * ((value - inputMin) / (inputMax - inputMin));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 in_color = texture(in_texture, in_uv);
|
||||
vec2 centeredUv = (in_uv - vec2(0.5, 0.5));
|
||||
@@ -33,16 +36,19 @@ void main() {
|
||||
float noiseY = (noiseUV.y + seed) * u_frequency;
|
||||
float noise = (1.0 + snoise(vec3(noiseX, noiseY, time))) / 2.0;
|
||||
|
||||
float t = noise;
|
||||
if (u_thresholdEnabled) t = t < u_threshold ? 1.0 : 0.0;
|
||||
if (noise < u_threshold) {
|
||||
out_color = in_color;
|
||||
} else {
|
||||
float n = remap(noise, u_threshold, 1.0, 0.0, 1.0);
|
||||
|
||||
// TODO: マスクの形自体も揺らぎを与える
|
||||
float d = distance(uv * vec2(2.0, 2.0), u_pos * vec2(2.0, 2.0));
|
||||
float mask = d < u_maskSize ? 0.0 : ((d - u_maskSize) * (1.0 + (u_maskSize * 2.0)));
|
||||
out_color = vec4(
|
||||
mix(in_color.r, u_black ? 0.0 : 1.0, t * mask),
|
||||
mix(in_color.g, u_black ? 0.0 : 1.0, t * mask),
|
||||
mix(in_color.b, u_black ? 0.0 : 1.0, t * mask),
|
||||
in_color.a
|
||||
);
|
||||
// TODO: マスクの形自体も揺らぎを与える
|
||||
float d = distance(uv * vec2(2.0, 2.0), u_pos * vec2(2.0, 2.0));
|
||||
float mask = d < u_maskSize ? 0.0 : ((d - u_maskSize) * (1.0 + (u_maskSize * 2.0)));
|
||||
out_color = vec4(
|
||||
mix(in_color.r, n < u_outlineThickness ? 0.0 : 1.0, mask),
|
||||
mix(in_color.g, n < u_outlineThickness ? 0.0 : 1.0, mask),
|
||||
mix(in_color.b, n < u_outlineThickness ? 0.0 : 1.0, mask),
|
||||
in_color.a
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,20 +12,17 @@ export const fn = defineImageCompositorFunction<{
|
||||
x: number;
|
||||
y: number;
|
||||
frequency: number;
|
||||
smoothing: boolean;
|
||||
threshold: number;
|
||||
density: number;
|
||||
outlineThickness: number;
|
||||
maskSize: number;
|
||||
black: boolean;
|
||||
}>({
|
||||
shader,
|
||||
main: ({ gl, u, params }) => {
|
||||
gl.uniform2f(u.pos, params.x / 2, params.y / 2);
|
||||
gl.uniform1f(u.frequency, params.frequency * params.frequency);
|
||||
// thresholdの調整が有効な間はsmoothingが利用できない
|
||||
gl.uniform1i(u.thresholdEnabled, params.smoothing ? 0 : 1);
|
||||
gl.uniform1f(u.threshold, params.threshold);
|
||||
gl.uniform1f(u.threshold, 1.0 - params.density);
|
||||
gl.uniform1f(u.outlineThickness, params.outlineThickness);
|
||||
gl.uniform1f(u.maskSize, params.maskSize);
|
||||
gl.uniform1i(u.black, params.black ? 1 : 0);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -56,20 +53,22 @@ export const uiDefinition = {
|
||||
max: 15.0,
|
||||
step: 0.1,
|
||||
},
|
||||
smoothing: {
|
||||
label: i18n.ts._imageEffector._fxProps.zoomLinesSmoothing,
|
||||
caption: i18n.ts._imageEffector._fxProps.zoomLinesSmoothingDescription,
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
threshold: {
|
||||
label: i18n.ts._imageEffector._fxProps.zoomLinesThreshold,
|
||||
density: {
|
||||
label: i18n.ts._imageEffector._fxProps.density,
|
||||
type: 'number',
|
||||
default: 0.5,
|
||||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
},
|
||||
outlineThickness: {
|
||||
label: i18n.ts._imageEffector._fxProps.zoomLinesOutlineThickness,
|
||||
type: 'number',
|
||||
default: 0.25,
|
||||
min: 0.0,
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
},
|
||||
maskSize: {
|
||||
label: i18n.ts._imageEffector._fxProps.zoomLinesMaskSize,
|
||||
type: 'number',
|
||||
@@ -78,10 +77,5 @@ export const uiDefinition = {
|
||||
max: 1.0,
|
||||
step: 0.01,
|
||||
},
|
||||
black: {
|
||||
label: i18n.ts._imageEffector._fxProps.zoomLinesBlack,
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
} satisfies ImageEffectorUiDefinition<typeof fn>;
|
||||
|
||||
@@ -3,13 +3,21 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
import { ref } from 'vue';
|
||||
import { readonly, ref } from 'vue';
|
||||
import * as os from '@/os.js';
|
||||
import { store } from '@/store.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
|
||||
export const storagePersistenceSupported = window.isSecureContext && 'storage' in navigator;
|
||||
export const storagePersisted = ref(storagePersistenceSupported ? await navigator.storage.persisted() : false);
|
||||
const storagePersisted = ref(false);
|
||||
|
||||
export async function getStoragePersistenceStatusRef() {
|
||||
if (storagePersistenceSupported) {
|
||||
storagePersisted.value = await navigator.storage.persisted().catch(() => false);
|
||||
}
|
||||
|
||||
return readonly(storagePersisted);
|
||||
}
|
||||
|
||||
export async function enableStoragePersistence() {
|
||||
if (!storagePersistenceSupported) return;
|
||||
|
||||
@@ -30,7 +30,7 @@ import { useLowresTime } from '@/composables/use-lowres-time.js';
|
||||
import { userPage, acct } from '@/filters/user.js';
|
||||
|
||||
const props = defineProps<{
|
||||
item: Misskey.entities.UsersGetFollowingBirthdayUsersResponse[number];
|
||||
item: Misskey.entities.UsersGetFollowingUsersByBirthdayResponse[number];
|
||||
}>();
|
||||
|
||||
const now = useLowresTime();
|
||||
|
||||
@@ -106,7 +106,7 @@ const end = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
const birthdayUsersPaginator = markRaw(new Paginator('users/get-following-birthday-users', {
|
||||
const birthdayUsersPaginator = markRaw(new Paginator('users/get-following-users-by-birthday', {
|
||||
limit: 18,
|
||||
offsetMode: true,
|
||||
computedParams: computed(() => {
|
||||
|
||||
Reference in New Issue
Block a user