Merge remote-tracking branch 'misskey-original/develop' into develop

# Conflicts:
#	packages/frontend/src/components/MkEmojiEditDialog.vue
#	packages/frontend/src/components/MkMenu.vue
#	packages/frontend/src/pages/about.vue
#	packages/frontend/src/pages/admin/index.vue
#	packages/frontend/src/pages/custom-emojis-manager.vue
#	packages/frontend/src/pages/settings/mute-block.vue
#	packages/frontend/src/pages/settings/theme.vue
#	packages/frontend/src/ui/_common_/navbar-for-mobile.vue
This commit is contained in:
mattyatea 2023-12-26 23:38:43 +09:00
commit 8d058b0529
208 changed files with 1583 additions and 904 deletions

View file

@ -38,7 +38,7 @@ import tinycolor from 'tinycolor2';
import { popupMenu } from '@/os.js';
import { scrollToTop } from '@/scripts/scroll.js';
import MkButton from '@/components/MkButton.vue';
import { globalEvents } from '@/events';
import { globalEvents } from '@/events.js';
import { injectPageMetadata } from '@/scripts/page-metadata.js';
type Tab = {
@ -70,7 +70,7 @@ const metadata = injectPageMetadata();
const el = shallowRef<HTMLElement>(null);
const tabRefs = {};
const tabHighlightEl = shallowRef<HTMLElement | null>(null);
const bg = ref(null);
const bg = ref<string | null>(null);
const height = ref(0);
const hasTabs = computed(() => {
return props.tabs && props.tabs.length > 0;

View file

@ -56,7 +56,7 @@ import { computed, shallowRef, ref } from 'vue';
import XHeader from './_header_.vue';
import MkSelect from '@/components/MkSelect.vue';
import MkPagination from '@/components/MkPagination.vue';
import MkPagination, { Paging } from '@/components/MkPagination.vue';
import XAbuseReport from '@/components/MkAbuseReport.vue';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
@ -77,7 +77,7 @@ const pagination = {
reporterOrigin: reporterOrigin.value,
targetUserOrigin: targetUserOrigin.value,
})),
};
} satisfies Paging;
function resolved(reportId) {
reports.value.removeItem(reportId);

View file

@ -86,6 +86,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { ref, computed } from 'vue';
import * as Misskey from 'misskey-js';
import XHeader from './_header_.vue';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
@ -98,7 +99,7 @@ import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
const ads = ref<any[]>([]);
const ads = ref<Misskey.entities.Ad[]>([]);
// ISOTZUTCTZ
const localTime = new Date();

View file

@ -65,6 +65,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { defineAsyncComponent, ref } from 'vue';
import type { CaptchaProvider } from '@/components/MkCaptcha.vue';
import MkRadios from '@/components/MkRadios.vue';
import MkInput from '@/components/MkInput.vue';
import MkButton from '@/components/MkButton.vue';
@ -76,7 +77,7 @@ import { i18n } from '@/i18n.js';
const MkCaptcha = defineAsyncComponent(() => import('@/components/MkCaptcha.vue'));
const provider = ref(null);
const provider = ref<CaptchaProvider | null>(null);
const hcaptchaSiteKey = ref<string | null>(null);
const hcaptchaSecretKey = ref<string | null>(null);
const recaptchaSiteKey = ref<string | null>(null);

View file

@ -113,9 +113,9 @@ const app192IconUrl = ref<string | null>(null);
const app512IconUrl = ref<string | null>(null);
const bannerUrl = ref<string | null>(null);
const backgroundImageUrl = ref<string | null>(null);
const themeColor = ref<any>(null);
const defaultLightTheme = ref<any>(null);
const defaultDarkTheme = ref<any>(null);
const themeColor = ref<string | null>(null);
const defaultLightTheme = ref<string | null>(null);
const defaultDarkTheme = ref<string | null>(null);
const serverErrorImageUrl = ref<string | null>(null);
const infoImageUrl = ref<string | null>(null);
const notFoundImageUrl = ref<string | null>(null);

View file

@ -79,7 +79,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkButton from '@/components/MkButton.vue';
const enableEmail = ref<boolean>(false);
const email = ref<any>(null);
const email = ref<string | null>(null);
const smtpSecure = ref<boolean>(false);
const smtpHost = ref<string>('');
const smtpPort = ref<number>(0);

View file

@ -62,7 +62,7 @@ import { computed, ref } from 'vue';
import XHeader from './_header_.vue';
import MkInput from '@/components/MkInput.vue';
import MkSelect from '@/components/MkSelect.vue';
import MkPagination from '@/components/MkPagination.vue';
import MkPagination, { Paging } from '@/components/MkPagination.vue';
import MkInstanceCardMini from '@/components/MkInstanceCardMini.vue';
import FormSplit from '@/components/form/split.vue';
import { i18n } from '@/i18n.js';
@ -88,7 +88,7 @@ const pagination = {
state.value === 'notResponding' ? { notResponding: true } :
{}),
})),
};
} satisfies Paging;
function getStatus(instance) {
if (instance.isSuspended) return 'Suspended';

View file

@ -46,7 +46,7 @@ import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
const origin = ref('local');
const type = ref(null);
const type = ref<string | null>(null);
const searchHost = ref('');
const userId = ref('');
const viewMode = ref('grid');

View file

@ -28,7 +28,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import {computed, onActivated, onMounted, onUnmounted, provide, ref, watch } from 'vue';
import { watch,ComputedRef, Ref, onActivated, onMounted, onUnmounted, provide, watch, ref, computed } from 'vue';
import { i18n } from '@/i18n.js';
import MkSuperMenu from '@/components/MkSuperMenu.vue';
import MkInfo from '@/components/MkInfo.vue';
@ -36,7 +36,7 @@ import { instance } from '@/instance.js';
import * as os from '@/os.js';
import { lookupUser, lookupUserByEmail } from '@/scripts/lookup-user.js';
import { useRouter } from '@/router.js';
import { definePageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
import { PageMetadata, definePageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata.js';
import {bannerDark, bannerLight, defaultStore, iconDark, iconLight} from "@/store.js";
const isEmpty = (x: string | null) => x == null || x === '';
@ -52,10 +52,10 @@ const indexInfo = {
provide('shouldOmitHeaderTitle', false);
const INFO = ref(indexInfo);
const childInfo = ref(null);
const childInfo: Ref<ComputedRef<PageMetadata> | null> = ref(null);
const narrow = ref(false);
const view = ref(null);
const el = ref(null);
const el = ref<HTMLDivElement | null>(null);
const pageProps = ref({});
let noMaintainerInformation = isEmpty(instance.maintainerName) || isEmpty(instance.maintainerEmail);
let noBotProtection = !instance.disableRegistration && !instance.enableHcaptcha && !instance.enableRecaptcha && !instance.enableTurnstile;

View file

@ -73,7 +73,7 @@ const pagingComponent = shallowRef<InstanceType<typeof MkPagination>>();
const type = ref('all');
const sort = ref('+createdAt');
const pagination: Paging = {
const pagination = {
endpoint: 'admin/invite/list' as const,
limit: 10,
params: computed(() => ({
@ -81,7 +81,7 @@ const pagination: Paging = {
sort: sort.value,
})),
offsetMode: true,
};
} satisfies Paging;
const expiresAt = ref('');
const noExpirationDate = ref(true);
@ -97,10 +97,10 @@ async function createWithOptions() {
os.alert({
type: 'success',
title: i18n.ts.inviteCodeCreated,
text: tickets?.map(x => x.code).join('\n'),
text: tickets.map(x => x.code).join('\n'),
});
tickets?.forEach(ticket => pagingComponent.value?.prepend(ticket));
tickets.forEach(ticket => pagingComponent.value?.prepend(ticket));
}
function deleted(id: string) {

View file

@ -145,7 +145,7 @@ const props = defineProps<{
}
.logYellow {
color: var(--warning);
color: var(--warn);
}
.logRed {

View file

@ -36,13 +36,13 @@ import XHeader from './_header_.vue';
import XModLog from './modlog.ModLog.vue';
import MkSelect from '@/components/MkSelect.vue';
import MkInput from '@/components/MkInput.vue';
import MkPagination from '@/components/MkPagination.vue';
import MkPagination, { Paging } from '@/components/MkPagination.vue';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
const logs = shallowRef<InstanceType<typeof MkPagination>>();
const type = ref(null);
const type = ref<string | null>(null);
const moderatorId = ref('');
const pagination = {
@ -52,7 +52,7 @@ const pagination = {
type: type.value,
userId: moderatorId.value === '' ? null : moderatorId.value,
})),
};
} satisfies Paging;
console.log(Misskey);

View file

@ -47,15 +47,15 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import XPie from './overview.pie.vue';
import XPie, { type InstanceForPie } from './overview.pie.vue';
import * as os from '@/os.js';
import number from '@/filters/number.js';
import MkNumberDiff from '@/components/MkNumberDiff.vue';
import { i18n } from '@/i18n.js';
import { useChartTooltip } from '@/scripts/use-chart-tooltip.js';
const topSubInstancesForPie = ref<any>(null);
const topPubInstancesForPie = ref<any>(null);
const topSubInstancesForPie = ref<InstanceForPie[] | null>(null);
const topPubInstancesForPie = ref<InstanceForPie[] | null>(null);
const federationPubActive = ref<number | null>(null);
const federationPubActiveDiff = ref<number | null>(null);
const federationSubActive = ref<number | null>(null);
@ -72,22 +72,28 @@ onMounted(async () => {
federationSubActiveDiff.value = chart.subActive[0] - chart.subActive[1];
os.apiGet('federation/stats', { limit: 10 }).then(res => {
topSubInstancesForPie.value = res.topSubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followersCount,
onClick: () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})).concat([{ name: '(other)', color: '#80808080', value: res.otherFollowersCount }]);
topPubInstancesForPie.value = res.topPubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followingCount,
onClick: () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})).concat([{ name: '(other)', color: '#80808080', value: res.otherFollowingCount }]);
topSubInstancesForPie.value = [
...res.topSubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followersCount,
onClick: () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})),
{ name: '(other)', color: '#80808080', value: res.otherFollowersCount },
];
topPubInstancesForPie.value = [
...res.topPubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followingCount,
onClick: () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})),
{ name: '(other)', color: '#80808080', value: res.otherFollowingCount },
];
});
fetching.value = false;

