feat: Toggle showing calckey updates as admin

This commit is contained in:
ThatOneCalculator 2022-10-25 22:31:19 -07:00
parent 07c6472ba6
commit 7559a0d81a
8 changed files with 54 additions and 13 deletions

View file

@ -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."

View file

@ -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: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。"

View file

@ -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",

View file

@ -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,6 +69,7 @@ os.api('admin/abuse-user-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, '');
@ -75,6 +77,7 @@ os.api('latest-version').then(res => {
updateAvailable = true;
}
});
}
const NARROW_THRESHOLD = 600;
const ro = new ResizeObserver((entries, observer) => {

View file

@ -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();
});

View file

@ -85,6 +85,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
'numberOfPageCache',
'showUpdates',
'swipeOnDesktop',
'showAdminUpdates',
];
const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
'lightTheme',

View file

@ -263,6 +263,10 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'device',
default: false,
},
showAdminUpdates: {
where: 'account',
default: false,
}
}));
// TODO: 他のタブと永続化されたstateを同期

View file

@ -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,