lint and type fixes
This commit is contained in:
parent
54071efaea
commit
6ac37b4d6c
84 changed files with 188 additions and 374 deletions
|
|
@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script setup lang="ts">
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { computed, defineAsyncComponent, shallowRef } from 'vue';
|
||||
import { computed, defineAsyncComponent, useTemplateRef } from 'vue';
|
||||
import type { ComponentExposed } from 'vue-component-type-helpers';
|
||||
import type MkNote from '@/components/MkNote.vue';
|
||||
import type SkNote from '@/components/SkNote.vue';
|
||||
|
|
@ -31,7 +31,7 @@ const XNote = computed(() =>
|
|||
),
|
||||
);
|
||||
|
||||
const rootEl = shallowRef<ComponentExposed<typeof MkNote | typeof SkNote>>();
|
||||
const rootEl = useTemplateRef<ComponentExposed<typeof MkNote | typeof SkNote>>('rootEl');
|
||||
|
||||
defineExpose({ rootEl });
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script setup lang="ts">
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { computed, defineAsyncComponent, shallowRef } from 'vue';
|
||||
import { computed, defineAsyncComponent, useTemplateRef } from 'vue';
|
||||
import type { ComponentExposed } from 'vue-component-type-helpers';
|
||||
import type MkNoteDetailed from '@/components/MkNoteDetailed.vue';
|
||||
import type SkNoteDetailed from '@/components/SkNoteDetailed.vue';
|
||||
|
|
@ -28,7 +28,7 @@ const XNoteDetailed = computed(() =>
|
|||
),
|
||||
);
|
||||
|
||||
const rootEl = shallowRef<ComponentExposed<typeof MkNoteDetailed | typeof SkNoteDetailed>>();
|
||||
const rootEl = useTemplateRef<ComponentExposed<typeof MkNoteDetailed | typeof SkNoteDetailed>>('rootEl');
|
||||
|
||||
defineExpose({ rootEl });
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script setup lang="ts">
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { computed, defineAsyncComponent, shallowRef } from 'vue';
|
||||
import { computed, defineAsyncComponent, useTemplateRef } from 'vue';
|
||||
import type { ComponentExposed } from 'vue-component-type-helpers';
|
||||
import type MkNoteSimple from '@/components/MkNoteSimple.vue';
|
||||
import type SkNoteSimple from '@/components/SkNoteSimple.vue';
|
||||
|
|
@ -29,7 +29,7 @@ const XNoteSimple = computed(() =>
|
|||
),
|
||||
);
|
||||
|
||||
const rootEl = shallowRef<ComponentExposed<typeof MkNoteSimple | typeof SkNoteSimple>>();
|
||||
const rootEl = useTemplateRef<ComponentExposed<typeof MkNoteSimple | typeof SkNoteSimple>>('rootEl');
|
||||
|
||||
defineExpose({ rootEl });
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ const src = computed(() => {
|
|||
case 'fc': return 'https://cdn.jsdelivr.net/npm/friendly-challenge@0.9.18/widget.min.js';
|
||||
case 'mcaptcha': return null;
|
||||
case 'testcaptcha': return null;
|
||||
default: return null;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,9 @@ function waitForDecode() {
|
|||
.then(() => img.value?.decode())
|
||||
.then(() => {
|
||||
loaded.value = true;
|
||||
});
|
||||
})
|
||||
// Ignore decoding errors
|
||||
.catch(() => {});
|
||||
} else {
|
||||
loaded.value = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -805,8 +805,8 @@ function onContextmenu(ev: MouseEvent): void {
|
|||
ev.preventDefault();
|
||||
react();
|
||||
} else {
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
|
||||
os.contextMenu(popupMenu, ev).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
|
||||
os.contextMenu(menu, ev).then(focus).finally(cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -815,8 +815,8 @@ function showMenu(): void {
|
|||
return;
|
||||
}
|
||||
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
|
||||
os.popupMenu(popupMenu, menuButton.value).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
|
||||
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
||||
}
|
||||
|
||||
async function menuVersions(): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -749,14 +749,14 @@ function onContextmenu(ev: MouseEvent): void {
|
|||
ev.preventDefault();
|
||||
react();
|
||||
} else {
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted });
|
||||
os.contextMenu(popupMenu, ev).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted });
|
||||
os.contextMenu(menu, ev).then(focus).finally(cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
function showMenu(): void {
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted });
|
||||
os.popupMenu(popupMenu, menuButton.value).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted });
|
||||
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
||||
}
|
||||
|
||||
async function menuVersions(): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -54,11 +54,9 @@ const props = defineProps<{
|
|||
|
||||
const menuVersionsButton = shallowRef<HTMLElement>();
|
||||
|
||||
async function menuVersions(viaKeyboard = false): Promise<void> {
|
||||
const { menu, cleanup } = await getNoteVersionsMenu({ note: props.note, menuVersionsButton });
|
||||
popupMenu(menu, menuVersionsButton.value, {
|
||||
viaKeyboard,
|
||||
}).then(focus).finally(cleanup);
|
||||
async function menuVersions(): Promise<void> {
|
||||
const { menu, cleanup } = await getNoteVersionsMenu({ note: props.note, menuButton: menuVersionsButton });
|
||||
popupMenu(menu, menuVersionsButton.value).then(focus).finally(cleanup);
|
||||
}
|
||||
|
||||
const mock = inject(DI.mock, false);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ const props = defineProps<{
|
|||
hideFiles?: boolean;
|
||||
}>();
|
||||
|
||||
let showContent = ref(prefer.s.uncollapseCW);
|
||||
const showContent = ref(prefer.s.uncollapseCW);
|
||||
const isDeleted = ref(false);
|
||||
|
||||
const mergedCW = computed(() => computeMergedCw(props.note));
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ const props = withDefaults(defineProps<{
|
|||
const canRenote = computed(() => ['public', 'home'].includes(props.note.visibility) || props.note.userId === $i?.id);
|
||||
|
||||
const el = shallowRef<HTMLElement>();
|
||||
const muted = ref($i ? checkWordMute(props.note, $i, $i.mutedWords) : false);
|
||||
const muted = computed(() => $i ? checkWordMute(props.note, $i, $i.mutedWords) : false);
|
||||
const translation = ref<any>(null);
|
||||
const translating = ref(false);
|
||||
const isDeleted = ref(false);
|
||||
|
|
@ -142,7 +142,7 @@ const likeButton = shallowRef<HTMLElement>();
|
|||
|
||||
const renoteTooltip = computeRenoteTooltip(renoted);
|
||||
|
||||
let appearNote = computed(() => isRenote ? props.note.renote as Misskey.entities.Note : props.note);
|
||||
const appearNote = computed(() => isRenote ? props.note.renote as Misskey.entities.Note : props.note);
|
||||
const defaultLike = computed(() => prefer.s.like ? prefer.s.like : null);
|
||||
const replies = ref<Misskey.entities.Note[]>([]);
|
||||
|
||||
|
|
@ -377,8 +377,8 @@ function quote() {
|
|||
}
|
||||
|
||||
function menu(): void {
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: props.note, translating, translation, isDeleted });
|
||||
os.popupMenu(popupMenu, menuButton.value).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: props.note, translating, translation, isDeleted });
|
||||
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
||||
}
|
||||
|
||||
if (props.detail) {
|
||||
|
|
|
|||
|
|
@ -219,9 +219,22 @@ const props = withDefaults(defineProps<{
|
|||
full: false,
|
||||
});
|
||||
|
||||
const userDetailed: Ref<UserDetailed | null> = ref(null);
|
||||
type ExportCompletedNotification = Misskey.entities.Notification & { type: 'exportCompleted' };
|
||||
|
||||
const exportEntityName = {
|
||||
antenna: i18n.ts.antennas,
|
||||
blocking: i18n.ts.blockedUsers,
|
||||
clip: i18n.ts.clips,
|
||||
customEmoji: i18n.ts.customEmojis,
|
||||
favorite: i18n.ts.favorites,
|
||||
following: i18n.ts.following,
|
||||
muting: i18n.ts.mutedUsers,
|
||||
note: i18n.ts.notes,
|
||||
userList: i18n.ts.lists,
|
||||
} as const satisfies Record<ExportCompletedNotification['exportedEntity'], string>;
|
||||
|
||||
const followRequestDone = ref(true);
|
||||
const userDetailed: Ref<UserDetailed | null> = ref(null);
|
||||
|
||||
// watch() is required because computed() doesn't support async.
|
||||
watch(props, async () => {
|
||||
|
|
@ -241,20 +254,6 @@ watch(props, async () => {
|
|||
}
|
||||
}, { immediate: true });
|
||||
|
||||
type ExportCompletedNotification = Misskey.entities.Notification & { type: 'exportCompleted' };
|
||||
|
||||
const exportEntityName = {
|
||||
antenna: i18n.ts.antennas,
|
||||
blocking: i18n.ts.blockedUsers,
|
||||
clip: i18n.ts.clips,
|
||||
customEmoji: i18n.ts.customEmojis,
|
||||
favorite: i18n.ts.favorites,
|
||||
following: i18n.ts.following,
|
||||
muting: i18n.ts.mutedUsers,
|
||||
note: i18n.ts.notes,
|
||||
userList: i18n.ts.lists,
|
||||
} as const satisfies Record<ExportCompletedNotification['exportedEntity'], string>;
|
||||
|
||||
const acceptFollowRequest = () => {
|
||||
if (!('user' in props.notification)) return;
|
||||
followRequestDone.value = true;
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ onUnmounted(() => {
|
|||
left: 0;
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
//background: linear-gradient(0deg, var(--MI_THEME-panel), color(from var(--MI_THEME-panel) srgb r g b / 0));
|
||||
|
||||
> .fadeLabel {
|
||||
display: inline-block;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ watch(() => props.expandAllCws, (expandAllCws) => {
|
|||
left: 0;
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
// background: linear-gradient(0deg, var(--MI_THEME-panel), color(from var(--MI_THEME-panel) srgb r g b / 0));
|
||||
|
||||
> .fadeLabel {
|
||||
display: inline-block;
|
||||
|
|
|
|||
|
|
@ -805,8 +805,8 @@ function onContextmenu(ev: MouseEvent): void {
|
|||
ev.preventDefault();
|
||||
react();
|
||||
} else {
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
|
||||
os.contextMenu(popupMenu, ev).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
|
||||
os.contextMenu(menu, ev).then(focus).finally(cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -815,8 +815,8 @@ function showMenu(): void {
|
|||
return;
|
||||
}
|
||||
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
|
||||
os.popupMenu(popupMenu, menuButton.value).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted, currentClip: currentClip?.value });
|
||||
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
||||
}
|
||||
|
||||
async function menuVersions(): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -755,14 +755,14 @@ function onContextmenu(ev: MouseEvent): void {
|
|||
ev.preventDefault();
|
||||
react();
|
||||
} else {
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted });
|
||||
os.contextMenu(popupMenu, ev).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted });
|
||||
os.contextMenu(menu, ev).then(focus).finally(cleanup);
|
||||
}
|
||||
}
|
||||
|
||||
function showMenu(): void {
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted });
|
||||
os.popupMenu(popupMenu, menuButton.value).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: note.value, translating, translation, isDeleted });
|
||||
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
||||
}
|
||||
|
||||
async function menuVersions(): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -391,8 +391,8 @@ function quote() {
|
|||
}
|
||||
|
||||
function menu(): void {
|
||||
const { popupMenu, cleanup } = getNoteMenu({ note: props.note, translating, translation, isDeleted });
|
||||
os.popupMenu(popupMenu, menuButton.value).then(focus).finally(cleanup);
|
||||
const { menu, cleanup } = getNoteMenu({ note: props.note, translating, translation, isDeleted });
|
||||
os.popupMenu(menu, menuButton.value).then(focus).finally(cleanup);
|
||||
}
|
||||
|
||||
if (props.detail) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { defineAsyncComponent, computed } from 'vue';
|
||||
import * as mfm from '@transfem-org/sfm-js';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { extractUrlFromMfm } from '@/utility/extract-url-from-mfm.js';
|
||||
|
|
@ -26,7 +26,10 @@ const props = defineProps<{
|
|||
page: Misskey.entities.Page,
|
||||
}>();
|
||||
|
||||
const urls = props.block.text ? extractUrlFromMfm(mfm.parse(props.block.text)) : [];
|
||||
const urls = computed(() => {
|
||||
if (!props.block.text) return [];
|
||||
return extractUrlFromMfm(mfm.parse(props.block.text));
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template #label>{{ i18n.ts.host }}</template>
|
||||
</MkInput>
|
||||
<FormSplit style="margin-top: var(--MI-margin);">
|
||||
<!-- TODO translate -->
|
||||
<MkSelect v-model="state">
|
||||
<template #label>{{ i18n.ts.state }}</template>
|
||||
<option value="all">{{ i18n.ts.all }}</option>
|
||||
|
|
@ -61,7 +62,7 @@ import type { Paging } from '@/components/MkPagination.vue';
|
|||
import MkInstanceCardMini from '@/components/MkInstanceCardMini.vue';
|
||||
import FormSplit from '@/components/form/split.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { $i } from '@/account.js';
|
||||
import { $i } from '@/i';
|
||||
|
||||
const host = ref('');
|
||||
const state = ref('federating');
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div class="_gaps_m">
|
||||
<div :class="$style.banner" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }">
|
||||
<div style="overflow: clip;">
|
||||
<img :src="instance.sidebarLogoUrl ?? instance.iconUrl ?? instance.faviconUrl ?? '/favicon.ico'" alt="" :class="$style.bannerIcon"/>
|
||||
<img :src="instance.sidebarLogoUrl ?? instance.iconUrl ?? '/favicon.ico'" alt="" :class="$style.bannerIcon"/>
|
||||
<div :class="$style.bannerName">
|
||||
<b>{{ instance.name ?? host }}</b>
|
||||
</div>
|
||||
|
|
@ -22,6 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<FormSection>
|
||||
<div class="_gaps_m">
|
||||
<MkKeyValue :copy="version">
|
||||
<!-- TODO translate -->
|
||||
<template #key>Sharkey</template>
|
||||
<template #value>{{ version }}</template>
|
||||
</MkKeyValue>
|
||||
|
|
@ -101,7 +102,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</FormSection>
|
||||
|
||||
<FormSuspense v-slot="{ result: stats }" :p="initStats">
|
||||
<FormSection>
|
||||
<FormSection v-if="stats">
|
||||
<template #label>{{ i18n.ts.statistics }}</template>
|
||||
<FormSplit>
|
||||
<MkKeyValue>
|
||||
|
|
@ -116,12 +117,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</FormSection>
|
||||
</FormSuspense>
|
||||
|
||||
<FormSection v-if="sponsors[0].length > 0">
|
||||
<FormSection v-if="sponsors.length > 0">
|
||||
<template #label>Our lovely Sponsors</template>
|
||||
<div :class="$style.contributors">
|
||||
<span
|
||||
v-for="sponsor in sponsors[0]"
|
||||
:key="sponsor"
|
||||
v-for="(sponsor, i) of sponsors"
|
||||
:key="i"
|
||||
style="margin-bottom: 0.5rem;"
|
||||
>
|
||||
<a :href="sponsor.website || sponsor.profile" target="_blank" :class="$style.contributor">
|
||||
|
|
@ -147,7 +148,6 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import sanitizeHtml from '@/utility/sanitize-html.js';
|
||||
import { host, version } from '@@/js/config.js';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { instance } from '@/instance.js';
|
||||
|
|
@ -160,11 +160,12 @@ import FormSuspense from '@/components/form/suspense.vue';
|
|||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import MkKeyValue from '@/components/MkKeyValue.vue';
|
||||
import MkLink from '@/components/MkLink.vue';
|
||||
import sanitizeHtml from '@/utility/sanitize-html.js';
|
||||
|
||||
const sponsors = ref([]);
|
||||
const sponsors = ref<{ name: string, image: string | null, website: string | null, profile: string }[]>([]);
|
||||
|
||||
const initStats = () => misskeyApi('stats', {});
|
||||
await misskeyApi('sponsors', { instance: true }).then((res) => sponsors.value.push(res.sponsor_data));
|
||||
await misskeyApi('sponsors', { instance: true }).then((res) => sponsors.value = res.sponsor_data);
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template #icon><i class="ti ti-password"></i></template>
|
||||
<template #label>IP</template>
|
||||
<MkInfo v-if="!iAmAdmin" warn>{{ i18n.ts.requireAdminForView }}</MkInfo>
|
||||
<!-- TODO translate -->
|
||||
<MkInfo v-else>The date is the IP address was first acknowledged.</MkInfo>
|
||||
<template v-if="iAmAdmin && ips">
|
||||
<div v-for="record in ips" :key="record.ip" class="_monospace" :class="$style.ip" style="margin: 1em 0;">
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<FormLink to="/admin/server-rules">{{ i18n.ts.serverRules }}</FormLink>
|
||||
|
||||
<!-- TODO translate -->
|
||||
<MkFolder v-if="bubbleTimelineEnabled">
|
||||
<template #icon><i class="ph-drop ph-bold ph-lg"></i></template>
|
||||
<template #label>Bubble timeline</template>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</MkSwitch>
|
||||
</MkFolder>
|
||||
|
||||
<!-- TODO translate -->
|
||||
<MkFolder v-if="matchQuery([i18n.ts._role._options.btlAvailable, 'btlAvailable'])">
|
||||
<template #label>{{ i18n.ts._role._options.btlAvailable }}</template>
|
||||
<template #suffix>{{ policies.btlAvailable ? i18n.ts.yes : i18n.ts.no }}</template>
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
|
||||
<script lang="ts" setup>
|
||||
import MkPagination from '@/components/MkPagination.vue';
|
||||
import DynamicNote from '@/components/DynamicNote.vue';
|
||||
import MkDateSeparatedList from '@/components/MkDateSeparatedList.vue';
|
||||
import { i18n } from '@/i18n.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import { infoImageUrl } from '@/instance.js';
|
||||
import DynamicNote from '@/components/DynamicNote.vue';
|
||||
|
||||
const pagination = {
|
||||
endpoint: 'i/favorites' as const,
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ import { computed, watch, ref } from 'vue';
|
|||
import * as Misskey from 'misskey-js';
|
||||
import { host } from '@@/js/config.js';
|
||||
import type { Paging } from '@/components/MkPagination.vue';
|
||||
import DynamicNoteDetailed from '@/components/DynamicNoteDetailed.vue';
|
||||
import MkNotes from '@/components/MkNotes.vue';
|
||||
import MkRemoteCaution from '@/components/MkRemoteCaution.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
|
|
@ -66,7 +67,6 @@ import { pleaseLogin } from '@/utility/please-login.js';
|
|||
import { getAppearNote } from '@/utility/get-appear-note.js';
|
||||
import { serverContext, assertServerContext } from '@/server-context.js';
|
||||
import { $i } from '@/i.js';
|
||||
import DynamicNoteDetailed from '@/components/DynamicNoteDetailed.vue';
|
||||
|
||||
// contextは非ログイン状態の情報しかないためログイン時は利用できない
|
||||
const CTX_NOTE = !$i && assertServerContext(serverContext, 'note') ? serverContext.note : null;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, shallowRef, watch } from 'vue';
|
||||
import { computed, ref, useTemplateRef, watch } from 'vue';
|
||||
import type { StyleValue } from 'vue';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import * as Misskey from 'misskey-js';
|
||||
|
|
@ -61,10 +61,9 @@ import { i18n } from '@/i18n.js';
|
|||
import bytes from '@/filters/bytes.js';
|
||||
import { definePage } from '@/page.js';
|
||||
import MkSelect from '@/components/MkSelect.vue';
|
||||
import { getDriveFileMenu } from '@/utility/get-drive-file-menu.js';
|
||||
import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
|
||||
|
||||
const paginationComponent = shallowRef<InstanceType<typeof MkPagination>>();
|
||||
const paginationComponent = useTemplateRef<InstanceType<typeof MkPagination>>('paginationComponent');
|
||||
|
||||
const sortMode = ref('+size');
|
||||
const pagination = {
|
||||
|
|
|
|||
|
|
@ -861,7 +861,6 @@ import MkFeatureBanner from '@/components/MkFeatureBanner.vue';
|
|||
import { globalEvents } from '@/events.js';
|
||||
import { claimAchievement } from '@/utility/achievements.js';
|
||||
import { instance } from '@/instance.js';
|
||||
import Search from '@/pages/search.vue';
|
||||
|
||||
// Sharkey imports
|
||||
import { searchEngineMap } from '@/utility/search-engine-map.js';
|
||||
|
|
|
|||
|
|
@ -187,7 +187,6 @@ import { claimAchievement } from '@/utility/achievements.js';
|
|||
import { store } from '@/store.js';
|
||||
import MkInfo from '@/components/MkInfo.vue';
|
||||
import MkTextarea from '@/components/MkTextarea.vue';
|
||||
import { globalEvents } from '@/events.js';
|
||||
|
||||
const $i = ensureSignin();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div :class="$style.formContainer">
|
||||
<form :class="$style.form" class="_panel" @submit.prevent="submit()">
|
||||
<div :class="$style.title">
|
||||
<!-- TODO translate -->
|
||||
<div>Welcome to Sharkey!</div>
|
||||
<div :class="$style.version">v{{ version }}</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export interface PostFormProps {
|
|||
initialFiles?: Misskey.entities.DriveFile[];
|
||||
initialLocalOnly?: boolean;
|
||||
initialVisibleUsers?: Misskey.entities.UserDetailed[];
|
||||
/* TODO inline this into the entity */
|
||||
initialNote?: Misskey.entities.Note & {
|
||||
isSchedule?: boolean,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,11 +31,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
:enterFromClass="$style.transition_notification_enterFrom"
|
||||
:leaveToClass="$style.transition_notification_leaveTo"
|
||||
>
|
||||
<div
|
||||
v-for="notification in notifications" :key="notification.id" :class="$style.notification" :style="{
|
||||
pointerEvents: getPointerEvents()
|
||||
}"
|
||||
>
|
||||
<div v-for="notification in notifications" :key="notification.id" :class="$style.notification" :style="{ pointerEvents: getPointerEvents() }">
|
||||
<XNotification :notification="notification"/>
|
||||
</div>
|
||||
</component>
|
||||
|
|
@ -67,10 +63,9 @@ import { prefer } from '@/preferences.js';
|
|||
import { globalEvents } from '@/events.js';
|
||||
import { store } from '@/store.js';
|
||||
|
||||
const SkOneko = defineAsyncComponent(() => import('@/components/SkOneko.vue'));
|
||||
|
||||
const XStreamIndicator = defineAsyncComponent(() => import('./stream-indicator.vue'));
|
||||
const XUpload = defineAsyncComponent(() => import('./upload.vue'));
|
||||
const SkOneko = defineAsyncComponent(() => import('@/components/SkOneko.vue'));
|
||||
|
||||
const dev = _DEV_;
|
||||
|
||||
|
|
@ -99,7 +94,6 @@ function onNotification(notification: Misskey.entities.Notification, isClient =
|
|||
if ($i) {
|
||||
const connection = useStream().useChannel('main', null, 'UI');
|
||||
connection.on('notification', onNotification);
|
||||
|
||||
globalEvents.on('clientNotification', notification => onNotification(notification, true));
|
||||
|
||||
//#region Listen message from SW
|
||||
|
|
@ -132,8 +126,8 @@ function getPointerEvents() {
|
|||
position: fixed;
|
||||
z-index: 3900000;
|
||||
padding: 0 var(--MI-margin);
|
||||
display: flex;
|
||||
pointer-events: none;
|
||||
display: flex;
|
||||
|
||||
&.notificationsPosition_leftTop {
|
||||
top: var(--MI-margin);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<div :class="$style.top">
|
||||
<div :class="$style.banner" :style="{ backgroundImage: `url(${ instance.bannerUrl })` }"></div>
|
||||
<button v-tooltip.noDelay.right="instance.name ?? i18n.ts.instance" class="_button" :class="$style.instance" @click="openInstanceMenu">
|
||||
<img :src="instance.sidebarLogoUrl && !iconOnly ? instance.sidebarLogoUrl : instance.iconUrl || instance.faviconUrl || '/favicon.ico'" alt="" :class="instance.sidebarLogoUrl && !iconOnly ? $style.wideInstanceIcon : $style.instanceIcon" style="viewTransitionName: navbar-serverIcon;"/>
|
||||
<img :src="instance.sidebarLogoUrl && !iconOnly ? instance.sidebarLogoUrl : instance.iconUrl || '/favicon.ico'" alt="" :class="instance.sidebarLogoUrl && !iconOnly ? $style.wideInstanceIcon : $style.instanceIcon" style="viewTransitionName: navbar-serverIcon;"/>
|
||||
</button>
|
||||
</div>
|
||||
<div :class="$style.middle">
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
*/
|
||||
|
||||
import { onUnmounted } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import type { Ref, ShallowRef } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import { useStream } from '@/stream.js';
|
||||
import { $i } from '@/i.js';
|
||||
import { misskeyApi } from '@/utility/misskey-api.js';
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
type JsonLike = string | number | boolean | null | undefined | JsonLike[] | { [key: string]: JsonLike | undefined } | Map<string, JsonLike>;
|
||||
type JsonLike = string | number | boolean | null | undefined | JsonLike[] | { [key: string]: JsonLike } | Map<string, JsonLike>;
|
||||
|
||||
export function deepEqual(a: JsonLike, b: JsonLike): boolean {
|
||||
if (a === b) return true;
|
||||
|
|
|
|||
|
|
@ -14,20 +14,18 @@ class FavIconDot {
|
|||
private hasLoaded: Promise<void> | undefined;
|
||||
|
||||
constructor() {
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.canvas = window.document.createElement('canvas');
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called before calling any other functions
|
||||
*/
|
||||
public async setup() {
|
||||
const element: HTMLLinkElement = await this.getOrMakeFaviconElement();
|
||||
|
||||
this.faviconEL = element;
|
||||
this.faviconEL = await this.getOrMakeFaviconElement();
|
||||
this.src = this.faviconEL.getAttribute('href');
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
|
||||
this.faviconImage = document.createElement('img');
|
||||
this.faviconImage = window.document.createElement('img');
|
||||
this.faviconImage.crossOrigin = 'anonymous';
|
||||
|
||||
this.hasLoaded = new Promise((resolve, reject) => {
|
||||
|
|
@ -46,7 +44,7 @@ class FavIconDot {
|
|||
|
||||
private async getOrMakeFaviconElement(): Promise<HTMLLinkElement> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const favicon = (document.querySelector('link[rel=icon]') ?? this.createFaviconElem()) as HTMLLinkElement;
|
||||
const favicon = (window.document.querySelector('link[rel=icon]') ?? this.createFaviconElem()) as HTMLLinkElement;
|
||||
favicon.addEventListener('load', () => {
|
||||
resolve(favicon);
|
||||
});
|
||||
|
|
@ -59,12 +57,12 @@ class FavIconDot {
|
|||
}
|
||||
|
||||
private createFaviconElem() {
|
||||
const newLink = document.createElement('link');
|
||||
const newLink = window.document.createElement('link');
|
||||
newLink.setAttribute('rel', 'icon');
|
||||
newLink.setAttribute('href', '/favicon.ico');
|
||||
newLink.setAttribute('type', 'image/x-icon');
|
||||
|
||||
document.head.appendChild(newLink);
|
||||
window.document.head.appendChild(newLink);
|
||||
return newLink;
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +77,7 @@ class FavIconDot {
|
|||
this.ctx.beginPath();
|
||||
const radius = Math.min(this.faviconImage.width, this.faviconImage.height) * 0.2;
|
||||
this.ctx.arc(this.faviconImage.width - radius, radius, radius, 0, 2 * Math.PI);
|
||||
const computedStyle = getComputedStyle(document.documentElement);
|
||||
const computedStyle = getComputedStyle(window.document.documentElement);
|
||||
this.ctx.fillStyle = tinycolor(computedStyle.getPropertyValue('--MI_THEME-navIndicator')).toHexString();
|
||||
this.ctx.strokeStyle = 'white';
|
||||
this.ctx.fill();
|
||||
|
|
@ -111,7 +109,7 @@ class FavIconDot {
|
|||
public async worksOnInstance() {
|
||||
try {
|
||||
await this.setVisible(true);
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
await new Promise((resolve) => window.setTimeout(resolve, 1000));
|
||||
await this.setVisible(false);
|
||||
} catch (error) {
|
||||
console.error('error setting notification dot', error);
|
||||
|
|
@ -138,7 +136,7 @@ export async function setFavIconDot(visible: boolean) {
|
|||
};
|
||||
|
||||
// If document is already loaded, set visibility immediately
|
||||
if (document.readyState === 'complete') {
|
||||
if (window.document.readyState === 'complete') {
|
||||
await setIconVisibility();
|
||||
} else {
|
||||
// Otherwise, set visibility when window loads
|
||||
|
|
|
|||
|
|
@ -541,7 +541,7 @@ export function getNoteMenu(props: {
|
|||
};
|
||||
|
||||
return {
|
||||
popupMenu: menuItems,
|
||||
menu: menuItems,
|
||||
cleanup,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue