diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2022-06-29 21:22:15 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2022-06-29 21:22:15 +0900 |
| commit | c9b3ab80ca9f1bfa6815fa73c5d885f1c1caa0b5 (patch) | |
| tree | 57aee4b0dcbd0f7164c402cd79efdec8a6a969cd /packages/client/src | |
| parent | chore(client): fix type def (diff) | |
| download | sharkey-c9b3ab80ca9f1bfa6815fa73c5d885f1c1caa0b5.tar.gz sharkey-c9b3ab80ca9f1bfa6815fa73c5d885f1c1caa0b5.tar.bz2 sharkey-c9b3ab80ca9f1bfa6815fa73c5d885f1c1caa0b5.zip | |
feat(client): add tag cloud component
Diffstat (limited to 'packages/client/src')
| -rw-r--r-- | packages/client/src/components/tag-cloud.vue | 80 | ||||
| -rw-r--r-- | packages/client/src/pages/admin/overview.vue | 33 |
2 files changed, 112 insertions, 1 deletions
diff --git a/packages/client/src/components/tag-cloud.vue b/packages/client/src/components/tag-cloud.vue new file mode 100644 index 0000000000..43ab49357b --- /dev/null +++ b/packages/client/src/components/tag-cloud.vue @@ -0,0 +1,80 @@ +<template> +<div class="root"> + <canvas :id="idForCanvas" ref="canvasEl" class="canvas" width="300" height="300"></canvas> + <div :id="idForTags" ref="tagsEl" class="tags"> + <ul> + <slot></slot> + </ul> + </div> +</div> +</template> + +<script lang="ts" setup> +import { onMounted, ref, watch, PropType, onBeforeUnmount } from 'vue'; +import tinycolor from 'tinycolor2'; + +const props = defineProps<{}>(); + +const loaded = !!window.TagCanvas; +const SAFE_FOR_HTML_ID = 'abcdefghijklmnopqrstuvwxyz'; +const computedStyle = getComputedStyle(document.documentElement); +const idForCanvas = Array.from(Array(16)).map(() => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join(''); +const idForTags = Array.from(Array(16)).map(() => SAFE_FOR_HTML_ID[Math.floor(Math.random() * SAFE_FOR_HTML_ID.length)]).join(''); +let available = $ref(false); +let canvasEl = $ref<HTMLCanvasElement | null>(null); +let tagsEl = $ref<HTMLElement | null>(null); + +watch($$(available), () => { + window.TagCanvas.Start(idForCanvas, idForTags, { + textColour: '#ffffff', + outlineColour: tinycolor(computedStyle.getPropertyValue('--accent')).toHexString(), + outlineRadius: 10, + initial: [-0.030, -0.010], + frontSelect: true, + imageRadius: 8, + //dragControl: true, + dragThreshold: 3, + wheelZoom: false, + reverse: true, + depth: 0.5, + maxSpeed: 0.2, + minSpeed: 0.003, + stretchX: 0.8, + stretchY: 0.8, + }); +}); + +onMounted(() => { + if (loaded) { + available = true; + } else { + document.head.appendChild(Object.assign(document.createElement('script'), { + async: true, + src: '/client-assets/tagcanvas.min.js', + })).addEventListener('load', () => available = true); + } +}); + +onBeforeUnmount(() => { + window.TagCanvas.Delete(idForCanvas); +}); +</script> + +<style lang="scss" scoped> +.root { + position: relative; + overflow: clip; + display: grid; + place-items: center; + + > .canvas { + display: block; + } + + > .tags { + position: absolute; + top: 999px; + left: 999px; + } +} +</style> diff --git a/packages/client/src/pages/admin/overview.vue b/packages/client/src/pages/admin/overview.vue index 190f756f78..6ccee8aea2 100644 --- a/packages/client/src/pages/admin/overview.vue +++ b/packages/client/src/pages/admin/overview.vue @@ -108,6 +108,17 @@ </div> </div> </div> + <div class="container tagCloud"> + <div class="body"> + <MkTagCloud v-if="activeInstances"> + <li v-for="instance in activeInstances"> + <a @click.prevent="onInstanceClick(instance)"> + <img style="width: 32px;" :src="instance.iconUrl"> + </a> + </li> + </MkTagCloud> + </div> + </div> <div v-if="fedStats" class="container federationPies"> <div class="body"> <div class="chart deliver"> @@ -154,8 +165,8 @@ import XFederation from './overview.federation.vue'; import XQueueChart from './overview.queue-chart.vue'; import XUser from './overview.user.vue'; import XPie from './overview.pie.vue'; -import MkInstanceStats from '@/components/instance-stats.vue'; import MkNumberDiff from '@/components/number-diff.vue'; +import MkTagCloud from '@/components/tag-cloud.vue'; import { version, url } from '@/config'; import number from '@/filters/number'; import * as os from '@/os'; @@ -197,6 +208,7 @@ let federationPubActiveDiff = $ref<number | null>(null); let federationSubActive = $ref<number | null>(null); let federationSubActiveDiff = $ref<number | null>(null); let newUsers = $ref(null); +let activeInstances = $shallowRef(null); const queueStatsConnection = markRaw(stream.useChannel('queueStats')); const now = new Date(); let chartInstance: Chart = null; @@ -363,6 +375,10 @@ async function renderChart() { }); } +function onInstanceClick(i) { + os.pageWindow(`/instance-info/${i.host}`); +} + onMounted(async () => { /* const magicGrid = new MagicGrid({ @@ -410,6 +426,13 @@ onMounted(async () => { newUsers = res; }); + os.api('federation/instances', { + sort: '+lastCommunicatedAt', + limit: 25, + }).then(res => { + activeInstances = res; + }); + nextTick(() => { queueStatsConnection.send('requestLog', { id: Math.random().toString().substr(2, 8), @@ -577,6 +600,14 @@ definePageMetadata({ } } } + + &.tagCloud { + > .body { + background: var(--panel); + border-radius: var(--radius); + overflow: clip; + } + } } } |