Merge branch 'develop' into qr

This commit is contained in:
tamaina 2025-08-25 14:44:17 +09:00
commit 8f5ff9ed92
31 changed files with 89 additions and 61 deletions

View File

@ -67,6 +67,7 @@
- Fix: `notes/mentions` で場合によっては並び順が正しく返されない問題を修正 - Fix: `notes/mentions` で場合によっては並び順が正しく返されない問題を修正
- Fix: SystemWebhook設定でsecretを空に出来ない問題を修正 - Fix: SystemWebhook設定でsecretを空に出来ない問題を修正
- Fix: 削除されたユーザーがチャットメッセージにリアクションしている場合`chat/history`などでエラーになる問題を修正 - Fix: 削除されたユーザーがチャットメッセージにリアクションしている場合`chat/history`などでエラーになる問題を修正
- Fix: Pageのアイキャッチ画像をドライブから消してもPageごと消えないように
## 2025.7.0 ## 2025.7.0

2
locales/index.d.ts vendored
View File

@ -6633,7 +6633,7 @@ export interface Locale extends ILocale {
/** /**
* *
*/ */
"showActivityiesForVisitor": string; "showActivitiesForVisitor": string;
"_userGeneratedContentsVisibilityForVisitor": { "_userGeneratedContentsVisibilityForVisitor": {
/** /**
* *

View File

@ -1685,7 +1685,7 @@ _serverSettings:
restartServerSetupWizardConfirm_text: "現在の一部の設定はリセットされます。" restartServerSetupWizardConfirm_text: "現在の一部の設定はリセットされます。"
entrancePageStyle: "エントランスページのスタイル" entrancePageStyle: "エントランスページのスタイル"
showTimelineForVisitor: "タイムラインを表示する" showTimelineForVisitor: "タイムラインを表示する"
showActivityiesForVisitor: "アクティビティを表示する" showActivitiesForVisitor: "アクティビティを表示する"
_userGeneratedContentsVisibilityForVisitor: _userGeneratedContentsVisibilityForVisitor:
all: "全て公開" all: "全て公開"

View File

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class NonCascadingPageEyeCatching1756062689648 {
name = 'NonCascadingPageEyeCatching1756062689648'
async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa"`);
await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
}
async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "page" DROP CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa"`);
await queryRunner.query(`ALTER TABLE "page" ADD CONSTRAINT "FK_a9ca79ad939bf06066b81c9d3aa" FOREIGN KEY ("eyeCatchingImageId") REFERENCES "drive_file"("id") ON DELETE CASCADE ON UPDATE NO ACTION`);
}
}

View File

@ -69,7 +69,7 @@ export class MiPage {
public eyeCatchingImageId: MiDriveFile['id'] | null; public eyeCatchingImageId: MiDriveFile['id'] | null;
@ManyToOne(type => MiDriveFile, { @ManyToOne(type => MiDriveFile, {
onDelete: 'CASCADE', onDelete: 'SET NULL',
}) })
@JoinColumn() @JoinColumn()
public eyeCatchingImage: MiDriveFile | null; public eyeCatchingImage: MiDriveFile | null;

View File

@ -44,7 +44,7 @@ function initShaderProgram(gl: WebGLRenderingContext, vsSource: string, fsSource
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource); const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
const shaderProgram = gl.createProgram(); const shaderProgram = gl.createProgram();
if (shaderProgram == null || vertexShader == null || fragmentShader == null) return null; if (vertexShader == null || fragmentShader == null) return null;
gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader); gl.attachShader(shaderProgram, fragmentShader);
@ -71,8 +71,10 @@ onMounted(() => {
canvas.width = width; canvas.width = width;
canvas.height = height; canvas.height = height;
const gl = canvas.getContext('webgl', { premultipliedAlpha: true }); const maybeGl = canvas.getContext('webgl', { premultipliedAlpha: true });
if (gl == null) return; if (maybeGl == null) return;
const gl = maybeGl;
gl.clearColor(0.0, 0.0, 0.0, 0.0); gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT);
@ -229,8 +231,8 @@ onMounted(() => {
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.DYNAMIC_DRAW); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.DYNAMIC_DRAW);
if (isChromatic()) { if (isChromatic()) {
gl!.uniform1f(u_time, 0); gl.uniform1f(u_time, 0);
gl!.drawArrays(gl!.TRIANGLE_STRIP, 0, 4); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
} else { } else {
function render(timeStamp: number) { function render(timeStamp: number) {
let sizeChanged = false; let sizeChanged = false;
@ -249,8 +251,8 @@ onMounted(() => {
gl.viewport(0, 0, width, height); gl.viewport(0, 0, width, height);
} }
gl!.uniform1f(u_time, timeStamp); gl.uniform1f(u_time, timeStamp);
gl!.drawArrays(gl!.TRIANGLE_STRIP, 0, 4); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
handle = window.requestAnimationFrame(render); handle = window.requestAnimationFrame(render);
} }

View File

@ -363,7 +363,7 @@ function onDrop(ev: DragEvent) {
//#endregion //#endregion
} }
function onUploadRequested(files: File[], folder: Misskey.entities.DriveFolder | null) { function onUploadRequested(files: File[], folder?: Misskey.entities.DriveFolder | null) {
os.launchUploader(files, { os.launchUploader(files, {
folderId: folder?.id ?? null, folderId: folder?.id ?? null,
}); });

View File

@ -22,7 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:forceBlurhash="forceBlurhash" :forceBlurhash="forceBlurhash"
/> />
<img <img
v-else-if="isThumbnailAvailable" v-else-if="isThumbnailAvailable && file.thumbnailUrl != null"
:src="file.thumbnailUrl" :src="file.thumbnailUrl"
:alt="file.name" :alt="file.name"
:title="file.name" :title="file.name"

View File

@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<Mfm class="summaryMfm" :text="flash.summary" :plain="true" :nowrap="true"/> <Mfm class="summaryMfm" :text="flash.summary" :plain="true" :nowrap="true"/>
</p> </p>
<footer> <footer>
<img class="icon" :src="flash.user.avatarUrl"/> <img v-if="flash.user.avatarUrl != null" class="icon" :src="flash.user.avatarUrl"/>
<p>{{ userName(flash.user) }}</p> <p>{{ userName(flash.user) }}</p>
</footer> </footer>
</article> </article>

View File

@ -17,11 +17,11 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup> <script lang="ts" setup>
import { defineAsyncComponent, ref } from 'vue'; import { defineAsyncComponent, ref } from 'vue';
import { url as local } from '@@/js/config.js'; import { url as local } from '@@/js/config.js';
import { maybeMakeRelative } from '@@/js/url.js';
import type { MkABehavior } from '@/components/global/MkA.vue';
import { useTooltip } from '@/composables/use-tooltip.js'; import { useTooltip } from '@/composables/use-tooltip.js';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { isEnabledUrlPreview } from '@/utility/url-preview.js'; import { isEnabledUrlPreview } from '@/utility/url-preview.js';
import type { MkABehavior } from '@/components/global/MkA.vue';
import { maybeMakeRelative } from '@@/js/url.js';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
url: string; url: string;
@ -42,7 +42,7 @@ if (isEnabledUrlPreview.value) {
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), { const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), {
showing, showing,
url: props.url, url: props.url,
source: el.value instanceof HTMLElement ? el.value : el.value?.$el, anchorElement: el.value instanceof HTMLElement ? el.value : el.value?.$el,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });

View File

@ -16,7 +16,7 @@ import type { MenuItem } from '@/types/menu.js';
const props = defineProps<{ const props = defineProps<{
items: MenuItem[]; items: MenuItem[];
targetElement: HTMLElement; anchorElement: HTMLElement;
rootElement: HTMLElement; rootElement: HTMLElement;
width?: number; width?: number;
}>(); }>();
@ -36,10 +36,10 @@ const SCROLLBAR_THICKNESS = 16;
function setPosition() { function setPosition() {
if (el.value == null) return; if (el.value == null) return;
const rootRect = props.rootElement.getBoundingClientRect(); const rootRect = props.rootElement.getBoundingClientRect();
const parentRect = props.targetElement.getBoundingClientRect(); const parentRect = props.anchorElement.getBoundingClientRect();
const myRect = el.value.getBoundingClientRect(); const myRect = el.value.getBoundingClientRect();
let left = props.targetElement.offsetWidth; let left = props.anchorElement.offsetWidth;
let top = (parentRect.top - rootRect.top) - 8; let top = (parentRect.top - rootRect.top) - 8;
if (rootRect.left + left + myRect.width >= (window.innerWidth - SCROLLBAR_THICKNESS)) { if (rootRect.left + left + myRect.width >= (window.innerWidth - SCROLLBAR_THICKNESS)) {
left = -myRect.width; left = -myRect.width;
@ -59,7 +59,7 @@ function onChildClosed(actioned?: boolean) {
} }
} }
watch(() => props.targetElement, () => { watch(() => props.anchorElement, () => {
setPosition(); setPosition();
}); });

View File

@ -208,7 +208,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</span> </span>
</div> </div>
<div v-if="childMenu"> <div v-if="childMenu">
<XChild ref="child" :items="childMenu" :targetElement="childTarget!" :rootElement="itemsEl!" @actioned="childActioned" @closed="closeChild"/> <XChild ref="child" :items="childMenu" :anchorElement="childTarget!" :rootElement="itemsEl!" @actioned="childActioned" @closed="closeChild"/>
</div> </div>
</div> </div>
</template> </template>

View File

@ -429,7 +429,7 @@ if (!props.mock) {
showing, showing,
users, users,
count: appearNote.renoteCount, count: appearNote.renoteCount,
targetElement: renoteButton.value, anchorElement: renoteButton.value,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });
@ -452,7 +452,7 @@ if (!props.mock) {
reaction: '❤️', reaction: '❤️',
users, users,
count: $appearNote.reactionCount, count: $appearNote.reactionCount,
targetElement: reactButton.value!, anchorElement: reactButton.value!,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });
@ -460,14 +460,12 @@ if (!props.mock) {
} }
} }
function renote(viaKeyboard = false) { function renote() {
pleaseLogin({ openOnRemote: pleaseLoginContext.value }); pleaseLogin({ openOnRemote: pleaseLoginContext.value });
showMovedDialog(); showMovedDialog();
const { menu } = getRenoteMenu({ note: note, renoteButton, mock: props.mock }); const { menu } = getRenoteMenu({ note: note, renoteButton, mock: props.mock });
os.popupMenu(menu, renoteButton.value, { os.popupMenu(menu, renoteButton.value);
viaKeyboard,
});
subscribeManuallyToNoteCapture(); subscribeManuallyToNoteCapture();
} }

View File

@ -302,7 +302,7 @@ if (noteViewInterruptors.length > 0) {
} }
const isRenote = Misskey.note.isPureRenote(note); const isRenote = Misskey.note.isPureRenote(note);
const appearNote = getAppearNote(note); const appearNote = getAppearNote(note) ?? note;
const { $note: $appearNote, subscribe: subscribeManuallyToNoteCapture } = useNoteCapture({ const { $note: $appearNote, subscribe: subscribeManuallyToNoteCapture } = useNoteCapture({
note: appearNote, note: appearNote,
parentNote: note, parentNote: note,
@ -405,7 +405,7 @@ useTooltip(renoteButton, async (showing) => {
showing, showing,
users, users,
count: appearNote.renoteCount, count: appearNote.renoteCount,
targetElement: renoteButton.value, anchorElement: renoteButton.value,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });
@ -428,7 +428,7 @@ if (appearNote.reactionAcceptance === 'likeOnly') {
reaction: '❤️', reaction: '❤️',
users, users,
count: $appearNote.reactionCount, count: $appearNote.reactionCount,
targetElement: reactButton.value!, anchorElement: reactButton.value!,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });

View File

@ -37,7 +37,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkInput> </MkInput>
</section> </section>
<section v-else-if="expiration === 'after'"> <section v-else-if="expiration === 'after'">
<MkInput v-model="after" small type="number" min="1" class="input"> <MkInput v-model="after" small type="number" :min="1" class="input">
<template #label>{{ i18n.ts._poll.duration }}</template> <template #label>{{ i18n.ts._poll.duration }}</template>
</MkInput> </MkInput>
<MkSelect v-model="unit" small> <MkSelect v-model="unit" small>

View File

@ -959,7 +959,16 @@ async function post(ev?: MouseEvent) {
if (postAccount.value) { if (postAccount.value) {
const storedAccounts = await getAccounts(); const storedAccounts = await getAccounts();
token = storedAccounts.find(x => x.id === postAccount.value?.id)?.token; const storedAccount = storedAccounts.find(x => x.id === postAccount.value?.id);
if (storedAccount && storedAccount.token != null) {
token = storedAccount.token;
} else {
await os.alert({
type: 'error',
text: 'cannot find the token of the selected account.',
});
return;
}
} }
posting.value = true; posting.value = true;

View File

@ -167,7 +167,7 @@ function onMouseenter() {
text: computed(() => { text: computed(() => {
return props.textConverter(finalValue.value); return props.textConverter(finalValue.value);
}), }),
targetElement: thumbEl.value ?? undefined, anchorElement: thumbEl.value ?? undefined,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });
@ -191,7 +191,7 @@ function onMousedown(ev: MouseEvent | TouchEvent) {
text: computed(() => { text: computed(() => {
return props.textConverter(finalValue.value); return props.textConverter(finalValue.value);
}), }),
targetElement: thumbEl.value ?? undefined, anchorElement: thumbEl.value ?? undefined,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });

View File

@ -28,7 +28,7 @@ if (props.withTooltip) {
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkReactionTooltip.vue')), { const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkReactionTooltip.vue')), {
showing, showing,
reaction: props.reaction.replace(/^:(\w+):$/, ':$1@.:'), reaction: props.reaction.replace(/^:(\w+):$/, ':$1@.:'),
targetElement: elRef.value.$el, anchorElement: elRef.value.$el,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<MkTooltip ref="tooltip" :showing="showing" :targetElement="targetElement" :maxWidth="340" @closed="emit('closed')"> <MkTooltip ref="tooltip" :showing="showing" :anchorElement="anchorElement" :maxWidth="340" @closed="emit('closed')">
<div :class="$style.root"> <div :class="$style.root">
<MkReactionIcon :reaction="reaction" :class="$style.icon" :noStyle="true"/> <MkReactionIcon :reaction="reaction" :class="$style.icon" :noStyle="true"/>
<div :class="$style.name">{{ reaction.replace('@.', '') }}</div> <div :class="$style.name">{{ reaction.replace('@.', '') }}</div>
@ -20,7 +20,7 @@ import MkReactionIcon from '@/components/MkReactionIcon.vue';
defineProps<{ defineProps<{
showing: boolean; showing: boolean;
reaction: string; reaction: string;
targetElement: HTMLElement; anchorElement: HTMLElement;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<MkTooltip ref="tooltip" :showing="showing" :targetElement="targetElement" :maxWidth="340" @closed="emit('closed')"> <MkTooltip ref="tooltip" :showing="showing" :anchorElement="anchorElement" :maxWidth="340" @closed="emit('closed')">
<div :class="$style.root"> <div :class="$style.root">
<div :class="$style.reaction"> <div :class="$style.reaction">
<MkReactionIcon :reaction="reaction" :class="$style.reactionIcon" :noStyle="true"/> <MkReactionIcon :reaction="reaction" :class="$style.reactionIcon" :noStyle="true"/>
@ -33,7 +33,7 @@ defineProps<{
reaction: string; reaction: string;
users: Misskey.entities.UserLite[]; users: Misskey.entities.UserLite[];
count: number; count: number;
targetElement: HTMLElement; anchorElement: HTMLElement;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{

View File

@ -231,7 +231,7 @@ if (!mock) {
reaction: props.reaction, reaction: props.reaction,
users, users,
count: props.count, count: props.count,
targetElement: buttonEl.value, anchorElement: buttonEl.value,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });

View File

@ -31,7 +31,7 @@ import { prefer } from '@/preferences.js';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
showing: boolean; showing: boolean;
targetElement?: HTMLElement; anchorElement?: HTMLElement;
x?: number; x?: number;
y?: number; y?: number;
text?: string; text?: string;
@ -58,7 +58,7 @@ const zIndex = os.claimZIndex('high');
function setPosition() { function setPosition() {
if (el.value == null) return; if (el.value == null) return;
const data = calcPopupPosition(el.value, { const data = calcPopupPosition(el.value, {
anchorElement: props.targetElement, anchorElement: props.anchorElement,
direction: props.direction, direction: props.direction,
align: 'center', align: 'center',
innerMargin: props.innerMargin, innerMargin: props.innerMargin,

View File

@ -20,7 +20,7 @@ import { prefer } from '@/preferences.js';
const props = defineProps<{ const props = defineProps<{
showing: boolean; showing: boolean;
url: string; url: string;
source: HTMLElement; anchorElement: HTMLElement;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
@ -32,9 +32,9 @@ const top = ref(0);
const left = ref(0); const left = ref(0);
onMounted(() => { onMounted(() => {
const rect = props.source.getBoundingClientRect(); const rect = props.anchorElement.getBoundingClientRect();
const x = Math.max((rect.left + (props.source.offsetWidth / 2)) - (300 / 2), 6) + window.scrollX; const x = Math.max((rect.left + (props.anchorElement.offsetWidth / 2)) - (300 / 2), 6) + window.scrollX;
const y = rect.top + props.source.offsetHeight + window.scrollY; const y = rect.top + props.anchorElement.offsetHeight + window.scrollY;
top.value = y; top.value = y;
left.value = x; left.value = x;

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<MkTooltip ref="tooltip" :showing="showing" :targetElement="targetElement" :maxWidth="250" @closed="emit('closed')"> <MkTooltip ref="tooltip" :showing="showing" :anchorElement="anchorElement" :maxWidth="250" @closed="emit('closed')">
<div :class="$style.root"> <div :class="$style.root">
<div v-for="u in users" :key="u.id" :class="$style.user"> <div v-for="u in users" :key="u.id" :class="$style.user">
<MkAvatar :class="$style.avatar" :user="u"/> <MkAvatar :class="$style.avatar" :user="u"/>
@ -23,7 +23,7 @@ defineProps<{
showing: boolean; showing: boolean;
users: Misskey.entities.UserLite[]; users: Misskey.entities.UserLite[];
count: number; count: number;
targetElement: HTMLElement; anchorElement: HTMLElement;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{

View File

@ -53,7 +53,7 @@ const props = withDefaults(defineProps<{
currentVisibility: typeof Misskey.noteVisibilities[number]; currentVisibility: typeof Misskey.noteVisibilities[number];
isSilenced: boolean; isSilenced: boolean;
localOnly: boolean; localOnly: boolean;
anchorElement?: HTMLElement; anchorElement?: HTMLElement | null;
isReplyVisibilitySpecified?: boolean; isReplyVisibilitySpecified?: boolean;
}>(), { }>(), {
}); });

View File

@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</div> </div>
</div> </div>
<div v-if="stats && instance.clientOptions.showActivityiesForVisitor !== false" :class="$style.stats"> <div v-if="stats && instance.clientOptions.showActivitiesForVisitor !== false" :class="$style.stats">
<div :class="[$style.statsItem, $style.panel]"> <div :class="[$style.statsItem, $style.panel]">
<div :class="$style.statsItemLabel">{{ i18n.ts.users }}</div> <div :class="$style.statsItemLabel">{{ i18n.ts.users }}</div>
<div :class="$style.statsItemCount"><MkNumber :value="stats.originalUsersCount"/></div> <div :class="$style.statsItemCount"><MkNumber :value="stats.originalUsersCount"/></div>
@ -46,7 +46,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkStreamingNotesTimeline src="local"/> <MkStreamingNotesTimeline src="local"/>
</div> </div>
</div> </div>
<div v-if="instance.clientOptions.showActivityiesForVisitor !== false" :class="$style.panel"> <div v-if="instance.clientOptions.showActivitiesForVisitor !== false" :class="$style.panel">
<XActiveUsersChart/> <XActiveUsersChart/>
</div> </div>
</div> </div>
@ -72,7 +72,7 @@ import { openInstanceMenu } from '@/ui/_common_/common.js';
const stats = ref<Misskey.entities.StatsResponse | null>(null); const stats = ref<Misskey.entities.StatsResponse | null>(null);
if (instance.clientOptions.showActivityiesForVisitor !== false) { if (instance.clientOptions.showActivitiesForVisitor !== false) {
misskeyApi('stats', {}).then((res) => { misskeyApi('stats', {}).then((res) => {
stats.value = res; stats.value = res;
}); });

View File

@ -62,7 +62,7 @@ if (props.showUrlPreview && isEnabledUrlPreview.value) {
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), { const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkUrlPreviewPopup.vue')), {
showing, showing,
url: props.url, url: props.url,
source: el.value instanceof HTMLElement ? el.value : el.value?.$el, anchorElement: el.value instanceof HTMLElement ? el.value : el.value?.$el,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<MkTooltip ref="tooltip" :showing="showing" :targetElement="targetElement" :maxWidth="250" @closed="emit('closed')"> <MkTooltip ref="tooltip" :showing="showing" :anchorElement="anchorElement" :maxWidth="250" @closed="emit('closed')">
<div :class="$style.root"> <div :class="$style.root">
{{ content }} {{ content }}
</div> </div>
@ -18,7 +18,7 @@ import MkTooltip from '@/components/MkTooltip.vue';
defineProps<{ defineProps<{
showing: boolean; showing: boolean;
content: string; content: string;
targetElement: HTMLElement; anchorElement: HTMLElement;
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{

View File

@ -300,7 +300,7 @@ useTooltip(rootEl, (showing) => {
const result = os.popup(defineAsyncComponent(() => import('@/components/grid/MkCellTooltip.vue')), { const result = os.popup(defineAsyncComponent(() => import('@/components/grid/MkCellTooltip.vue')), {
showing, showing,
content, content,
targetElement: rootEl.value!, anchorElement: rootEl.value!,
}, { }, {
closed: () => { closed: () => {
result.dispose(); result.dispose();

View File

@ -57,7 +57,7 @@ export default {
text: self.text, text: self.text,
asMfm: binding.modifiers.mfm, asMfm: binding.modifiers.mfm,
direction: binding.modifiers.left ? 'left' : binding.modifiers.right ? 'right' : binding.modifiers.top ? 'top' : binding.modifiers.bottom ? 'bottom' : 'top', direction: binding.modifiers.left ? 'left' : binding.modifiers.right ? 'right' : binding.modifiers.top ? 'top' : binding.modifiers.bottom ? 'bottom' : 'top',
targetElement: el, anchorElement: el,
}, { }, {
closed: () => dispose(), closed: () => dispose(),
}); });

View File

@ -23,8 +23,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</SearchMarker> </SearchMarker>
<SearchMarker :keywords="['activity', 'activities']"> <SearchMarker :keywords="['activity', 'activities']">
<MkSwitch v-model="showActivityiesForVisitor"> <MkSwitch v-model="showActivitiesForVisitor">
<template #label><SearchLabel>{{ i18n.ts._serverSettings.showActivityiesForVisitor }}</SearchLabel></template> <template #label><SearchLabel>{{ i18n.ts._serverSettings.showActivitiesForVisitor }}</SearchLabel></template>
</MkSwitch> </MkSwitch>
</SearchMarker> </SearchMarker>
@ -168,7 +168,7 @@ const meta = await misskeyApi('admin/meta');
const entrancePageStyle = ref(meta.clientOptions.entrancePageStyle ?? 'classic'); const entrancePageStyle = ref(meta.clientOptions.entrancePageStyle ?? 'classic');
const showTimelineForVisitor = ref(meta.clientOptions.showTimelineForVisitor ?? true); const showTimelineForVisitor = ref(meta.clientOptions.showTimelineForVisitor ?? true);
const showActivityiesForVisitor = ref(meta.clientOptions.showActivityiesForVisitor ?? true); const showActivitiesForVisitor = ref(meta.clientOptions.showActivitiesForVisitor ?? true);
const iconUrl = ref(meta.iconUrl); const iconUrl = ref(meta.iconUrl);
const app192IconUrl = ref(meta.app192IconUrl); const app192IconUrl = ref(meta.app192IconUrl);
const app512IconUrl = ref(meta.app512IconUrl); const app512IconUrl = ref(meta.app512IconUrl);
@ -189,7 +189,7 @@ function save() {
clientOptions: { clientOptions: {
entrancePageStyle: entrancePageStyle.value, entrancePageStyle: entrancePageStyle.value,
showTimelineForVisitor: showTimelineForVisitor.value, showTimelineForVisitor: showTimelineForVisitor.value,
showActivityiesForVisitor: showActivityiesForVisitor.value, showActivitiesForVisitor: showActivitiesForVisitor.value,
}, },
iconUrl: iconUrl.value, iconUrl: iconUrl.value,
app192IconUrl: app192IconUrl.value, app192IconUrl: app192IconUrl.value,