Merge tag '2023.11.0' into merge-upstream

This commit is contained in:
riku6460 2023-11-06 06:42:28 +09:00
commit 2bc887a6c5
No known key found for this signature in database
GPG key ID: 27414FA27DB94CF6
301 changed files with 9351 additions and 3283 deletions

View file

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<MkStickyContainer>
<template #header>
<XHeader :actions="headerActions" :tabs="headerTabs" />
<XHeader :actions="headerActions" :tabs="headerTabs"/>
</template>
<MkSpacer :contentMax="900">
<MkSwitch :modelValue="publishing" @update:modelValue="onChangePublishing">
@ -14,11 +14,11 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch>
<div>
<div v-for="ad in ads" class="_panel _gaps_m" :class="$style.ad">
<MkAd v-if="ad.url" :specify="ad" />
<MkAd v-if="ad.url" :specify="ad"/>
<MkInput v-model="ad.url" type="url">
<template #label>URL</template>
</MkInput>
<MkInput v-model="ad.imageUrl">
<MkInput v-model="ad.imageUrl" type="url">
<template #label>{{ i18n.ts.imageUrl }}</template>
</MkInput>
<MkRadios v-model="ad.place">
@ -51,8 +51,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<span>
{{ i18n.ts._ad.timezoneinfo }}
<div v-for="(day, index) in daysOfWeek" :key="index">
<input :id="`ad${ad.id}-${index}`" type="checkbox" :checked="(ad.dayOfWeek & (1 << index)) !== 0"
@change="toggleDayOfWeek(ad, index)">
<input
:id="`ad${ad.id}-${index}`" type="checkbox" :checked="(ad.dayOfWeek & (1 << index)) !== 0"
@change="toggleDayOfWeek(ad, index)"
>
<label :for="`ad${ad.id}-${index}`">{{ day }}</label>
</div>
</span>
@ -61,9 +63,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts.memo }}</template>
</MkTextarea>
<div class="buttons">
<MkButton class="button" inline primary style="margin-right: 12px;" @click="save(ad)"><i
class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
<MkButton class="button" inline danger @click="remove(ad)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}
<MkButton class="button" inline primary style="margin-right: 12px;" @click="save(ad)">
<i
class="ti ti-device-floppy"
></i> {{ i18n.ts.save }}
</MkButton>
<MkButton class="button" inline danger @click="remove(ad)">
<i class="ti ti-trash"></i> {{ i18n.ts.remove }}
</MkButton>
</div>
</div>
@ -115,6 +121,7 @@ const onChangePublishing = (v) => {
publishing = v;
refresh();
};
// (index)
function toggleDayOfWeek(ad, index) {
ad.dayOfWeek ^= 1 << index;
@ -187,6 +194,7 @@ function save(ad) {
});
}
}
function more() {
os.api('admin/ad/list', { untilId: ads.reduce((acc, ad) => ad.id != null ? ad : acc).id, publishing: publishing }).then(adsResponse => {
ads = ads.concat(adsResponse.map(r => {

View file

@ -43,7 +43,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkTextarea v-model="announcement.text">
<template #label>{{ i18n.ts.text }}</template>
</MkTextarea>
<MkInput v-model="announcement.imageUrl">
<MkInput v-model="announcement.imageUrl" type="url">
<template #label>{{ i18n.ts.imageUrl }}</template>
</MkInput>
<MkRadios v-model="announcement.icon">
@ -59,9 +59,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<option value="banner">{{ i18n.ts.banner }}</option>
<option value="dialog">{{ i18n.ts.dialog }}</option>
</MkRadios>
<MkInfo v-if="announcement.display === 'dialog'" warn>{{ i18n.ts._announcement.dialogAnnouncementUxWarn }}</MkInfo>
<MkSwitch v-model="announcement.forExistingUsers" :helpText="i18n.ts._announcement.forExistingUsersDescription">
{{ i18n.ts._announcement.forExistingUsers }}
</MkSwitch>
<MkSwitch v-model="announcement.silence" :helpText="i18n.ts._announcement.silenceDescription">
{{ i18n.ts._announcement.silence }}
</MkSwitch>
<MkSwitch v-model="announcement.needConfirmationToRead" :helpText="i18n.ts._announcement.needConfirmationToReadDescription">
{{ i18n.ts._announcement.needConfirmationToRead }}
</MkSwitch>
@ -140,6 +144,7 @@ function add() {
icon: 'info',
display: 'normal',
forExistingUsers: false,
silence: false,
needConfirmationToRead: false,
closeDuration: 0,
displayOrder: 0,

View file

@ -10,12 +10,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer :contentMax="700" :marginMin="16" :marginMax="32">
<FormSuspense :p="init">
<div class="_gaps_m">
<MkInput v-model="iconUrl">
<MkInput v-model="iconUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts._serverSettings.iconUrl }}</template>
</MkInput>
<MkInput v-model="app192IconUrl">
<MkInput v-model="app192IconUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts._serverSettings.iconUrl }} (App/192px)</template>
<template #caption>
@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
</MkInput>
<MkInput v-model="app512IconUrl">
<MkInput v-model="app512IconUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts._serverSettings.iconUrl }} (App/512px)</template>
<template #caption>
@ -37,27 +37,27 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
</MkInput>
<MkInput v-model="bannerUrl">
<MkInput v-model="bannerUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts.bannerUrl }}</template>
</MkInput>
<MkInput v-model="backgroundImageUrl">
<MkInput v-model="backgroundImageUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts.backgroundImageUrl }}</template>
</MkInput>
<MkInput v-model="notFoundImageUrl">
<MkInput v-model="notFoundImageUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts.notFoundDescription }}</template>
</MkInput>
<MkInput v-model="infoImageUrl">
<MkInput v-model="infoImageUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts.nothing }}</template>
</MkInput>
<MkInput v-model="serverErrorImageUrl">
<MkInput v-model="serverErrorImageUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts.somethingHappened }}</template>
</MkInput>

View file

@ -115,6 +115,11 @@ const menuDef = $computed(() => [{
text: i18n.ts.customEmojis,
to: '/admin/emojis',
active: currentPage?.route.name === 'emojis',
}, {
icon: 'ti ti-sparkles',
text: i18n.ts.avatarDecorations,
to: '/admin/avatar-decorations',
active: currentPage?.route.name === 'avatarDecorations',
}, {
icon: 'ti ti-whirl',
text: i18n.ts.federation,

View file

@ -20,12 +20,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<FormLink to="/admin/server-rules">{{ i18n.ts.serverRules }}</FormLink>
<MkInput v-model="tosUrl">
<MkInput v-model="tosUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts.tosUrl }}</template>
</MkInput>
<MkInput v-model="privacyPolicyUrl">
<MkInput v-model="privacyPolicyUrl" type="url">
<template #prefix><i class="ti ti-link"></i></template>
<template #label>{{ i18n.ts.privacyPolicyUrl }}</template>
</MkInput>

View file

@ -8,9 +8,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>
<b
:class="{
[$style.logGreen]: ['createRole', 'addCustomEmoji', 'createGlobalAnnouncement', 'createUserAnnouncement', 'createAd', 'createInvitation'].includes(log.type),
[$style.logGreen]: ['createRole', 'addCustomEmoji', 'createGlobalAnnouncement', 'createUserAnnouncement', 'createAd', 'createInvitation', 'createAvatarDecoration'].includes(log.type),
[$style.logYellow]: ['markSensitiveDriveFile', 'resetPassword'].includes(log.type),
[$style.logRed]: ['suspend', 'deleteRole', 'suspendRemoteInstance', 'deleteGlobalAnnouncement', 'deleteUserAnnouncement', 'deleteCustomEmoji', 'deleteNote', 'deleteDriveFile', 'deleteAd'].includes(log.type)
[$style.logRed]: ['suspend', 'deleteRole', 'suspendRemoteInstance', 'deleteGlobalAnnouncement', 'deleteUserAnnouncement', 'deleteCustomEmoji', 'deleteNote', 'deleteDriveFile', 'deleteAd', 'deleteAvatarDecoration'].includes(log.type)
}"
>{{ i18n.ts._moderationLogTypes[log.type] }}</b>
<span v-if="log.type === 'updateUserNote'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
@ -37,6 +37,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-else-if="log.type === 'deleteUserAnnouncement'">: @{{ log.info.userUsername }}{{ log.info.userHost ? '@' + log.info.userHost : '' }}</span>
<span v-else-if="log.type === 'deleteNote'">: @{{ log.info.noteUserUsername }}{{ log.info.noteUserHost ? '@' + log.info.noteUserHost : '' }}</span>
<span v-else-if="log.type === 'deleteDriveFile'">: @{{ log.info.fileUserUsername }}{{ log.info.fileUserHost ? '@' + log.info.fileUserHost : '' }}</span>
<span v-else-if="log.type === 'createAvatarDecoration'">: {{ log.info.avatarDecoration.name }}</span>
<span v-else-if="log.type === 'updateAvatarDecoration'">: {{ log.info.before.name }}</span>
<span v-else-if="log.type === 'deleteAvatarDecoration'">: {{ log.info.avatarDecoration.name }}</span>
</template>
<template #icon>
<MkAvatar :user="log.user" :class="$style.avatar"/>
@ -102,6 +105,11 @@ SPDX-License-Identifier: AGPL-3.0-only
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/>
</div>
</template>
<template v-else-if="log.type === 'updateAvatarDecoration'">
<div :class="$style.diff">
<CodeDiff :context="5" :hideHeader="true" :oldString="JSON5.stringify(log.info.before, null, '\t')" :newString="JSON5.stringify(log.info.after, null, '\t')" language="javascript" maxHeight="300px"/>
</div>
</template>
<details>
<summary>raw</summary>

View file

@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="useObjectStorage">{{ i18n.ts.useObjectStorage }}</MkSwitch>
<template v-if="useObjectStorage">
<MkInput v-model="objectStorageBaseUrl" :placeholder="'https://example.com'">
<MkInput v-model="objectStorageBaseUrl" :placeholder="'https://example.com'" type="url">
<template #label>{{ i18n.ts.objectStorageBaseUrl }}</template>
<template #caption>{{ i18n.ts.objectStorageBaseUrlDesc }}</template>
</MkInput>

View file

@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts.color }}</template>
</MkColorInput>
<MkInput v-model="role.iconUrl">
<MkInput v-model="role.iconUrl" type="url">
<template #label>{{ i18n.ts._role.iconUrl }}</template>
</MkInput>
@ -319,6 +319,26 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</MkFolder>
<MkFolder v-if="matchQuery([i18n.ts._role._options.canManageAvatarDecorations, 'canManageAvatarDecorations'])">
<template #label>{{ i18n.ts._role._options.canManageAvatarDecorations }}</template>
<template #suffix>
<span v-if="role.policies.canManageAvatarDecorations.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span>
<span v-else>{{ role.policies.canManageAvatarDecorations.value ? i18n.ts.yes : i18n.ts.no }}</span>
<span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.canManageAvatarDecorations)"></i></span>
</template>
<div class="_gaps">
<MkSwitch v-model="role.policies.canManageAvatarDecorations.useDefault" :readonly="readonly">
<template #label>{{ i18n.ts._role.useBaseValue }}</template>
</MkSwitch>
<MkSwitch v-model="role.policies.canManageAvatarDecorations.value" :disabled="role.policies.canManageAvatarDecorations.useDefault" :readonly="readonly">
<template #label>{{ i18n.ts.enable }}</template>
</MkSwitch>
<MkRange v-model="role.policies.canManageAvatarDecorations.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''">
<template #label>{{ i18n.ts._role.priority }}</template>
</MkRange>
</div>
</MkFolder>
<MkFolder v-if="matchQuery([i18n.ts._role._options.canSearchNotes, 'canSearchNotes'])">
<template #label>{{ i18n.ts._role._options.canSearchNotes }}</template>
<template #suffix>

View file

@ -103,6 +103,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkInput>
</MkFolder>
<MkFolder v-if="matchQuery([i18n.ts._role._options.canManageAvatarDecorations, 'canManageAvatarDecorations'])">
<template #label>{{ i18n.ts._role._options.canManageAvatarDecorations }}</template>
<template #suffix>{{ policies.canManageAvatarDecorations ? i18n.ts.yes : i18n.ts.no }}</template>
<MkSwitch v-model="policies.canManageAvatarDecorations">
<template #label>{{ i18n.ts.enable }}</template>
</MkSwitch>
</MkFolder>
<MkFolder v-if="matchQuery([i18n.ts._role._options.canManageCustomEmojis, 'canManageCustomEmojis'])">
<template #label>{{ i18n.ts._role._options.canManageCustomEmojis }}</template>
<template #suffix>{{ policies.canManageCustomEmojis ? i18n.ts.yes : i18n.ts.no }}</template>

View file

@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkInput>
</FormSplit>
<MkInput v-model="impressumUrl">
<MkInput v-model="impressumUrl" type="url">
<template #label>{{ i18n.ts.impressumUrl }}</template>
<template #prefix><i class="ti ti-link"></i></template>
<template #caption>{{ i18n.ts.impressumDescription }}</template>
@ -87,9 +87,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</FormSection>
<FormSection>
<template #label>Timeline caching</template>
<template #label>Misskey® Fan-out Timeline Technology (FTT)</template>
<div class="_gaps_m">
<MkSwitch v-model="enableFanoutTimeline">
<template #label>{{ i18n.ts.enable }}</template>
<template #caption>{{ i18n.ts._serverSettings.fanoutTimelineDescription }}</template>
</MkSwitch>
<MkInput v-model="perLocalUserUserTimelineCacheMax" type="number">
<template #label>perLocalUserUserTimelineCacheMax</template>
</MkInput>
@ -165,6 +170,7 @@ let cacheRemoteSensitiveFiles: boolean = $ref(false);
let enableServiceWorker: boolean = $ref(false);
let swPublicKey: any = $ref(null);
let swPrivateKey: any = $ref(null);
let enableFanoutTimeline: boolean = $ref(false);
let perLocalUserUserTimelineCacheMax: number = $ref(0);
let perRemoteUserUserTimelineCacheMax: number = $ref(0);
let perUserHomeTimelineCacheMax: number = $ref(0);
@ -185,6 +191,7 @@ async function init(): Promise<void> {
enableServiceWorker = meta.enableServiceWorker;
swPublicKey = meta.swPublickey;
swPrivateKey = meta.swPrivateKey;
enableFanoutTimeline = meta.enableFanoutTimeline;
perLocalUserUserTimelineCacheMax = meta.perLocalUserUserTimelineCacheMax;
perRemoteUserUserTimelineCacheMax = meta.perRemoteUserUserTimelineCacheMax;
perUserHomeTimelineCacheMax = meta.perUserHomeTimelineCacheMax;
@ -206,6 +213,7 @@ async function save(): void {
enableServiceWorker,
swPublicKey,
swPrivateKey,
enableFanoutTimeline,
perLocalUserUserTimelineCacheMax,
perRemoteUserUserTimelineCacheMax,
perUserHomeTimelineCacheMax,