View file

@ -18,12 +18,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { ref } from 'vue';
import * as Misskey from 'misskey-js';
import * as os from '@/os.js';
import { useInterval } from '@/scripts/use-interval.js';
import MkInstanceCardMini from '@/components/MkInstanceCardMini.vue';
import { defaultStore } from '@/store.js';
const instances = ref([]);
const instances = ref<Misskey.entities.FederationInstance[]>([]);
const fetching = ref(true);
const fetch = async () => {

View file

@ -18,10 +18,11 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import * as Misskey from 'misskey-js';
import * as os from '@/os.js';
import { defaultStore } from '@/store.js';
const moderators = ref<any>(null);
const moderators = ref<Misskey.entities.UserDetailed[] | null>(null);
const fetching = ref(true);
onMounted(async () => {

View file

@ -13,10 +13,17 @@ import { Chart } from 'chart.js';
import { useChartTooltip } from '@/scripts/use-chart-tooltip.js';
import { initChart } from '@/scripts/init-chart.js';
export type InstanceForPie = {
name: string,
color: string | null,
value: number,
onClick?: () => void
};
initChart();
const props = defineProps<{
data: { name: string; value: number; color: string; onClick?: () => void }[];
data: InstanceForPie[];
}>();
const chartEl = shallowRef<HTMLCanvasElement>(null);

View file

@ -62,6 +62,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import * as Misskey from 'misskey-js';
import * as os from '@/os.js';
import MkNumberDiff from '@/components/MkNumberDiff.vue';
import MkNumber from '@/components/MkNumber.vue';
@ -69,7 +70,7 @@ import { i18n } from '@/i18n.js';
import { customEmojis } from '@/custom-emojis.js';
import { defaultStore } from '@/store.js';
const stats = ref<any>(null);
const stats = ref<Misskey.entities.StatsResponse | null>(null);
const usersComparedToThePrevDay = ref<number>();
const notesComparedToThePrevDay = ref<number>();
const onlineUsersCount = ref(0);

View file

@ -18,12 +18,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { ref } from 'vue';
import * as Misskey from 'misskey-js';
import * as os from '@/os.js';
import { useInterval } from '@/scripts/use-interval.js';
import MkUserCardMini from '@/components/MkUserCardMini.vue';
import { defaultStore } from '@/store.js';
const newUsers = ref(null);
const newUsers = ref<Misskey.entities.UserDetailed[] | null>(null);
const fetching = ref(true);
const fetch = async () => {

View file

@ -66,6 +66,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { markRaw, onMounted, onBeforeUnmount, nextTick, shallowRef, ref, computed } from 'vue';
import * as Misskey from 'misskey-js';
import XFederation from './overview.federation.vue';
import XInstances from './overview.instances.vue';
import XQueue from './overview.queue.vue';
@ -76,6 +77,7 @@ import XStats from './overview.stats.vue';
import XRetention from './overview.retention.vue';
import XModerators from './overview.moderators.vue';
import XHeatmap from './overview.heatmap.vue';
import type { InstanceForPie } from './overview.pie.vue';
import * as os from '@/os.js';
import { useStream } from '@/stream.js';
import { i18n } from '@/i18n.js';
@ -83,15 +85,15 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkFoldableSection from '@/components/MkFoldableSection.vue';
const rootEl = shallowRef<HTMLElement>();
const serverInfo = ref<any>(null);
const topSubInstancesForPie = ref<any>(null);
const topPubInstancesForPie = ref<any>(null);
const serverInfo = ref<Misskey.entities.ServerInfoResponse | null>(null);
const topSubInstancesForPie = ref<InstanceForPie[] | null>(null);
const topPubInstancesForPie = ref<InstanceForPie[] | null>(null);
const federationPubActive = ref<number | null>(null);
const federationPubActiveDiff = ref<number | null>(null);
const federationSubActive = ref<number | null>(null);
const federationSubActiveDiff = ref<number | null>(null);
const newUsers = ref(null);
const activeInstances = shallowRef(null);
const newUsers = ref<Misskey.entities.UserDetailed[] | null>(null);
const activeInstances = shallowRef<Misskey.entities.FederationInstance | null>(null);
const queueStatsConnection = markRaw(useStream().useChannel('queueStats'));
const now = new Date();
const filesPagination = {
@ -123,22 +125,28 @@ onMounted(async () => {
});
os.apiGet('federation/stats', { limit: 10 }).then(res => {
topSubInstancesForPie.value = res.topSubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followersCount,
onClick: () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})).concat([{ name: '(other)', color: '#80808080', value: res.otherFollowersCount }]);
topPubInstancesForPie.value = res.topPubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followingCount,
onClick: () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})).concat([{ name: '(other)', color: '#80808080', value: res.otherFollowingCount }]);
topSubInstancesForPie.value = [
...res.topSubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followersCount,
onClick: () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})),
{ name: '(other)', color: '#80808080', value: res.otherFollowersCount },
];
topPubInstancesForPie.value = [
...res.topPubInstances.map(x => ({
name: x.host,
color: x.themeColor,
value: x.followingCount,
onClick: () => {
os.pageWindow(`/instance-info/${x.host}`);
},
})),
{ name: '(other)', color: '#80808080', value: res.otherFollowingCount },
];
});
os.api('admin/server-info').then(serverInfoResponse => {

View file

@ -22,6 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { ref, computed } from 'vue';
import * as Misskey from 'misskey-js';
import MkKeyValue from '@/components/MkKeyValue.vue';
import MkButton from '@/components/MkButton.vue';
import MkInfo from '@/components/MkInfo.vue';
@ -31,8 +32,8 @@ import { fetchInstance } from '@/instance.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
const proxyAccount = ref<any>(null);
const proxyAccountId = ref<any>(null);
const proxyAccount = ref<Misskey.entities.UserDetailed | null>(null);
const proxyAccountId = ref<string | null>(null);
async function init() {
const meta = await os.api('admin/meta');

View file

@ -62,7 +62,7 @@ const activeSincePrevTick = ref(0);
const active = ref(0);
const delayed = ref(0);
const waiting = ref(0);
const jobs = ref([]);
const jobs = ref<(string | number)[][]>([]);
const chartProcess = shallowRef<InstanceType<typeof XChart>>();
const chartActive = shallowRef<InstanceType<typeof XChart>>();
const chartDelayed = shallowRef<InstanceType<typeof XChart>>();
@ -104,9 +104,11 @@ const onStatsLog = (statsLog) => {
};
onMounted(() => {
os.api(props.domain === 'inbox' ? 'admin/queue/inbox-delayed' : props.domain === 'deliver' ? 'admin/queue/deliver-delayed' : null, {}).then(result => {
jobs.value = result;
});
if (props.domain === 'inbox' || props.domain === 'deliver') {
os.api(`admin/queue/${props.domain}-delayed`).then(result => {
jobs.value = result;
});
}
connection.on('stats', onStats);
connection.on('statsLog', onStatsLog);

View file

@ -25,13 +25,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { ref, computed } from 'vue';
import * as Misskey from 'misskey-js';
import XHeader from './_header_.vue';
import MkButton from '@/components/MkButton.vue';
import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
const relays = ref<any[]>([]);
const relays = ref<Misskey.entities.AdminRelaysListResponse>([]);
async function addRelay() {
const { canceled, result: inbox } = await os.inputText({
@ -66,7 +67,7 @@ function remove(inbox: string) {
}
function refresh() {
os.api('admin/relays/list').then((relayList: any) => {
os.api('admin/relays/list').then(relayList => {
relays.value = relayList;
});
}

View file

@ -23,6 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { computed, ref } from 'vue';
import * as Misskey from 'misskey-js';
import { v4 as uuid } from 'uuid';
import XHeader from './_header_.vue';
import XEditor from './roles.editor.vue';
@ -31,7 +32,7 @@ import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import { useRouter } from '@/router.js';
import MkButton from '@/components/MkButton.vue';
import { rolesCache } from '@/cache';
import { rolesCache } from '@/cache.js';
const router = useRouter();
@ -39,8 +40,8 @@ const props = defineProps<{
id?: string;
}>();
const role = ref(null);
const data = ref(null);
const role = ref<Misskey.entities.Role | null>(null);
const data = ref<any>(null);
if (props.id) {
role.value = await os.api('admin/roles/show', {

View file

@ -73,7 +73,7 @@ import { useRouter } from '@/router.js';
import MkButton from '@/components/MkButton.vue';
import MkUserCardMini from '@/components/MkUserCardMini.vue';
import MkInfo from '@/components/MkInfo.vue';
import MkPagination from '@/components/MkPagination.vue';
import MkPagination, { Paging } from '@/components/MkPagination.vue';
import { infoImageUrl } from '@/instance.js';
const router = useRouter();
@ -88,7 +88,7 @@ const usersPagination = {
params: computed(() => ({
roleId: props.id,
})),
};
} satisfies Paging;
const expandedItems = ref([]);

View file

@ -262,7 +262,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import { instance } from '@/instance.js';
import { useRouter } from '@/router.js';
import MkFoldableSection from '@/components/MkFoldableSection.vue';
import { ROLE_POLICIES } from '@/const';
import { ROLE_POLICIES } from '@/const.js';
const router = useRouter();
const baseRoleQ = ref('');

View file

@ -173,8 +173,8 @@ const pinnedUsers = ref<string>('');
const cacheRemoteFiles = ref<boolean>(false);
const cacheRemoteSensitiveFiles = ref<boolean>(false);
const enableServiceWorker = ref<boolean>(false);
const swPublicKey = ref<any>(null);
const swPrivateKey = ref<any>(null);
const swPublicKey = ref<string | null>(null);
const swPrivateKey = ref<string | null>(null);
const enableFanoutTimeline = ref<boolean>(false);
const enableFanoutTimelineDbFallback = ref<boolean>(false);
const perLocalUserUserTimelineCacheMax = ref<number>(0);

View file

@ -61,7 +61,7 @@ import { computed, shallowRef, ref } from 'vue';
import XHeader from './_header_.vue';
import MkInput from '@/components/MkInput.vue';
import MkSelect from '@/components/MkSelect.vue';
import MkPagination from '@/components/MkPagination.vue';
import MkPagination, { Paging } from '@/components/MkPagination.vue';
import * as os from '@/os.js';
import { lookupUser } from '@/scripts/lookup-user.js';
import { i18n } from '@/i18n.js';
@ -87,7 +87,7 @@ const pagination = {
hostname: searchHost.value,
})),
offsetMode: true,
};
} satisfies Paging;
function searchUser() {
os.selectUser().then(user => {