ae5d052274
to keep things manageable i merged a lot of one off values into just a handful of common sizes, so some parts of the ui will look different than upstream even with the "Misskey" rounding mode
189 lines
4.5 KiB
Vue
189 lines
4.5 KiB
Vue
<!--
|
|
SPDX-FileCopyrightText: syuilo and other misskey contributors
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
-->
|
|
|
|
<template>
|
|
<div>
|
|
<MkLoading v-if="fetching"/>
|
|
<div v-show="!fetching" :class="$style.root">
|
|
<div v-if="topSubInstancesForPie && topPubInstancesForPie" class="pies">
|
|
<div class="pie deliver _panel">
|
|
<div class="title">Sub</div>
|
|
<XPie :data="topSubInstancesForPie" class="chart"/>
|
|
<div class="subTitle">Top 10</div>
|
|
</div>
|
|
<div class="pie inbox _panel">
|
|
<div class="title">Pub</div>
|
|
<XPie :data="topPubInstancesForPie" class="chart"/>
|
|
<div class="subTitle">Top 10</div>
|
|
</div>
|
|
</div>
|
|
<div v-if="!fetching" class="items">
|
|
<div class="item _panel sub">
|
|
<div class="icon"><i class="ph-globe-hemisphere-west ph-bold ph-lg-download"></i></div>
|
|
<div class="body">
|
|
<div class="value">
|
|
{{ number(federationSubActive) }}
|
|
<MkNumberDiff v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="federationSubActiveDiff"></MkNumberDiff>
|
|
</div>
|
|
<div class="label">Sub</div>
|
|
</div>
|
|
</div>
|
|
<div class="item _panel pub">
|
|
<div class="icon"><i class="ph-globe-hemisphere-west ph-bold ph-lg-upload"></i></div>
|
|
<div class="body">
|
|
<div class="value">
|
|
{{ number(federationPubActive) }}
|
|
<MkNumberDiff v-tooltip="i18n.ts.dayOverDayChanges" class="diff" :value="federationPubActiveDiff"></MkNumberDiff>
|
|
</div>
|
|
<div class="label">Pub</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { onMounted } from 'vue';
|
|
import XPie 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';
|
|
|
|
let topSubInstancesForPie: any = $ref(null);
|
|
let topPubInstancesForPie: any = $ref(null);
|
|
let federationPubActive = $ref<number | null>(null);
|
|
let federationPubActiveDiff = $ref<number | null>(null);
|
|
let federationSubActive = $ref<number | null>(null);
|
|
let federationSubActiveDiff = $ref<number | null>(null);
|
|
let fetching = $ref(true);
|
|
|
|
const { handler: externalTooltipHandler } = useChartTooltip();
|
|
|
|
onMounted(async () => {
|
|
const chart = await os.apiGet('charts/federation', { limit: 2, span: 'day' });
|
|
federationPubActive = chart.pubActive[0];
|
|
federationPubActiveDiff = chart.pubActive[0] - chart.pubActive[1];
|
|
federationSubActive = chart.subActive[0];
|
|
federationSubActiveDiff = chart.subActive[0] - chart.subActive[1];
|
|
|
|
os.apiGet('federation/stats', { limit: 10 }).then(res => {
|
|
topSubInstancesForPie = 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 = 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 }]);
|
|
});
|
|
|
|
fetching = false;
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" module>
|
|
.root {
|
|
|
|
&:global {
|
|
> .pies {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
|
|
grid-gap: 12px;
|
|
margin-bottom: 12px;
|
|
|
|
> .pie {
|
|
position: relative;
|
|
padding: 12px;
|
|
|
|
> .title {
|
|
position: absolute;
|
|
top: 20px;
|
|
left: 20px;
|
|
font-size: 90%;
|
|
}
|
|
|
|
> .chart {
|
|
max-height: 150px;
|
|
}
|
|
|
|
> .subTitle {
|
|
position: absolute;
|
|
bottom: 20px;
|
|
right: 20px;
|
|
font-size: 85%;
|
|
}
|
|
}
|
|
}
|
|
|
|
> .items {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
|
|
grid-gap: 12px;
|
|
|
|
> .item {
|
|
display: flex;
|
|
box-sizing: border-box;
|
|
padding: 12px;
|
|
|
|
> .icon {
|
|
display: grid;
|
|
place-items: center;
|
|
height: 100%;
|
|
aspect-ratio: 1;
|
|
margin-right: 12px;
|
|
background: var(--accentedBg);
|
|
color: var(--accent);
|
|
border-radius: var(--radius);
|
|
}
|
|
|
|
&.sub {
|
|
> .icon {
|
|
background: #d5ba0026;
|
|
color: #dfc300;
|
|
}
|
|
}
|
|
|
|
&.pub {
|
|
> .icon {
|
|
background: #00cf2326;
|
|
color: #00cd5b;
|
|
}
|
|
}
|
|
|
|
> .body {
|
|
padding: 2px 0;
|
|
|
|
> .value {
|
|
font-size: 1.2em;
|
|
font-weight: bold;
|
|
|
|
> .diff {
|
|
font-size: 0.65em;
|
|
font-weight: normal;
|
|
}
|
|
}
|
|
|
|
> .label {
|
|
font-size: 0.8em;
|
|
opacity: 0.5;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|
|
|