1
1
mirror of https://github.com/kokonect-link/cherrypick synced 2025-01-21 17:23:56 +09:00

fix(frontend): CherryPick 클라이언트 업데이트를 올바르게 확인하지 못할 수 있음

This commit is contained in:
NoriDev 2024-08-26 16:47:24 +09:00
parent 56a0832913
commit d826a1ad27
9 changed files with 246 additions and 95 deletions

View File

@ -28,6 +28,12 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2024xx](CHANGE
기반 Misskey 버전: 2024.x.x<br> 기반 Misskey 버전: 2024.x.x<br>
Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2024xx](CHANGELOG.md#2024xx) 문서를 참고하십시오. Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2024xx](CHANGELOG.md#2024xx) 문서를 참고하십시오.
### Client
- Fix: CherryPick 클라이언트 업데이트를 올바르게 확인하지 못할 수 있음
- 일부 버전에서 버전 확인 오류가 발생할 수 있음
- 예: `4.9.0 < 4.10.0` 계산 시 `4.9.0`이 더 큰 것으로 계산됨
- CherryPick 클라이언트 업데이트 페이지에서 버전 알림이 작동하지 않을 수 있음
### Server ### Server
- Fix: `Announce`를 사용하는 릴레이 서버의 노트를 가져올 수 없음 (kokonect-link/cherrypick#483) - Fix: `Announce`를 사용하는 릴레이 서버의 노트를 가져올 수 없음 (kokonect-link/cherrypick#483)
- Fix: 번역 기능을 사용할 수 없을 수 있음 (kokonect-link/cherrypick#486) - Fix: 번역 기능을 사용할 수 없을 수 있음 (kokonect-link/cherrypick#486)

View File

@ -70,7 +70,7 @@ let noInquiryUrl = isEmpty(instance.inquiryUrl);
const thereIsUnresolvedAbuseReport = ref(false); const thereIsUnresolvedAbuseReport = ref(false);
const currentPage = computed(() => router.currentRef.value.child); const currentPage = computed(() => router.currentRef.value.child);
const updateAvailable = ref(false); const updateAvailable = ref(false);
const releasesCherryPick = ref(); const releasesCherryPick = ref(null);
misskeyApi('admin/abuse-user-reports', { misskeyApi('admin/abuse-user-reports', {
state: 'unresolved', state: 'unresolved',
@ -79,14 +79,19 @@ misskeyApi('admin/abuse-user-reports', {
if (reports.length > 0) thereIsUnresolvedAbuseReport.value = true; if (reports.length > 0) thereIsUnresolvedAbuseReport.value = true;
}); });
fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases', { misskeyApi('admin/meta')
method: 'GET', .then(meta => {
}).then(res => res.json()) return fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases')
.then(async res => { .then(res => res.json())
const meta = await misskeyApi('admin/meta'); .then(cherryPickData => {
if (meta.enableReceivePrerelease) releasesCherryPick.value = res; releasesCherryPick.value = meta.enableReceivePrerelease ? cherryPickData : cherryPickData.filter(x => !x.prerelease);
else releasesCherryPick.value = res.filter(x => x.prerelease === false); if ((compareVersions(version, releasesCherryPick.value[0].tag_name) < 0) && (compareVersions(meta.skipCherryPickVersion, releasesCherryPick.value[0].tag_name) < 0)) {
if ((version < releasesCherryPick.value[0].tag_name) && (meta.skipCherryPickVersion < releasesCherryPick.value[0].tag_name)) updateAvailable.value = true; updateAvailable.value = true;
}
});
})
.catch(error => {
console.error('Failed to fetch CherryPick releases:', error);
}); });
const NARROW_THRESHOLD = 600; const NARROW_THRESHOLD = 600;
@ -293,6 +298,20 @@ provideMetadataReceiver((metadataGetter) => {
}); });
provideReactiveMetadata(INFO); provideReactiveMetadata(INFO);
function compareVersions(v1: string, v2: string): number {
const v1Parts = v1.split('.').map(Number);
const v2Parts = v2.split('.').map(Number);
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const part1 = v1Parts[i] || 0;
const part2 = v2Parts[i] || 0;
if (part1 < part2) return -1;
if (part1 > part2) return 1;
}
return 0;
}
function invite() { function invite() {
misskeyApi('admin/invite/create').then(x => { misskeyApi('admin/invite/create').then(x => {
os.alert({ os.alert({

View File

@ -15,11 +15,12 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSwitch> </MkSwitch>
</div> </div>
<template> <template v-if="(version && version.length > 0) && (releasesCherryPick && releasesCherryPick.length > 0)">
<FormInfo v-if="version > releasesCherryPick[0].tag_name">{{ i18n.ts.youAreRunningBetaClient }}</FormInfo> <FormInfo v-if="compareVersions(version, releasesCherryPick[0].tag_name) > 0">{{ i18n.ts.youAreRunningBetaClient }}</FormInfo>
<FormInfo v-else-if="version === releasesCherryPick[0].tag_name">{{ i18n.ts.youAreRunningUpToDateClient }}</FormInfo> <FormInfo v-else-if="compareVersions(version, releasesCherryPick[0].tag_name) === 0">{{ i18n.ts.youAreRunningUpToDateClient }}</FormInfo>
<FormInfo v-else warn>{{ i18n.ts.newVersionOfClientAvailable }}</FormInfo> <FormInfo v-else warn>{{ i18n.ts.newVersionOfClientAvailable }}</FormInfo>
</template> </template>
<FormInfo v-else>{{ i18n.ts.loading }}</FormInfo>
<FormSection first> <FormSection first>
<template #label>{{ instanceName }}</template> <template #label>{{ instanceName }}</template>
@ -32,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template v-if="releasesCherryPick" #value>{{ releasesCherryPick[0].tag_name }}</template> <template v-if="releasesCherryPick" #value>{{ releasesCherryPick[0].tag_name }}</template>
<template v-else #value><MkEllipsis/></template> <template v-else #value><MkEllipsis/></template>
</MkKeyValue> </MkKeyValue>
<MkButton v-if="!skipVersion && (version < releasesCherryPick[0].tag_name)" style="margin-top: 10px;" @click="skipThisVersion">{{ i18n.ts.skipThisVersion }}</MkButton> <MkButton v-if="!skipVersion && (compareVersions(version, releasesCherryPick[0].tag_name) < 0)" style="margin-top: 10px;" @click="skipThisVersion">{{ i18n.ts.skipThisVersion }}</MkButton>
</FormSection> </FormSection>
<FormSection @click="whatIsNewLatestCherryPick"> <FormSection @click="whatIsNewLatestCherryPick">
@ -67,7 +68,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onMounted, ref } from 'vue'; import { computed, ref } from 'vue';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { misskeyApi } from '@/scripts/misskey-api.js'; import { misskeyApi } from '@/scripts/misskey-api.js';
import FormInfo from '@/components/MkInfo.vue'; import FormInfo from '@/components/MkInfo.vue';
@ -84,10 +85,10 @@ import MkButton from '@/components/MkButton.vue';
const enableReceivePrerelease = ref<boolean>(false); const enableReceivePrerelease = ref<boolean>(false);
const skipVersion = ref<boolean>(false); const skipVersion = ref<boolean>(false);
const skipCherryPickVersion = ref<string | null | undefined>(null); const skipCherryPickVersion = ref<string | null>(null);
const releasesCherryPick = ref(); const releasesCherryPick = ref(null);
const releasesMisskey = ref(); const releasesMisskey = ref(null);
const meta = await misskeyApi('admin/meta'); const meta = await misskeyApi('admin/meta');
@ -95,13 +96,46 @@ async function init() {
enableReceivePrerelease.value = meta.enableReceivePrerelease; enableReceivePrerelease.value = meta.enableReceivePrerelease;
skipVersion.value = meta.skipVersion; skipVersion.value = meta.skipVersion;
skipCherryPickVersion.value = meta.skipCherryPickVersion; skipCherryPickVersion.value = meta.skipCherryPickVersion;
try {
// CherryPick Releases Fetch
const cherryPickResponse = await fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases');
const cherryPickData = await cherryPickResponse.json();
releasesCherryPick.value = meta.enableReceivePrerelease ? cherryPickData : cherryPickData.filter(x => !x.prerelease);
if (compareVersions(skipCherryPickVersion.value, releasesCherryPick.value[0].tag_name) < 0) {
skipVersion.value = false;
await misskeyApi('admin/update-meta', { skipVersion: skipVersion.value });
}
// Misskey Releases Fetch
const misskeyResponse = await fetch('https://api.github.com/repos/misskey-dev/misskey/releases');
const misskeyData = await misskeyResponse.json();
releasesMisskey.value = meta.enableReceivePrerelease ? misskeyData : misskeyData.filter(x => !x.prerelease);
} catch (error) {
console.error('Failed to fetch releases:', error);
}
}
function compareVersions(v1: string, v2: string): number {
const v1Parts = v1.split('.').map(Number);
const v2Parts = v2.split('.').map(Number);
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const part1 = v1Parts[i] || 0;
const part2 = v2Parts[i] || 0;
if (part1 < part2) return -1;
if (part1 > part2) return 1;
}
return 0;
} }
function save() { function save() {
os.apiWithDialog('admin/update-meta', { os.apiWithDialog('admin/update-meta', {
enableReceivePrerelease: enableReceivePrerelease.value, enableReceivePrerelease: enableReceivePrerelease.value,
}).then(() => { }).then(() => {
fetchInstance(); fetchInstance(true);
}); });
} }
@ -113,32 +147,10 @@ function skipThisVersion() {
skipVersion: skipVersion.value, skipVersion: skipVersion.value,
skipCherryPickVersion: skipCherryPickVersion.value, skipCherryPickVersion: skipCherryPickVersion.value,
}).then(() => { }).then(() => {
fetchInstance(); fetchInstance(true);
}); });
} }
onMounted(() => {
fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases', {
method: 'GET',
}).then(res => res.json())
.then(res => {
if (meta.enableReceivePrerelease) releasesCherryPick.value = res;
else releasesCherryPick.value = res.filter(x => x.prerelease === false);
if (skipCherryPickVersion.value < releasesCherryPick.value[0].tag_name) {
skipVersion.value = false;
misskeyApi('admin/update-meta', { skipVersion: skipVersion.value });
}
});
fetch('https://api.github.com/repos/misskey-dev/misskey/releases', {
method: 'GET',
}).then(res => res.json())
.then(res => {
if (meta.enableReceivePrerelease) releasesMisskey.value = res;
else releasesMisskey.value = res.filter(x => x.prerelease === false);
});
});
const whatIsNewCherryPick = () => { const whatIsNewCherryPick = () => {
window.open(`https://github.com/kokonect-link/cherrypick/blob/develop/CHANGELOG_CHERRYPICK.md#${version.replace(/\./g, '')}`, '_blank'); window.open(`https://github.com/kokonect-link/cherrypick/blob/develop/CHANGELOG_CHERRYPICK.md#${version.replace(/\./g, '')}`, '_blank');
}; };

