Frontend: Removed pointless tag cloud eye candy
This commit is contained in:
parent
f06c74c85c
commit
1366adcebf
File diff suppressed because it is too large
Load Diff
|
@ -1,117 +0,0 @@
|
||||||
<template>
|
|
||||||
<div ref="rootEl" class="meijqfqm">
|
|
||||||
<canvas
|
|
||||||
:id="idForCanvas"
|
|
||||||
ref="canvasEl"
|
|
||||||
class="canvas"
|
|
||||||
:width="width"
|
|
||||||
height="300"
|
|
||||||
@contextmenu.prevent="() => {}"
|
|
||||||
></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 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 rootEl = $ref<HTMLElement | null>(null);
|
|
||||||
let canvasEl = $ref<HTMLCanvasElement | null>(null);
|
|
||||||
let tagsEl = $ref<HTMLElement | null>(null);
|
|
||||||
let width = $ref(300);
|
|
||||||
|
|
||||||
watch($$(available), () => {
|
|
||||||
try {
|
|
||||||
window.TagCanvas.Start(idForCanvas, idForTags, {
|
|
||||||
textColour: "#ffffff",
|
|
||||||
outlineColour: tinycolor(
|
|
||||||
computedStyle.getPropertyValue("--accent")
|
|
||||||
).toHexString(),
|
|
||||||
outlineRadius: 10,
|
|
||||||
initial: [-0.03, -0.01],
|
|
||||||
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,
|
|
||||||
});
|
|
||||||
} catch (err) {}
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
width = rootEl.offsetWidth;
|
|
||||||
|
|
||||||
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(() => {
|
|
||||||
if (window.TagCanvas) window.TagCanvas.Delete(idForCanvas);
|
|
||||||
});
|
|
||||||
|
|
||||||
defineExpose({
|
|
||||||
update: () => {
|
|
||||||
window.TagCanvas.Update(idForCanvas);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.meijqfqm {
|
|
||||||
position: relative;
|
|
||||||
overflow: clip;
|
|
||||||
display: grid;
|
|
||||||
place-items: center;
|
|
||||||
|
|
||||||
> .canvas {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .tags {
|
|
||||||
position: absolute;
|
|
||||||
top: 999px;
|
|
||||||
left: 999px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -60,13 +60,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import {
|
import { markRaw, nextTick, onBeforeUnmount, onMounted } from "vue";
|
||||||
markRaw,
|
|
||||||
version as vueVersion,
|
|
||||||
onMounted,
|
|
||||||
onBeforeUnmount,
|
|
||||||
nextTick,
|
|
||||||
} from "vue";
|
|
||||||
import XFederation from "./overview.federation.vue";
|
import XFederation from "./overview.federation.vue";
|
||||||
import XInstances from "./overview.instances.vue";
|
import XInstances from "./overview.instances.vue";
|
||||||
import XQueue from "./overview.queue.vue";
|
import XQueue from "./overview.queue.vue";
|
||||||
|
@ -77,14 +71,10 @@ import XStats from "./overview.stats.vue";
|
||||||
import XModerators from "./overview.moderators.vue";
|
import XModerators from "./overview.moderators.vue";
|
||||||
import XHeatmap from "./overview.heatmap.vue";
|
import XHeatmap from "./overview.heatmap.vue";
|
||||||
// import XMetrics from "./overview.metrics.vue";
|
// import XMetrics from "./overview.metrics.vue";
|
||||||
import MkTagCloud from "@/components/MkTagCloud.vue";
|
|
||||||
import { version, url } from "@/config";
|
|
||||||
import * as os from "@/os";
|
import * as os from "@/os";
|
||||||
import { stream } from "@/stream";
|
import { stream } from "@/stream";
|
||||||
import { i18n } from "@/i18n";
|
import { i18n } from "@/i18n";
|
||||||
import { definePageMetadata } from "@/scripts/page-metadata";
|
import { definePageMetadata } from "@/scripts/page-metadata";
|
||||||
import { defaultStore } from "@/store";
|
|
||||||
import MkFileListForAdmin from "@/components/MkFileListForAdmin.vue";
|
|
||||||
import MkFolder from "@/components/MkFolder.vue";
|
import MkFolder from "@/components/MkFolder.vue";
|
||||||
|
|
||||||
const rootEl = $shallowRef<HTMLElement>();
|
const rootEl = $shallowRef<HTMLElement>();
|
||||||
|
|
|
@ -73,10 +73,6 @@ export default function (app: App) {
|
||||||
"MkwJobQueue",
|
"MkwJobQueue",
|
||||||
defineAsyncComponent(() => import("./job-queue.vue"))
|
defineAsyncComponent(() => import("./job-queue.vue"))
|
||||||
);
|
);
|
||||||
app.component(
|
|
||||||
"MkwInstanceCloud",
|
|
||||||
defineAsyncComponent(() => import("./instance-cloud.vue"))
|
|
||||||
);
|
|
||||||
app.component(
|
app.component(
|
||||||
"MkwButton",
|
"MkwButton",
|
||||||
defineAsyncComponent(() => import("./button.vue"))
|
defineAsyncComponent(() => import("./button.vue"))
|
||||||
|
@ -110,7 +106,6 @@ export const widgets = [
|
||||||
"digitalClock",
|
"digitalClock",
|
||||||
"unixClock",
|
"unixClock",
|
||||||
"federation",
|
"federation",
|
||||||
"instanceCloud",
|
|
||||||
"postForm",
|
"postForm",
|
||||||
"slideshow",
|
"slideshow",
|
||||||
"serverMetric",
|
"serverMetric",
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
<template>
|
|
||||||
<MkContainer
|
|
||||||
:naked="widgetProps.transparent"
|
|
||||||
:show-header="false"
|
|
||||||
class="mkw-instance-cloud"
|
|
||||||
>
|
|
||||||
<div class="">
|
|
||||||
<MkTagCloud v-if="activeInstances">
|
|
||||||
<li v-for="instance in activeInstances" :key="instance.id">
|
|
||||||
<a @click.prevent="onInstanceClick(instance)">
|
|
||||||
<img
|
|
||||||
style="width: 32px"
|
|
||||||
:src="getInstanceIcon(instance)"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</MkTagCloud>
|
|
||||||
</div>
|
|
||||||
</MkContainer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import {} from "vue";
|
|
||||||
import {
|
|
||||||
useWidgetPropsManager,
|
|
||||||
WidgetComponentEmits,
|
|
||||||
WidgetComponentProps,
|
|
||||||
} from "./widget";
|
|
||||||
import type { Widget, WidgetComponentExpose } from "./widget";
|
|
||||||
import type { GetFormResultType } from "@/scripts/form";
|
|
||||||
import MkContainer from "@/components/MkContainer.vue";
|
|
||||||
import MkTagCloud from "@/components/MkTagCloud.vue";
|
|
||||||
import * as os from "@/os";
|
|
||||||
import { useInterval } from "@/scripts/use-interval";
|
|
||||||
import { getProxiedImageUrlNullable } from "@/scripts/media-proxy";
|
|
||||||
|
|
||||||
const name = "instanceCloud";
|
|
||||||
|
|
||||||
const widgetPropsDef = {
|
|
||||||
transparent: {
|
|
||||||
type: "boolean" as const,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
|
|
||||||
|
|
||||||
// 現時点ではvueの制限によりimportしたtypeをジェネリックに渡せない
|
|
||||||
//const props = defineProps<WidgetComponentProps<WidgetProps>>();
|
|
||||||
//const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
|
|
||||||
const props = defineProps<{ widget?: Widget<WidgetProps> }>();
|
|
||||||
const emit = defineEmits<{ (ev: "updateProps", props: WidgetProps) }>();
|
|
||||||
|
|
||||||
const { widgetProps, configure } = useWidgetPropsManager(
|
|
||||||
name,
|
|
||||||
widgetPropsDef,
|
|
||||||
props,
|
|
||||||
emit
|
|
||||||
);
|
|
||||||
|
|
||||||
let cloud = $ref<InstanceType<typeof MkTagCloud> | null>();
|
|
||||||
let activeInstances = $shallowRef(null);
|
|
||||||
|
|
||||||
function onInstanceClick(i) {
|
|
||||||
os.pageWindow(`/instance-info/${i.host}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
useInterval(
|
|
||||||
() => {
|
|
||||||
os.api("federation/instances", {
|
|
||||||
sort: "+lastCommunicatedAt",
|
|
||||||
limit: 25,
|
|
||||||
}).then((res) => {
|
|
||||||
activeInstances = res;
|
|
||||||
if (cloud) cloud.update();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
1000 * 60 * 3,
|
|
||||||
{
|
|
||||||
immediate: true,
|
|
||||||
afterMounted: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
function getInstanceIcon(instance): string {
|
|
||||||
return (
|
|
||||||
getProxiedImageUrlNullable(instance.iconUrl, "preview") ??
|
|
||||||
getProxiedImageUrlNullable(instance.faviconUrl, "preview") ??
|
|
||||||
"/client-assets/dummy.png"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
defineExpose<WidgetComponentExpose>({
|
|
||||||
name,
|
|
||||||
configure,
|
|
||||||
id: props.widget ? props.widget.id : null,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
Loading…
Reference in New Issue