refactor and fix
This commit is contained in:
parent
dbb6c71c5c
commit
eb9915baf8
|
@ -55,6 +55,7 @@
|
||||||
- Fix: メンションとしての条件を満たしていても、特定の条件(`-`が含まれる場合など)で正しくサジェストされない問題を一部修正
|
- Fix: メンションとしての条件を満たしていても、特定の条件(`-`が含まれる場合など)で正しくサジェストされない問題を一部修正
|
||||||
- Fix: ユーザーの前後ノートを閲覧する機能が動作しない問題を修正
|
- Fix: ユーザーの前後ノートを閲覧する機能が動作しない問題を修正
|
||||||
- Fix: 照会ダイアログでap/showでローカルユーザーを解決した際@username@nullに飛ばされる問題を修正
|
- Fix: 照会ダイアログでap/showでローカルユーザーを解決した際@username@nullに飛ばされる問題を修正
|
||||||
|
- Fix: アイコンのデコレーションを付ける際にデコレーションが表示されなくなる問題を修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
- Feat: サーバー管理コマンド
|
- Feat: サーバー管理コマンド
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { markRaw, ref, defineAsyncComponent, nextTick } from 'vue';
|
||||||
import { EventEmitter } from 'eventemitter3';
|
import { EventEmitter } from 'eventemitter3';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import type { Component, Ref } from 'vue';
|
import type { Component, Ref } from 'vue';
|
||||||
import type { ComponentProps as CP } from 'vue-component-type-helpers';
|
import type { ComponentEmit, ComponentProps as CP } from 'vue-component-type-helpers';
|
||||||
import type { Form, GetFormResultType } from '@/utility/form.js';
|
import type { Form, GetFormResultType } from '@/utility/form.js';
|
||||||
import type { MenuItem } from '@/types/menu.js';
|
import type { MenuItem } from '@/types/menu.js';
|
||||||
import type { PostFormProps } from '@/types/post-form.js';
|
import type { PostFormProps } from '@/types/post-form.js';
|
||||||
|
@ -157,28 +157,9 @@ export function claimZIndex(priority: keyof typeof zIndexes = 'low'): number {
|
||||||
return zIndexes[priority];
|
return zIndexes[priority];
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstanceType<typeof Component>['$emit'] だとインターセクション型が返ってきて
|
|
||||||
// 使い物にならないので、代わりに ['$props'] から色々省くことで emit の型を生成する
|
|
||||||
// FIXME: 何故か *.ts ファイルからだと型がうまく取れない?ことがあるのをなんとかしたい
|
|
||||||
type ComponentEmit<T> = T extends new () => { $props: infer Props }
|
|
||||||
? [keyof Pick<T, Extract<keyof T, `on${string}`>>] extends [never]
|
|
||||||
? Record<string, unknown> // *.ts ファイルから型がうまく取れないとき用(これがないと {} になって型エラーがうるさい)
|
|
||||||
: EmitsExtractor<Props>
|
|
||||||
: T extends (...args: any) => any
|
|
||||||
? ReturnType<T> extends { [x: string]: any; __ctx?: { [x: string]: any; props: infer Props } }
|
|
||||||
? [keyof Pick<T, Extract<keyof T, `on${string}`>>] extends [never]
|
|
||||||
? Record<string, unknown>
|
|
||||||
: EmitsExtractor<Props>
|
|
||||||
: never
|
|
||||||
: never;
|
|
||||||
|
|
||||||
// props に ref を許可するようにする
|
// props に ref を許可するようにする
|
||||||
type ComponentProps<T extends Component> = { [K in keyof CP<T>]: CP<T>[K] | Ref<CP<T>[K]> };
|
type ComponentProps<T extends Component> = { [K in keyof CP<T>]: CP<T>[K] | Ref<CP<T>[K]> };
|
||||||
|
|
||||||
type EmitsExtractor<T> = {
|
|
||||||
[K in keyof T as K extends `onVnode${string}` ? never : K extends `on${infer E}` ? Uncapitalize<E> : K extends string ? never : K]: T[K];
|
|
||||||
};
|
|
||||||
|
|
||||||
export function popup<T extends Component>(
|
export function popup<T extends Component>(
|
||||||
component: T,
|
component: T,
|
||||||
props: ComponentProps<T>,
|
props: ComponentProps<T>,
|
||||||
|
|
|
@ -17,13 +17,13 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div :class="$style.decorations">
|
<div :class="$style.decorations">
|
||||||
<XDecoration
|
<XDecoration
|
||||||
v-for="(avatarDecoration, i) in $i.avatarDecorations"
|
v-for="(avatarDecoration, i) in $i.avatarDecorations"
|
||||||
:decoration="avatarDecorations.find(d => d.id === avatarDecoration.id)"
|
:decoration="avatarDecorations.find(d => d.id === avatarDecoration.id) ?? { id: '', url: '', name: '?', roleIdsThatCanBeUsedThisDecoration: [] }"
|
||||||
:angle="avatarDecoration.angle"
|
:angle="avatarDecoration.angle"
|
||||||
:flipH="avatarDecoration.flipH"
|
:flipH="avatarDecoration.flipH"
|
||||||
:offsetX="avatarDecoration.offsetX"
|
:offsetX="avatarDecoration.offsetX"
|
||||||
:offsetY="avatarDecoration.offsetY"
|
:offsetY="avatarDecoration.offsetY"
|
||||||
:active="true"
|
:active="true"
|
||||||
@click="openDecoration(avatarDecoration, i)"
|
@click="openAttachedDecoration(i)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
import { ref, defineAsyncComponent, computed } from 'vue';
|
import { ref, defineAsyncComponent, computed } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import XDecoration from './avatar-decoration.decoration.vue';
|
import XDecoration from './avatar-decoration.decoration.vue';
|
||||||
|
import XDialog from './avatar-decoration.dialog.vue';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import * as os from '@/os.js';
|
import * as os from '@/os.js';
|
||||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||||
|
@ -68,14 +69,24 @@ misskeyApi('get-avatar-decorations').then(_avatarDecorations => {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
async function openDecoration(avatarDecoration, index?: number) {
|
function openAttachedDecoration(index: number) {
|
||||||
const { dispose } = await os.popupAsyncWithDialog(import('./avatar-decoration.dialog.vue').then(x => x.default), {
|
openDecoration(avatarDecorations.value.find(d => d.id === $i.avatarDecorations[index].id) ?? { id: '', url: '', name: '?', roleIdsThatCanBeUsedThisDecoration: [] }, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openDecoration(avatarDecoration: {
|
||||||
|
id: string;
|
||||||
|
url: string;
|
||||||
|
name: string;
|
||||||
|
roleIdsThatCanBeUsedThisDecoration: string[];
|
||||||
|
}, index?: number) {
|
||||||
|
const { dispose } = os.popup(XDialog, {
|
||||||
decoration: avatarDecoration,
|
decoration: avatarDecoration,
|
||||||
usingIndex: index,
|
usingIndex: index ?? null,
|
||||||
}, {
|
}, {
|
||||||
'attach': async (payload) => {
|
'attach': async (payload) => {
|
||||||
const decoration = {
|
const decoration = {
|
||||||
id: avatarDecoration.id,
|
id: avatarDecoration.id,
|
||||||
|
url: avatarDecoration.url,
|
||||||
angle: payload.angle,
|
angle: payload.angle,
|
||||||
flipH: payload.flipH,
|
flipH: payload.flipH,
|
||||||
offsetX: payload.offsetX,
|
offsetX: payload.offsetX,
|
||||||
|
@ -90,6 +101,7 @@ async function openDecoration(avatarDecoration, index?: number) {
|
||||||
'update': async (payload) => {
|
'update': async (payload) => {
|
||||||
const decoration = {
|
const decoration = {
|
||||||
id: avatarDecoration.id,
|
id: avatarDecoration.id,
|
||||||
|
url: avatarDecoration.url,
|
||||||
angle: payload.angle,
|
angle: payload.angle,
|
||||||
flipH: payload.flipH,
|
flipH: payload.flipH,
|
||||||
offsetX: payload.offsetX,
|
offsetX: payload.offsetX,
|
||||||
|
|
|
@ -43,7 +43,7 @@ async function edit() {
|
||||||
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkWatermarkEditorDialog.vue')), {
|
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkWatermarkEditorDialog.vue')), {
|
||||||
preset: deepClone(props.preset),
|
preset: deepClone(props.preset),
|
||||||
}, {
|
}, {
|
||||||
ok: (preset: WatermarkPreset) => {
|
ok: (preset) => {
|
||||||
emit('updatePreset', preset);
|
emit('updatePreset', preset);
|
||||||
},
|
},
|
||||||
closed: () => dispose(),
|
closed: () => dispose(),
|
||||||
|
|
Loading…
Reference in New Issue