View File

@ -74,7 +74,7 @@ const otherMenuItemIndicated = computed(() => {
return false; return false;
}); });
const controlPanelIndicated = ref(false); const controlPanelIndicated = ref(false);
const releasesCherryPick = ref(); const releasesCherryPick = ref(null);
if ($i.isAdmin ?? $i.isModerator) { if ($i.isAdmin ?? $i.isModerator) {
misskeyApi('admin/abuse-user-reports', { misskeyApi('admin/abuse-user-reports', {
@ -84,17 +84,36 @@ if ($i.isAdmin ?? $i.isModerator) {
if (reports.length > 0) controlPanelIndicated.value = true; if (reports.length > 0) controlPanelIndicated.value = true;
}); });
fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases', { misskeyApi('admin/meta')
method: 'GET', .then(meta => {
}).then(res => res.json()) return fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases')
.then(async res => { .then(res => res.json())
const meta = await misskeyApi('admin/meta'); .then(cherryPickData => {
if (meta.enableReceivePrerelease) releasesCherryPick.value = res; releasesCherryPick.value = meta.enableReceivePrerelease ? cherryPickData : cherryPickData.filter(x => !x.prerelease);
else releasesCherryPick.value = res.filter(x => x.prerelease === false); if ((compareVersions(version, releasesCherryPick.value[0].tag_name) < 0) && (compareVersions(meta.skipCherryPickVersion, releasesCherryPick.value[0].tag_name) < 0)) {
if ((version < releasesCherryPick.value[0].tag_name) && (meta.skipCherryPickVersion < releasesCherryPick.value[0].tag_name)) controlPanelIndicated.value = true; controlPanelIndicated.value = true;
}
});
})
.catch(error => {
console.error('Failed to fetch CherryPick releases:', error);
}); });
} }
function compareVersions(v1: string, v2: string): number {
const v1Parts = v1.split('.').map(Number);
const v2Parts = v2.split('.').map(Number);
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const part1 = v1Parts[i] || 0;
const part2 = v2Parts[i] || 0;
if (part1 < part2) return -1;
if (part1 > part2) return 1;
}
return 0;
}
function openAccountMenu(ev: MouseEvent) { function openAccountMenu(ev: MouseEvent) {
openAccountMenu_({ openAccountMenu_({
withExtraOperation: true, withExtraOperation: true,

View File

@ -86,7 +86,7 @@ const otherMenuItemIndicated = computed(() => {
return false; return false;
}); });
const controlPanelIndicated = ref(false); const controlPanelIndicated = ref(false);
const releasesCherryPick = ref(); const releasesCherryPick = ref(null);
if ($i.isAdmin ?? $i.isModerator) { if ($i.isAdmin ?? $i.isModerator) {
misskeyApi('admin/abuse-user-reports', { misskeyApi('admin/abuse-user-reports', {
@ -96,14 +96,19 @@ if ($i.isAdmin ?? $i.isModerator) {
if (reports.length > 0) controlPanelIndicated.value = true; if (reports.length > 0) controlPanelIndicated.value = true;
}); });
fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases', { misskeyApi('admin/meta')
method: 'GET', .then(meta => {
}).then(res => res.json()) return fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases')
.then(async res => { .then(res => res.json())
const meta = await misskeyApi('admin/meta'); .then(cherryPickData => {
if (meta.enableReceivePrerelease) releasesCherryPick.value = res; releasesCherryPick.value = meta.enableReceivePrerelease ? cherryPickData : cherryPickData.filter(x => !x.prerelease);
else releasesCherryPick.value = res.filter(x => x.prerelease === false); if ((compareVersions(version, releasesCherryPick.value[0].tag_name) < 0) && (compareVersions(meta.skipCherryPickVersion, releasesCherryPick.value[0].tag_name) < 0)) {
if ((version < releasesCherryPick.value[0].tag_name) && (meta.skipCherryPickVersion < releasesCherryPick.value[0].tag_name)) controlPanelIndicated.value = true; controlPanelIndicated.value = true;
}
});
})
.catch(error => {
console.error('Failed to fetch CherryPick releases:', error);
}); });
} }
@ -119,6 +124,20 @@ watch(defaultStore.reactiveState.menuDisplay, () => {
calcViewState(); calcViewState();
}); });
function compareVersions(v1: string, v2: string): number {
const v1Parts = v1.split('.').map(Number);
const v2Parts = v2.split('.').map(Number);
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const part1 = v1Parts[i] || 0;
const part2 = v2Parts[i] || 0;
if (part1 < part2) return -1;
if (part1 > part2) return 1;
}
return 0;
}
function openAccountMenu(ev: MouseEvent) { function openAccountMenu(ev: MouseEvent) {
openAccountMenu_({ openAccountMenu_({
withExtraOperation: true, withExtraOperation: true,

View File

@ -74,7 +74,7 @@ const otherNavItemIndicated = computed<boolean>(() => {
}); });
const controlPanelIndicated = ref(false); const controlPanelIndicated = ref(false);
const releasesCherryPick = ref(); const releasesCherryPick = ref(null);
if ($i.isAdmin ?? $i.isModerator) { if ($i.isAdmin ?? $i.isModerator) {
misskeyApi('admin/abuse-user-reports', { misskeyApi('admin/abuse-user-reports', {
@ -84,17 +84,36 @@ if ($i.isAdmin ?? $i.isModerator) {
if (reports.length > 0) controlPanelIndicated.value = true; if (reports.length > 0) controlPanelIndicated.value = true;
}); });
fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases', { misskeyApi('admin/meta')
method: 'GET', .then(meta => {
}).then(res => res.json()) return fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases')
.then(async res => { .then(res => res.json())
const meta = await misskeyApi('admin/meta'); .then(cherryPickData => {
if (meta.enableReceivePrerelease) releasesCherryPick.value = res; releasesCherryPick.value = meta.enableReceivePrerelease ? cherryPickData : cherryPickData.filter(x => !x.prerelease);
else releasesCherryPick.value = res.filter(x => x.prerelease === false); if ((compareVersions(version, releasesCherryPick.value[0].tag_name) < 0) && (compareVersions(meta.skipCherryPickVersion, releasesCherryPick.value[0].tag_name) < 0)) {
if ((version < releasesCherryPick.value[0].tag_name) && (meta.skipCherryPickVersion < releasesCherryPick.value[0].tag_name)) controlPanelIndicated.value = true; controlPanelIndicated.value = true;
}
});
})
.catch(error => {
console.error('Failed to fetch CherryPick releases:', error);
}); });
} }
function compareVersions(v1: string, v2: string): number {
const v1Parts = v1.split('.').map(Number);
const v2Parts = v2.split('.').map(Number);
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const part1 = v1Parts[i] || 0;
const part2 = v2Parts[i] || 0;
if (part1 < part2) return -1;
if (part1 > part2) return 1;
}
return 0;
}
function more(ev: MouseEvent) { function more(ev: MouseEvent) {
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkLaunchPad.vue')), { const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkLaunchPad.vue')), {
src: ev.currentTarget ?? ev.target, src: ev.currentTarget ?? ev.target,

View File

@ -83,7 +83,7 @@ const el = shallowRef<HTMLElement>();
const iconOnly = ref(false); const iconOnly = ref(false);
const settingsWindowed = ref(false); const settingsWindowed = ref(false);
const controlPanelIndicated = ref(false); const controlPanelIndicated = ref(false);
const releasesCherryPick = ref(); const releasesCherryPick = ref(null);
if ($i.isAdmin ?? $i.isModerator) { if ($i.isAdmin ?? $i.isModerator) {
misskeyApi('admin/abuse-user-reports', { misskeyApi('admin/abuse-user-reports', {
@ -93,17 +93,36 @@ if ($i.isAdmin ?? $i.isModerator) {
if (reports.length > 0) controlPanelIndicated.value = true; if (reports.length > 0) controlPanelIndicated.value = true;
}); });
fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases', { misskeyApi('admin/meta')
method: 'GET', .then(meta => {
}).then(res => res.json()) return fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases')
.then(async res => { .then(res => res.json())
const meta = await misskeyApi('admin/meta'); .then(cherryPickData => {
if (meta.enableReceivePrerelease) releasesCherryPick.value = res; releasesCherryPick.value = meta.enableReceivePrerelease ? cherryPickData : cherryPickData.filter(x => !x.prerelease);
else releasesCherryPick.value = res.filter(x => x.prerelease === false); if ((compareVersions(version, releasesCherryPick.value[0].tag_name) < 0) && (compareVersions(meta.skipCherryPickVersion, releasesCherryPick.value[0].tag_name) < 0)) {
if ((version < releasesCherryPick.value[0].tag_name) && (meta.skipCherryPickVersion < releasesCherryPick.value[0].tag_name)) controlPanelIndicated.value = true; controlPanelIndicated.value = true;
}
});
})
.catch(error => {
console.error('Failed to fetch CherryPick releases:', error);
}); });
} }
function compareVersions(v1: string, v2: string): number {
const v1Parts = v1.split('.').map(Number);
const v2Parts = v2.split('.').map(Number);
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const part1 = v1Parts[i] || 0;
const part2 = v2Parts[i] || 0;
if (part1 < part2) return -1;
if (part1 > part2) return 1;
}
return 0;
}
function calcViewState() { function calcViewState() {
iconOnly.value = (window.innerWidth <= WINDOW_THRESHOLD) || (menuDisplay.value === 'sideIcon'); iconOnly.value = (window.innerWidth <= WINDOW_THRESHOLD) || (menuDisplay.value === 'sideIcon');
settingsWindowed.value = (window.innerWidth > WINDOW_THRESHOLD); settingsWindowed.value = (window.innerWidth > WINDOW_THRESHOLD);

View File

@ -76,7 +76,7 @@ const otherMenuItemIndicated = computed(() => {
return false; return false;
}); });
const controlPanelIndicated = ref(false); const controlPanelIndicated = ref(false);
const releasesCherryPick = ref(); const releasesCherryPick = ref(null);
if ($i.isAdmin ?? $i.isModerator) { if ($i.isAdmin ?? $i.isModerator) {
misskeyApi('admin/abuse-user-reports', { misskeyApi('admin/abuse-user-reports', {
@ -86,17 +86,36 @@ if ($i.isAdmin ?? $i.isModerator) {
if (reports.length > 0) controlPanelIndicated.value = true; if (reports.length > 0) controlPanelIndicated.value = true;
}); });
fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases', { misskeyApi('admin/meta')
method: 'GET', .then(meta => {
}).then(res => res.json()) return fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases')
.then(async res => { .then(res => res.json())
const meta = await misskeyApi('admin/meta'); .then(cherryPickData => {
if (meta.enableReceivePrerelease) releasesCherryPick.value = res; releasesCherryPick.value = meta.enableReceivePrerelease ? cherryPickData : cherryPickData.filter(x => !x.prerelease);
else releasesCherryPick.value = res.filter(x => x.prerelease === false); if ((compareVersions(version, releasesCherryPick.value[0].tag_name) < 0) && (compareVersions(meta.skipCherryPickVersion, releasesCherryPick.value[0].tag_name) < 0)) {
if ((version < releasesCherryPick.value[0].tag_name) && (meta.skipCherryPickVersion < releasesCherryPick.value[0].tag_name)) controlPanelIndicated.value = true; controlPanelIndicated.value = true;
}
});
})
.catch(error => {
console.error('Failed to fetch CherryPick releases:', error);
}); });
} }
function compareVersions(v1: string, v2: string): number {
const v1Parts = v1.split('.').map(Number);
const v2Parts = v2.split('.').map(Number);
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const part1 = v1Parts[i] || 0;
const part2 = v2Parts[i] || 0;
if (part1 < part2) return -1;
if (part1 > part2) return 1;
}
return 0;
}
function openAccountMenu(ev: MouseEvent) { function openAccountMenu(ev: MouseEvent) {
openAccountMenu_({ openAccountMenu_({
withExtraOperation: true, withExtraOperation: true,

View File

@ -93,7 +93,7 @@ const otherMenuItemIndicated = computed(() => {
return false; return false;
}); });
const controlPanelIndicated = ref(false); const controlPanelIndicated = ref(false);
const releasesCherryPick = ref(); const releasesCherryPick = ref(null);
if ($i.isAdmin ?? $i.isModerator) { if ($i.isAdmin ?? $i.isModerator) {
misskeyApi('admin/abuse-user-reports', { misskeyApi('admin/abuse-user-reports', {
@ -103,14 +103,19 @@ if ($i.isAdmin ?? $i.isModerator) {
if (reports.length > 0) controlPanelIndicated.value = true; if (reports.length > 0) controlPanelIndicated.value = true;
}); });
fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases', { misskeyApi('admin/meta')
method: 'GET', .then(meta => {
}).then(res => res.json()) return fetch('https://api.github.com/repos/kokonect-link/cherrypick/releases')
.then(async res => { .then(res => res.json())
const meta = await misskeyApi('admin/meta'); .then(cherryPickData => {
if (meta.enableReceivePrerelease) releasesCherryPick.value = res; releasesCherryPick.value = meta.enableReceivePrerelease ? cherryPickData : cherryPickData.filter(x => !x.prerelease);
else releasesCherryPick.value = res.filter(x => x.prerelease === false); if ((compareVersions(version, releasesCherryPick.value[0].tag_name) < 0) && (compareVersions(meta.skipCherryPickVersion, releasesCherryPick.value[0].tag_name) < 0)) {
if ((version < releasesCherryPick.value[0].tag_name) && (meta.skipCherryPickVersion < releasesCherryPick.value[0].tag_name)) controlPanelIndicated.value = true; controlPanelIndicated.value = true;
}
});
})
.catch(error => {
console.error('Failed to fetch CherryPick releases:', error);
}); });
} }
@ -126,6 +131,20 @@ watch(defaultStore.reactiveState.menuDisplay, () => {
calcViewState(); calcViewState();
}); });
function compareVersions(v1: string, v2: string): number {
const v1Parts = v1.split('.').map(Number);
const v2Parts = v2.split('.').map(Number);
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
const part1 = v1Parts[i] || 0;
const part2 = v2Parts[i] || 0;
if (part1 < part2) return -1;
if (part1 > part2) return 1;
}
return 0;
}
function openAccountMenu(ev: MouseEvent) { function openAccountMenu(ev: MouseEvent) {
openAccountMenu_({ openAccountMenu_({
withExtraOperation: true, withExtraOperation: true,