diff options
| author | yukineko <27853966+hideki0403@users.noreply.github.com> | 2024-01-30 19:53:53 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-30 19:53:53 +0900 |
| commit | a6a91fec3af5314472b0a70402c1ef7e73a478ef (patch) | |
| tree | 7a7977d47a038038136082ee444840781c7164da /packages/frontend/src/components/MkMenu.vue | |
| parent | iOSで大きな画像を変換してアップロードできない問題を... (diff) | |
| download | misskey-a6a91fec3af5314472b0a70402c1ef7e73a478ef.tar.gz misskey-a6a91fec3af5314472b0a70402c1ef7e73a478ef.tar.bz2 misskey-a6a91fec3af5314472b0a70402c1ef7e73a478ef.zip | |
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
* :v:
* Update MkNotification.vue
* Update MkNotification.vue
* Update MkNotification.vue
* Update MkNotifications.vue
* Update MkUserSetupDialog.Profile.vue
* Update MkUserCardMini.vue
* :v:
* Update MkMenu.vue
---------
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
Diffstat (limited to 'packages/frontend/src/components/MkMenu.vue')
| -rw-r--r-- | packages/frontend/src/components/MkMenu.vue | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/packages/frontend/src/components/MkMenu.vue b/packages/frontend/src/components/MkMenu.vue index 17ace227ff..b8706231ee 100644 --- a/packages/frontend/src/components/MkMenu.vue +++ b/packages/frontend/src/components/MkMenu.vue @@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only :style="{ width: (width && !asDrawer) ? width + 'px' : '', maxHeight: maxHeight ? maxHeight + 'px' : '' }" @contextmenu.self="e => e.preventDefault()" > - <template v-for="(item, i) in items2"> + <template v-for="(item, i) in (items2 ?? [])"> <div v-if="item.type === 'divider'" role="separator" :class="$style.divider"></div> <span v-else-if="item.type === 'label'" role="menuitem" :class="[$style.label, $style.item]"> <span style="opacity: 0.7;">{{ item.text }}</span> @@ -54,7 +54,7 @@ SPDX-License-Identifier: AGPL-3.0-only <span :class="$style.caret" style="pointer-events: none;"><i class="ti ti-chevron-right ti-fw"></i></span> </div> </button> - <button v-else :tabindex="i" class="_button" role="menuitem" :class="[$style.item, { [$style.danger]: item.danger, [$style.active]: item.active }]" :disabled="item.active" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)"> + <button v-else :tabindex="i" class="_button" role="menuitem" :class="[$style.item, { [$style.danger]: item.danger, [$style.active]: getValue(item.active) }]" :disabled="getValue(item.active)" @click="clicked(item.action, $event)" @mouseenter.passive="onItemMouseEnter(item)" @mouseleave.passive="onItemMouseLeave(item)"> <i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i> <MkAvatar v-if="item.avatar" :user="item.avatar" :class="$style.avatar"/> <div :class="$style.item_content"> @@ -63,18 +63,18 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </button> </template> - <span v-if="items2.length === 0" :class="[$style.none, $style.item]"> + <span v-if="items2 == null || items2.length === 0" :class="[$style.none, $style.item]"> <span>{{ i18n.ts.none }}</span> </span> </div> <div v-if="childMenu"> - <XChild ref="child" :items="childMenu" :targetElement="childTarget" :rootElement="itemsEl" showing @actioned="childActioned" @close="close(false)"/> + <XChild ref="child" :items="childMenu" :targetElement="childTarget!" :rootElement="itemsEl!" showing @actioned="childActioned" @close="close(false)"/> </div> </div> </template> <script lang="ts"> -import { computed, defineAsyncComponent, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'; +import { ComputedRef, computed, defineAsyncComponent, isRef, nextTick, onBeforeUnmount, onMounted, ref, shallowRef, watch } from 'vue'; import { focusPrev, focusNext } from '@/scripts/focus.js'; import MkSwitchButton from '@/components/MkSwitch.button.vue'; import { MenuItem, InnerMenuItem, MenuPending, MenuAction, MenuSwitch, MenuParent } from '@/types/menu.js'; @@ -104,7 +104,7 @@ const emit = defineEmits<{ const itemsEl = shallowRef<HTMLDivElement>(); -const items2 = ref<InnerMenuItem[]>([]); +const items2 = ref<InnerMenuItem[]>(); const child = shallowRef<InstanceType<typeof XChild>>(); @@ -119,15 +119,15 @@ const childShowingItem = ref<MenuItem | null>(); let preferClick = isTouchUsing || props.asDrawer; watch(() => props.items, () => { - const items: (MenuItem | MenuPending)[] = [...props.items].filter(item => item !== undefined); + const items = [...props.items].filter(item => item !== undefined) as (NonNullable<MenuItem> | MenuPending)[]; for (let i = 0; i < items.length; i++) { const item = items[i]; - if (item && 'then' in item) { // if item is Promise + if ('then' in item) { // if item is Promise items[i] = { type: 'pending' }; item.then(actualItem => { - items2.value[i] = actualItem; + if (items2.value?.[i]) items2.value[i] = actualItem; }); } } @@ -151,7 +151,7 @@ function childActioned() { } const onGlobalMousedown = (event: MouseEvent) => { - if (childTarget.value && (event.target === childTarget.value || childTarget.value.contains(event.target))) return; + if (childTarget.value && (event.target === childTarget.value || childTarget.value.contains(event.target as Node))) return; if (child.value && child.value.checkHit(event)) return; closeChild(); }; @@ -169,7 +169,7 @@ function onItemMouseLeave(item) { } async function showChildren(item: MenuParent, ev: MouseEvent) { - const children = await (async () => { + const children: MenuItem[] = await (async () => { if (childrenCache.has(item)) { return childrenCache.get(item)!; } else { @@ -189,7 +189,7 @@ async function showChildren(item: MenuParent, ev: MouseEvent) { }); emit('hide'); } else { - childTarget.value = ev.currentTarget ?? ev.target; + childTarget.value = (ev.currentTarget ?? ev.target) as HTMLElement; // これでもリアクティビティは保たれる childMenu.value = children; childShowingItem.value = item; @@ -218,6 +218,10 @@ function switchItem(item: MenuSwitch & { ref: any }) { item.ref = !item.ref; } +function getValue<T>(item?: ComputedRef<T> | T) { + return isRef(item) ? item.value : item; +} + onMounted(() => { if (props.viaKeyboard) { nextTick(() => { |