refactor: frontendのcomponentsの型エラーを改善 (#12926)
* add: safeFloatParserを追加 * fix: 欠けていた型を追加 * refactor: pageBlockTypesをjson-schemaに移植 * refactor: components/global内の型エラーが出ている箇所を修正 * lint: fix null check style * refactor: fix type error * refactor: fix some type errors * fix: 翻訳が抜けていた箇所を修正 * refactor: getJsonSchemaで正しいスキーマが返されるように修正 * fix: MkChartの型エラーとbytesオプションが機能していない問題を修正 * fix(misskey-js): `drive`->`folderUpdated`のpayloadの型が間違っていたのを修正 * refactor: fix some type errors * change: Captcha読み込み中の文言をLoadingに変更 * refactor(backend/misskey-js): MainEventの型を改善 * refactor: chartjs-plugin-gradientが二重でpluginに登録されていたのを修正 * update: misskey-js.api.md * refactor: fix some type errors * fix: backendのtypecheckが落ちていたのを修正 * update: misskey-js.api.md * add: json-schemaのnoteにpollの型定義を追加 * refactor: noteのjson-schemaの型を改善 * refactor: MkPoll * refactor: fix some type errors * change: UserLiteにisLockedを持たせるように * fix: notificationスキーマにroleが含まれていないのを修正 * Revert "change: UserLiteにisLockedを持たせるように" This reverts commit 1bb0c8e7a9b19a4e9f21bf7381712b98f27672a5. * fix: フォロー通知から鍵垢へのフォローを行うと処理中のまま止まってしまう問題を修正 * refactor: noteスキーマのvisibilityにenumを追加 * change: deepCloneのCloneableTypeにundefinedを追加 * refactor: fix some type errors * refactor: `allowEmpty: false`を使用していた箇所を`minLength: 1`に置き換え * enhance: API 'retension' のresponseの型を追加 * fix: Chart関連のtooltipが正しい位置に表示されない問題を修正 * refactor: fix some type errors * fix: 型情報が不足していたのを修正 * enhance: announcementスキーマにenumを追加 * enhance: ロールポリシーの型定義をRoleServiceからjson-schemaに移植 * refactor: policiesを`ref: RolePolicies`に統一 * fix: API `meta` のレスポンスの型にpoliciesが含まれていないのを修正 * refactor: fix some type errors * fix: backendのlintが落ちているのを修正 * fix: MkFoldableSectionの開閉時のanimationが適用されていない問題を修正 * fix: backendのtypecheckが落ちているのを修正 * update: run build-misskey-js-with-types * fix: MkDialogのmount時に文字数制限の判定が行われない問題を修正 * update: CHANGELOG.md * refactor: MkUserSelectDialogの型を改善 * fix: deepCloneでundefinedはcloneしないように (#9207) * change: frontendのcloneをbackend側にも反映 * update: CHANGELOG.md * fix: RoleServiceからPackを通して型RolePoliciesに依存させないように * Update packages/frontend/src/scripts/get-note-summary.ts * revert RoleService.ts changes * change: optional chaining -> non-null assertion * remove: unused import * fix: propsで渡されたuserがUserLiteの場合に意図しない動作になってしまうのを修正 * change: fix null check style * refactor: fix type error * change: fix null check style * Update packages/frontend/src/components/MkDrive.vue Co-authored-by: syuilo <Syuilotan@yahoo.co.jp> * refactor: css moduleでglobalを使わないように * refactor: roleのiconUrlは必ず存在するものとして扱うように * enhance: MenuButtonのactiveにcomputedを受け付けられるように * Update packages/frontend/src/components/MkNotePreview.vue * Update MkWindow.vue * refactor: notification.noteは必ず存在するものとして扱うように * Update packages/frontend/src/components/MkNotification.vue Co-authored-by: syuilo <Syuilotan@yahoo.co.jp> * fix: MkSignupDialogでdoneのemit時にresを含んでいなかったのを修正 * Update packages/frontend/src/scripts/clone.ts Co-authored-by: syuilo <Syuilotan@yahoo.co.jp> * refactor: 不要な返り値の型を削除 * refactor: 不要なnullチェックを削除 * update: misskey-js-autogen * update: clone.ts * refactor * Update MkNotification.vue * Update MkNotification.vue * ✌️ * Update MkNotification.vue * Update MkNotification.vue * Update MkNotification.vue * Update MkNotifications.vue * Update MkUserSetupDialog.Profile.vue * Update MkUserCardMini.vue * ✌️ * Update MkMenu.vue --------- Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
parent
9ac2c36d76
commit
a6a91fec3a
139 changed files with 1944 additions and 1193 deletions
|
@ -21,7 +21,7 @@ import { host as hostRaw } from '@/config.js';
|
|||
import { defaultStore } from '@/store.js';
|
||||
|
||||
defineProps<{
|
||||
user: Misskey.entities.UserDetailed;
|
||||
user: Misskey.entities.User;
|
||||
detail?: boolean;
|
||||
}>();
|
||||
|
||||
|
|
|
@ -81,9 +81,11 @@ const bound = computed(() => props.link
|
|||
? { to: userPage(props.user), target: props.target }
|
||||
: {});
|
||||
|
||||
const url = computed(() => (defaultStore.state.disableShowingAnimatedImages || defaultStore.state.dataSaver.avatar)
|
||||
? getStaticImageUrl(props.user.avatarUrl)
|
||||
: props.user.avatarUrl);
|
||||
const url = computed(() => {
|
||||
if (props.user.avatarUrl == null) return null;
|
||||
if (defaultStore.state.disableShowingAnimatedImages || defaultStore.state.dataSaver.avatar) return getStaticImageUrl(props.user.avatarUrl);
|
||||
return props.user.avatarUrl;
|
||||
});
|
||||
|
||||
function onClick(ev: MouseEvent): void {
|
||||
if (props.link) return;
|
||||
|
@ -109,6 +111,7 @@ function getDecorationOffset(decoration: Omit<Misskey.entities.UserDetailed['ava
|
|||
const color = ref<string | undefined>();
|
||||
|
||||
watch(() => props.user.avatarBlurhash, () => {
|
||||
if (props.user.avatarBlurhash == null) return;
|
||||
color.value = extractAvgColorFromBlurhash(props.user.avatarBlurhash);
|
||||
}, {
|
||||
immediate: true,
|
||||
|
|
|
@ -57,7 +57,7 @@ const rawUrl = computed(() => {
|
|||
});
|
||||
|
||||
const url = computed(() => {
|
||||
if (rawUrl.value == null) return null;
|
||||
if (rawUrl.value == null) return undefined;
|
||||
|
||||
const proxied =
|
||||
(rawUrl.value.startsWith('/emoji/') || (props.useOriginalSize && isLocal.value))
|
||||
|
|
|
@ -20,6 +20,7 @@ import MkA from '@/components/global/MkA.vue';
|
|||
import { host } from '@/config.js';
|
||||
import { defaultStore } from '@/store.js';
|
||||
import { nyaize as doNyaize } from '@/scripts/nyaize.js';
|
||||
import { safeParseFloat } from '@/scripts/safe-parse.js';
|
||||
|
||||
const QUOTE_STYLE = `
|
||||
display: block;
|
||||
|
@ -36,7 +37,7 @@ type MfmProps = {
|
|||
nowrap?: boolean;
|
||||
author?: Misskey.entities.UserLite;
|
||||
isNote?: boolean;
|
||||
emojiUrls?: string[];
|
||||
emojiUrls?: Record<string, string>;
|
||||
rootScale?: number;
|
||||
nyaize?: boolean | 'respect';
|
||||
parsedNodes?: mfm.MfmNode[] | null;
|
||||
|
@ -49,7 +50,7 @@ type MfmEvents = {
|
|||
};
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
||||
export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEvents>['emit'] }) {
|
||||
const isNote = props.isNote ?? true;
|
||||
const shouldNyaize = props.nyaize ? props.nyaize === 'respect' ? props.author?.isCat : false : false;
|
||||
|
||||
|
@ -58,13 +59,14 @@ export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
|||
|
||||
const rootAst = props.parsedNodes ?? (props.plain ? mfm.parseSimple : mfm.parse)(props.text);
|
||||
|
||||
const validTime = (t: string | null | undefined) => {
|
||||
const validTime = (t: string | boolean | null | undefined) => {
|
||||
if (t == null) return null;
|
||||
if (typeof t === 'boolean') return null;
|
||||
return t.match(/^[0-9.]+s$/) ? t : null;
|
||||
};
|
||||
|
||||
const validColor = (c: string | null | undefined): string | null => {
|
||||
if (c == null) return null;
|
||||
const validColor = (c: unknown): string | null => {
|
||||
if (typeof c !== 'string') return null;
|
||||
return c.match(/^[0-9a-f]{3,6}$/i) ? c : null;
|
||||
};
|
||||
|
||||
|
@ -223,14 +225,14 @@ export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
|||
return h(MkSparkle, {}, genEl(token.children, scale));
|
||||
}
|
||||
case 'rotate': {
|
||||
const degrees = parseFloat(token.props.args.deg ?? '90');
|
||||
const degrees = safeParseFloat(token.props.args.deg) ?? 90;
|
||||
style = `transform: rotate(${degrees}deg); transform-origin: center center;`;
|
||||
break;
|
||||
}
|
||||
case 'position': {
|
||||
if (!defaultStore.state.advancedMfm) break;
|
||||
const x = parseFloat(token.props.args.x ?? '0');
|
||||
const y = parseFloat(token.props.args.y ?? '0');
|
||||
const x = safeParseFloat(token.props.args.x) ?? 0;
|
||||
const y = safeParseFloat(token.props.args.y) ?? 0;
|
||||
style = `transform: translateX(${x}em) translateY(${y}em);`;
|
||||
break;
|
||||
}
|
||||
|
@ -239,8 +241,8 @@ export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
|||
style = '';
|
||||
break;
|
||||
}
|
||||
const x = Math.min(parseFloat(token.props.args.x ?? '1'), 5);
|
||||
const y = Math.min(parseFloat(token.props.args.y ?? '1'), 5);
|
||||
const x = Math.min(safeParseFloat(token.props.args.x) ?? 1, 5);
|
||||
const y = Math.min(safeParseFloat(token.props.args.y) ?? 1, 5);
|
||||
style = `transform: scale(${x}, ${y});`;
|
||||
scale = scale * Math.max(x, y);
|
||||
break;
|
||||
|
@ -262,11 +264,12 @@ export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
|||
color = color ? `#${color}` : 'var(--accent)';
|
||||
let b_style = token.props.args.style;
|
||||
if (
|
||||
typeof b_style !== 'string' ||
|
||||
!['hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset']
|
||||
.includes(b_style)
|
||||
) b_style = 'solid';
|
||||
const width = parseFloat(token.props.args.width ?? '1');
|
||||
const radius = parseFloat(token.props.args.radius ?? '0');
|
||||
const width = safeParseFloat(token.props.args.width) ?? 1;
|
||||
const radius = safeParseFloat(token.props.args.radius) ?? 0;
|
||||
style = `border: ${width}px ${b_style} ${color}; border-radius: ${radius}px;${token.props.args.noclip ? '' : ' overflow: clip;'}`;
|
||||
break;
|
||||
}
|
||||
|
@ -308,7 +311,8 @@ export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
|||
return h('span', { onClick(ev: MouseEvent): void {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
context.emit('clickEv', token.props.args.ev ?? '');
|
||||
const clickEv = typeof token.props.args.ev === 'string' ? token.props.args.ev : '';
|
||||
emit('clickEv', clickEv);
|
||||
} }, genEl(token.children, scale));
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +373,7 @@ export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
|||
return [h(MkCode, {
|
||||
key: Math.random(),
|
||||
code: token.props.code,
|
||||
lang: token.props.lang,
|
||||
lang: token.props.lang ?? undefined,
|
||||
})];
|
||||
}
|
||||
|
||||
|
@ -412,8 +416,7 @@ export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
|||
return [h(MkCustomEmoji, {
|
||||
key: Math.random(),
|
||||
name: token.props.name,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
url: props.emojiUrls ? props.emojiUrls[token.props.name] : null,
|
||||
url: props.emojiUrls && props.emojiUrls[token.props.name],
|
||||
normal: props.plain,
|
||||
host: props.author.host,
|
||||
useOriginalSize: scale >= 2.5,
|
||||
|
|
|
@ -38,6 +38,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<script lang="ts">
|
||||
export type Tab = {
|
||||
key: string;
|
||||
title: string;
|
||||
onClick?: (ev: MouseEvent) => void;
|
||||
} & (
|
||||
| {
|
||||
|
@ -120,8 +121,9 @@ function onTabWheel(ev: WheelEvent) {
|
|||
|
||||
let entering = false;
|
||||
|
||||
async function enter(el: HTMLElement) {
|
||||
async function enter(element: Element) {
|
||||
entering = true;
|
||||
const el = element as HTMLElement;
|
||||
const elementWidth = el.getBoundingClientRect().width;
|
||||
el.style.width = '0';
|
||||
el.style.paddingLeft = '0';
|
||||
|
@ -135,11 +137,12 @@ async function enter(el: HTMLElement) {
|
|||
setTimeout(renderTab, 170);
|
||||
}
|
||||
|
||||
function afterEnter(el: HTMLElement) {
|
||||
function afterEnter(element: Element) {
|
||||
//el.style.width = '';
|
||||
}
|
||||
|
||||
async function leave(el: HTMLElement) {
|
||||
async function leave(element: Element) {
|
||||
const el = element as HTMLElement;
|
||||
const elementWidth = el.getBoundingClientRect().width;
|
||||
el.style.width = elementWidth + 'px';
|
||||
el.style.paddingLeft = '';
|
||||
|
@ -148,7 +151,8 @@ async function leave(el: HTMLElement) {
|
|||
el.style.paddingLeft = '0';
|
||||
}
|
||||
|
||||
function afterLeave(el: HTMLElement) {
|
||||
function afterLeave(element: Element) {
|
||||
const el = element as HTMLElement;
|
||||
el.style.width = '';
|
||||
}
|
||||
|
||||
|
|
|
@ -63,27 +63,32 @@ onMounted(() => {
|
|||
watch([parentStickyTop, parentStickyBottom], calc);
|
||||
|
||||
watch(childStickyTop, () => {
|
||||
if (bodyEl.value == null) return;
|
||||
bodyEl.value.style.setProperty('--stickyTop', `${childStickyTop.value}px`);
|
||||
}, {
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
watch(childStickyBottom, () => {
|
||||
if (bodyEl.value == null) return;
|
||||
bodyEl.value.style.setProperty('--stickyBottom', `${childStickyBottom.value}px`);
|
||||
}, {
|
||||
immediate: true,
|
||||
});
|
||||
|
||||
headerEl.value.style.position = 'sticky';
|
||||
headerEl.value.style.top = 'var(--stickyTop, 0)';
|
||||
headerEl.value.style.zIndex = '1000';
|
||||
if (headerEl.value != null) {
|
||||
headerEl.value.style.position = 'sticky';
|
||||
headerEl.value.style.top = 'var(--stickyTop, 0)';
|
||||
headerEl.value.style.zIndex = '1000';
|
||||
observer.observe(headerEl.value);
|
||||
}
|
||||
|
||||
footerEl.value.style.position = 'sticky';
|
||||
footerEl.value.style.bottom = 'var(--stickyBottom, 0)';
|
||||
footerEl.value.style.zIndex = '1000';
|
||||
|
||||
observer.observe(headerEl.value);
|
||||
observer.observe(footerEl.value);
|
||||
if (footerEl.value != null) {
|
||||
footerEl.value.style.position = 'sticky';
|
||||
footerEl.value.style.bottom = 'var(--stickyBottom, 0)';
|
||||
footerEl.value.style.zIndex = '1000';
|
||||
observer.observe(footerEl.value);
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
|
|
|
@ -24,7 +24,7 @@ const props = withDefaults(defineProps<{
|
|||
mode?: 'relative' | 'absolute' | 'detail';
|
||||
colored?: boolean;
|
||||
}>(), {
|
||||
origin: isChromatic() ? new Date('2023-04-01T00:00:00Z') : null,
|
||||
origin: isChromatic() ? () => new Date('2023-04-01T00:00:00Z') : null,
|
||||
mode: 'relative',
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue