feat: ✨ Toggle showing calckey updates as admin
This commit is contained in:
parent
07c6472ba6
commit
7559a0d81a
8 changed files with 54 additions and 13 deletions
|
@ -917,6 +917,7 @@ splash: "Splash Screen"
|
|||
updateAvailable: "There might be an update available!"
|
||||
swipeOnDesktop: "Allow mobile-style swiping on desktop"
|
||||
logoImageUrl: "Logo image URL"
|
||||
showAdminUpdates: "Indicate a new Calckey version is avaliable (admin only)"
|
||||
|
||||
_sensitiveMediaDetection:
|
||||
description: "Reduces the effort of server moderation through automatically recognizing NSFW media via Machine Learning. This will slightly increase the load on the server."
|
||||
|
|
|
@ -905,18 +905,19 @@ shuffle: "シャッフル"
|
|||
account: "アカウント"
|
||||
move: "移動"
|
||||
adminCustomCssWarn: "この設定は、それが何をするものであるかを知っている場合のみ使用してください。不適切な値を入力すると、クライアントが正常に動作しなくなる可能性があります。ユーザー設定でCSSをテストし、正しく動作することを確認してください。"
|
||||
customMOTD: "カスタムMOTD(スプラッシュスクリーンメッセージ)"
|
||||
customMOTDDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたMOTD(スプラッシュスクリーン)用のカスタムメッセージ"
|
||||
customMOTD: "カスタムMOTD(スプラッシュスクリーンメッセージ)"
|
||||
customMOTDDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたMOTD(スプラッシュスクリーン)用のカスタムメッセージ"
|
||||
customSplashIcons: "カスタムスプラッシュスクリーンアイコン"
|
||||
customSplashIconsDescription: "ユーザがページをロード/リロードするたびにランダムに表示される、改行で区切られたカスタムスプラッシュスクリーンアイコンの URL。画像は静的なURLで、できればすべて192x192にリサイズしてください。"
|
||||
showUpdates: "Calckeyの更新時にポップアップを表示する"
|
||||
recommendedInstances: "推奨インスタンス"
|
||||
recommendedInstancesDescription: "推奨タイムラインに表示するために改行で区切られた推奨インスタンス。`https://`を追加しないでください。ドメインのみを追加してください。"
|
||||
recommendedInstancesDescription: "推奨タイムラインに表示するために改行で区切られた推奨インスタンス。`https://`を追加しないでください。ドメインのみを追加してください。"
|
||||
caption: "自動キャプション"
|
||||
splash: "スプラッシュスクリーン"
|
||||
updateAvailable: "アップデートがありますよ"
|
||||
swipeOnDesktop: "デスクトップでモバイルスタイルのスワイプを可能にする"
|
||||
logoImageUrl: "ロゴのURL"
|
||||
showAdminUpdates: "新しいCalckeyのバージョンが利用可能であることを示す(管理者のみ)"
|
||||
|
||||
_sensitiveMediaDetection:
|
||||
description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "calckey",
|
||||
"version": "12.119.0-calc.4.1",
|
||||
"version": "12.119.0-calc.4.2",
|
||||
"codename": "aqua",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -33,6 +33,7 @@ import { instance } from '@/instance';
|
|||
import { version } from '@/config';
|
||||
import * as os from '@/os';
|
||||
import { lookupUser } from '@/scripts/lookup-user';
|
||||
import { defaultStore } from '@/store';
|
||||
import { useRouter } from '@/router';
|
||||
import { definePageMetadata, provideMetadataReceiver, setPageMetadata } from '@/scripts/page-metadata';
|
||||
|
||||
|
@ -68,13 +69,15 @@ os.api('admin/abuse-user-reports', {
|
|||
if (reports?.length > 0) thereIsUnresolvedAbuseReport = true;
|
||||
});
|
||||
|
||||
os.api('latest-version').then(res => {
|
||||
const cleanRes = res?.tag_name.replace(/[^0-9]/g, '');
|
||||
const cleanVersion = version.replace(/[^0-9]/g, '');
|
||||
if (cleanRes !== cleanVersion) {
|
||||
updateAvailable = true;
|
||||
}
|
||||
});
|
||||
if (defaultStore.state.showAdminUpdates) {
|
||||
os.api('latest-version').then(res => {
|
||||
const cleanRes = res?.tag_name.replace(/[^0-9]/g, '');
|
||||
const cleanVersion = version.replace(/[^0-9]/g, '');
|
||||
if (cleanRes !== cleanVersion) {
|
||||
updateAvailable = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const NARROW_THRESHOLD = 600;
|
||||
const ro = new ResizeObserver((entries, observer) => {
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
</FormSwitch>
|
||||
<FormSwitch v-model="disableDrawer" class="_formBlock">{{ i18n.ts.disableDrawer }}</FormSwitch>
|
||||
<FormSwitch v-model="showUpdates" class="_formBlock">{{ i18n.ts.showUpdates }}</FormSwitch>
|
||||
<FormSwitch v-if="$i?.isAdmin" v-model="showAdminUpdates" class="_formBlock">{{ i18n.ts.showAdminUpdates }}</FormSwitch>
|
||||
|
||||
<FormRadios v-model="fontSize" class="_formBlock">
|
||||
<template #label>{{ i18n.ts.fontSize }}</template>
|
||||
|
@ -96,6 +97,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { $i } from '@/account';
|
||||
import FormSwitch from '@/components/form/switch.vue';
|
||||
import FormSelect from '@/components/form/select.vue';
|
||||
import FormRadios from '@/components/form/radios.vue';
|
||||
|
@ -149,6 +151,7 @@ const seperateRenoteQuote = computed(defaultStore.makeGetterSetter('seperateReno
|
|||
const squareAvatars = computed(defaultStore.makeGetterSetter('squareAvatars'));
|
||||
const showUpdates = computed(defaultStore.makeGetterSetter('showUpdates'));
|
||||
const swipeOnDesktop = computed(defaultStore.makeGetterSetter('swipeOnDesktop'));
|
||||
const showAdminUpdates = computed(defaultStore.makeGetterSetter('showAdminUpdates'));
|
||||
|
||||
watch(lang, () => {
|
||||
localStorage.setItem('lang', lang.value as string);
|
||||
|
@ -184,6 +187,7 @@ watch([
|
|||
showUpdates,
|
||||
swipeOnDesktop,
|
||||
seperateRenoteQuote,
|
||||
showAdminUpdates,
|
||||
], async () => {
|
||||
await reloadAsk();
|
||||
});
|
||||
|
|
|
@ -85,6 +85,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
|
|||
'numberOfPageCache',
|
||||
'showUpdates',
|
||||
'swipeOnDesktop',
|
||||
'showAdminUpdates',
|
||||
];
|
||||
const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
|
||||
'lightTheme',
|
||||
|
|
|
@ -263,6 +263,10 @@ export const defaultStore = markRaw(new Storage('base', {
|
|||
where: 'device',
|
||||
default: false,
|
||||
},
|
||||
showAdminUpdates: {
|
||||
where: 'account',
|
||||
default: false,
|
||||
}
|
||||
}));
|
||||
|
||||
// TODO: 他のタブと永続化されたstateを同期
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</template>
|
||||
<div class="divider"></div>
|
||||
<MkA v-if="$i.isAdmin || $i.isModerator" v-click-anime v-tooltip.noDelay.right="i18n.ts.controlPanel" class="item" active-class="active" to="/admin">
|
||||
<i class="icon fas fa-door-open fa-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
|
||||
<span v-if="thereIsUnresolvedAbuseReport || noMaintainerInformation || noBotProtection || noEmailServer || updateAvailable" class="indicator"></span><i class="icon fas fa-door-open fa-fw"></i><span class="text">{{ i18n.ts.controlPanel }}</span>
|
||||
</MkA>
|
||||
<button v-click-anime class="item _button" @click="more">
|
||||
<i class="icon fa fa-ellipsis-h fa-fw"></i><span class="text">{{ i18n.ts.more }}</span>
|
||||
|
@ -63,7 +63,9 @@ import { $i, openAccountMenu as openAccountMenu_ } from '@/account';
|
|||
import { defaultStore } from '@/store';
|
||||
import { i18n } from '@/i18n';
|
||||
import { instance } from '@/instance';
|
||||
import { host } from '@/config';
|
||||
import { host, version } from '@/config';
|
||||
|
||||
const isEmpty = (x: string | null) => x == null || x === '';
|
||||
|
||||
const iconOnly = ref(false);
|
||||
|
||||
|
@ -88,6 +90,31 @@ watch(defaultStore.reactiveState.menuDisplay, () => {
|
|||
calcViewState();
|
||||
});
|
||||
|
||||
let noMaintainerInformation = isEmpty(instance.maintainerName) || isEmpty(instance.maintainerEmail);
|
||||
let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha;
|
||||
let noEmailServer = !instance.enableEmail;
|
||||
let thereIsUnresolvedAbuseReport = $ref(false);
|
||||
let updateAvailable = $ref(false);
|
||||
|
||||
if ($i?.isAdmin) {
|
||||
os.api('admin/abuse-user-reports', {
|
||||
state: 'unresolved',
|
||||
limit: 1,
|
||||
}).then(reports => {
|
||||
if (reports?.length > 0) thereIsUnresolvedAbuseReport = true;
|
||||
});
|
||||
}
|
||||
|
||||
if (defaultStore.state.showAdminUpdates) {
|
||||
os.api('latest-version').then(res => {
|
||||
const cleanRes = res?.tag_name.replace(/[^0-9]/g, '');
|
||||
const cleanVersion = version.replace(/[^0-9]/g, '');
|
||||
if (cleanRes !== cleanVersion) {
|
||||
updateAvailable = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openAccountMenu(ev: MouseEvent) {
|
||||
openAccountMenu_({
|
||||
withExtraOperation: true,
|
||||
|
|
Loading…
Reference in a new issue