refactor(frontend): フロントエンドの型エラー解消 (#16694)
This commit is contained in:
parent
4988719a2e
commit
d203e1a446
|
|
@ -39,13 +39,18 @@ for (let i = 0; i < emojilist.length; i++) {
|
||||||
|
|
||||||
export const emojiCharByCategory = _charGroupByCategory;
|
export const emojiCharByCategory = _charGroupByCategory;
|
||||||
|
|
||||||
export function getUnicodeEmoji(char: string): UnicodeEmojiDef | string {
|
export function getUnicodeEmojiOrNull(char: string): UnicodeEmojiDef | null {
|
||||||
// Colorize it because emojilist.json assumes that
|
// Colorize it because emojilist.json assumes that
|
||||||
return unicodeEmojisMap.get(colorizeEmoji(char))
|
return unicodeEmojisMap.get(colorizeEmoji(char))
|
||||||
// カラースタイル絵文字がjsonに無い場合はテキストスタイル絵文字にフォールバックする
|
// カラースタイル絵文字がjsonに無い場合はテキストスタイル絵文字にフォールバックする
|
||||||
?? unicodeEmojisMap.get(char)
|
?? unicodeEmojisMap.get(char)
|
||||||
// それでも見つからない場合はそのまま返す(絵文字情報がjsonに無い場合、このフォールバックが無いとレンダリングに失敗する)
|
// それでも見つからない場合はnullを返す
|
||||||
?? char;
|
?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getUnicodeEmoji(char: string): UnicodeEmojiDef | string {
|
||||||
|
// 絵文字が見つからない場合はそのまま返す(絵文字情報がjsonに無い場合、このフォールバックが無いとレンダリングに失敗する)
|
||||||
|
return getUnicodeEmojiOrNull(char) ?? char;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isSupportedEmoji(char: string): boolean {
|
export function isSupportedEmoji(char: string): boolean {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, inject, onMounted, useTemplateRef, watch } from 'vue';
|
import { computed, inject, onMounted, useTemplateRef, watch } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { getUnicodeEmoji } from '@@/js/emojilist.js';
|
import { getUnicodeEmojiOrNull } from '@@/js/emojilist.js';
|
||||||
import MkCustomEmojiDetailedDialog from './MkCustomEmojiDetailedDialog.vue';
|
import MkCustomEmojiDetailedDialog from './MkCustomEmojiDetailedDialog.vue';
|
||||||
import type { MenuItem } from '@/types/menu';
|
import type { MenuItem } from '@/types/menu';
|
||||||
import XDetails from '@/components/MkReactionsViewer.details.vue';
|
import XDetails from '@/components/MkReactionsViewer.details.vue';
|
||||||
|
|
@ -60,11 +60,11 @@ const buttonEl = useTemplateRef('buttonEl');
|
||||||
const emojiName = computed(() => props.reaction.replace(/:/g, '').replace(/@\./, ''));
|
const emojiName = computed(() => props.reaction.replace(/:/g, '').replace(/@\./, ''));
|
||||||
|
|
||||||
const canToggle = computed(() => {
|
const canToggle = computed(() => {
|
||||||
const emoji = customEmojisMap.get(emojiName.value) ?? getUnicodeEmoji(props.reaction);
|
const emoji = customEmojisMap.get(emojiName.value) ?? getUnicodeEmojiOrNull(props.reaction);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
//return !props.reaction.match(/@\w/) && $i && emoji && checkReactionPermissions($i, props.note, emoji);
|
//return !props.reaction.match(/@\w/) && $i && emoji && checkReactionPermissions($i, props.note, emoji);
|
||||||
return !props.reaction.match(/@\w/) && $i && emoji;
|
return props.reaction.match(/@\w/) == null && $i != null && emoji != null;
|
||||||
});
|
});
|
||||||
const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':'));
|
const canGetInfo = computed(() => !props.reaction.match(/@\w/) && props.reaction.includes(':'));
|
||||||
const isLocalCustomEmoji = props.reaction[0] === ':' && props.reaction.includes('@.');
|
const isLocalCustomEmoji = props.reaction[0] === ':' && props.reaction.includes('@.');
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,8 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { Awaitable } from '@/types/misc.js';
|
||||||
|
|
||||||
export type SuperMenuDef = {
|
export type SuperMenuDef = {
|
||||||
title?: string;
|
title?: string;
|
||||||
items: ({
|
items: ({
|
||||||
|
|
@ -80,7 +82,7 @@ export type SuperMenuDef = {
|
||||||
text: string;
|
text: string;
|
||||||
danger?: boolean;
|
danger?: boolean;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
action: (ev: MouseEvent) => void | Promise<void>;
|
action: (ev: MouseEvent) => Awaitable<void>;
|
||||||
} | {
|
} | {
|
||||||
type?: 'link';
|
type?: 'link';
|
||||||
to: string;
|
to: string;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import { throttle } from 'throttle-debounce';
|
import { throttle } from 'throttle-debounce';
|
||||||
import type { Directive } from 'vue';
|
import type { Directive } from 'vue';
|
||||||
|
import type { Awaitable } from '@/types/misc.js';
|
||||||
|
|
||||||
interface HTMLElementWithObserver extends HTMLElement {
|
interface HTMLElementWithObserver extends HTMLElement {
|
||||||
_observer_?: IntersectionObserver;
|
_observer_?: IntersectionObserver;
|
||||||
|
|
@ -31,4 +32,4 @@ export const appearDirective = {
|
||||||
unmounted(src) {
|
unmounted(src) {
|
||||||
if (src._observer_) src._observer_.disconnect();
|
if (src._observer_) src._observer_.disconnect();
|
||||||
},
|
},
|
||||||
} as Directive<HTMLElementWithObserver, () => void>;
|
} as Directive<HTMLElementWithObserver, (() => Awaitable<void>) | null | undefined>;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const start = isTouchUsing ? 'touchstart' : 'mouseenter';
|
||||||
const end = isTouchUsing ? 'touchend' : 'mouseleave';
|
const end = isTouchUsing ? 'touchend' : 'mouseleave';
|
||||||
|
|
||||||
type TooltipDirectiveState = {
|
type TooltipDirectiveState = {
|
||||||
text: string;
|
text: string | null | undefined;
|
||||||
_close: null | (() => void);
|
_close: null | (() => void);
|
||||||
showTimer: number | null;
|
showTimer: number | null;
|
||||||
hideTimer: number | null;
|
hideTimer: number | null;
|
||||||
|
|
@ -53,6 +53,7 @@ export const tooltipDirective = {
|
||||||
|
|
||||||
if (binding.arg === 'dialog') {
|
if (binding.arg === 'dialog') {
|
||||||
el.addEventListener('click', (ev) => {
|
el.addEventListener('click', (ev) => {
|
||||||
|
if (binding.value == null) return;
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
alert({
|
alert({
|
||||||
|
|
@ -128,4 +129,4 @@ export const tooltipDirective = {
|
||||||
if (self.checkTimer) window.clearTimeout(self.checkTimer);
|
if (self.checkTimer) window.clearTimeout(self.checkTimer);
|
||||||
self.close();
|
self.close();
|
||||||
},
|
},
|
||||||
} as Directive<TooltipDirectiveElement, string, TooltipDirectiveModifiers, TooltipDirectiveArg>;
|
} as Directive<TooltipDirectiveElement, string | null | undefined, TooltipDirectiveModifiers, TooltipDirectiveArg>;
|
||||||
|
|
|
||||||
|
|
@ -131,4 +131,4 @@ export const userPreviewDirective = {
|
||||||
if (self == null) return;
|
if (self == null) return;
|
||||||
self.preview.detach();
|
self.preview.detach();
|
||||||
},
|
},
|
||||||
} as Directive<UserPreviewDirectiveElement, string | Misskey.entities.UserDetailed>;
|
} as Directive<UserPreviewDirectiveElement, string | Misskey.entities.UserDetailed | null | undefined>;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
export type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
|
|
||||||
|
|
||||||
export type WithNonNullable<T, K extends keyof T> = T & { [P in K]-?: NonNullable<T[P]> };
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export type Awaitable <T> = T | Promise<T>;
|
||||||
Loading…
Reference in New Issue