Merge branch 'develop' into qr
This commit is contained in:
commit
8f5ff9ed92
|
@ -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
|
||||||
|
|
|
@ -6633,7 +6633,7 @@ export interface Locale extends ILocale {
|
||||||
/**
|
/**
|
||||||
* アクティビティを表示する
|
* アクティビティを表示する
|
||||||
*/
|
*/
|
||||||
"showActivityiesForVisitor": string;
|
"showActivitiesForVisitor": string;
|
||||||
"_userGeneratedContentsVisibilityForVisitor": {
|
"_userGeneratedContentsVisibilityForVisitor": {
|
||||||
/**
|
/**
|
||||||
* 全て公開
|
* 全て公開
|
||||||
|
|
|
@ -1685,7 +1685,7 @@ _serverSettings:
|
||||||
restartServerSetupWizardConfirm_text: "現在の一部の設定はリセットされます。"
|
restartServerSetupWizardConfirm_text: "現在の一部の設定はリセットされます。"
|
||||||
entrancePageStyle: "エントランスページのスタイル"
|
entrancePageStyle: "エントランスページのスタイル"
|
||||||
showTimelineForVisitor: "タイムラインを表示する"
|
showTimelineForVisitor: "タイムラインを表示する"
|
||||||
showActivityiesForVisitor: "アクティビティを表示する"
|
showActivitiesForVisitor: "アクティビティを表示する"
|
||||||
|
|
||||||
_userGeneratedContentsVisibilityForVisitor:
|
_userGeneratedContentsVisibilityForVisitor:
|
||||||
all: "全て公開"
|
all: "全て公開"
|
||||||
|
|
|
@ -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`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
});
|
});
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -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(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -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<{
|
||||||
|
|
|
@ -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<{
|
||||||
|
|
|
@ -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(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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<{
|
||||||
|
|
|
@ -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;
|
||||||
}>(), {
|
}>(), {
|
||||||
});
|
});
|
||||||
|
|
|
@ -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;
|
||||||
});
|
});
|
||||||
|
|
|
@ -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(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -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<{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue