mirror of
https://github.com/Pandipipas/scoreko-dev.git
synced 2026-06-06 03:32:06 +00:00
Add graphics cards with copy and OBS drag (#24)
This commit is contained in:
@@ -1,14 +1,125 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { useHead } from '@unhead/vue';
|
||||
import bundlePackage from '../../../../package.json';
|
||||
|
||||
type GraphicConfig = {
|
||||
file: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
};
|
||||
|
||||
useHead({ title: 'Graphics' });
|
||||
|
||||
const graphics = computed<GraphicConfig[]>(
|
||||
() => bundlePackage.nodecg?.graphics ?? [],
|
||||
);
|
||||
|
||||
const baseUrl = computed(() => {
|
||||
const bundleName = bundlePackage.name ?? 'bundle';
|
||||
return `${window.location.origin}/bundles/${bundleName}/graphics/`;
|
||||
});
|
||||
|
||||
const buildGraphicUrl = (graphic: GraphicConfig) =>
|
||||
`${baseUrl.value}${graphic.file}`;
|
||||
|
||||
const buildGraphicName = (graphic: GraphicConfig) => {
|
||||
const cleaned = graphic.file.replace(/\/?main\.html$/i, '');
|
||||
const parts = cleaned.split('/').filter(Boolean);
|
||||
return parts.at(-1) ?? graphic.file;
|
||||
};
|
||||
|
||||
const copyUrl = async (graphic: GraphicConfig) => {
|
||||
const url = buildGraphicUrl(graphic);
|
||||
if (navigator.clipboard?.writeText) {
|
||||
await navigator.clipboard.writeText(url);
|
||||
return;
|
||||
}
|
||||
|
||||
const input = document.createElement('input');
|
||||
input.value = url;
|
||||
document.body.appendChild(input);
|
||||
input.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(input);
|
||||
};
|
||||
|
||||
const onDragStart = (event: DragEvent, graphic: GraphicConfig) => {
|
||||
const url = buildGraphicUrl(graphic);
|
||||
const name = buildGraphicName(graphic);
|
||||
const payload = JSON.stringify({
|
||||
name,
|
||||
url,
|
||||
width: graphic.width ?? 1920,
|
||||
height: graphic.height ?? 1080,
|
||||
});
|
||||
|
||||
event.dataTransfer?.setData('text/uri-list', url);
|
||||
event.dataTransfer?.setData('text/plain', url);
|
||||
event.dataTransfer?.setData('application/x-obs-browser-source', payload);
|
||||
event.dataTransfer?.setData('application/json', payload);
|
||||
event.dataTransfer?.setDragImage?.(new Image(), 0, 0);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPage class="q-pa-lg">
|
||||
<div class="text-h4 q-mb-md">Graphics</div>
|
||||
<div class="text-body1">
|
||||
<div class="text-body1 q-mb-lg">
|
||||
Controles y estado de gráficos del bundle.
|
||||
</div>
|
||||
|
||||
<div v-if="graphics.length === 0" class="text-body2 text-grey-5">
|
||||
No hay gráficos configurados en el bundle.
|
||||
</div>
|
||||
|
||||
<div class="row q-col-gutter-md">
|
||||
<div
|
||||
v-for="graphic in graphics"
|
||||
:key="graphic.file"
|
||||
class="col-12 col-md-6"
|
||||
>
|
||||
<QCard bordered class="bg-grey-10">
|
||||
<QCardSection class="row items-center justify-between">
|
||||
<div>
|
||||
<div class="text-h6">
|
||||
{{ buildGraphicName(graphic) }}
|
||||
</div>
|
||||
<div class="text-caption text-grey-5">
|
||||
{{ graphic.file }}
|
||||
</div>
|
||||
</div>
|
||||
<QBadge color="primary" outline>
|
||||
{{ graphic.width ?? 1920 }}x{{ graphic.height ?? 1080 }}
|
||||
</QBadge>
|
||||
</QCardSection>
|
||||
|
||||
<QSeparator />
|
||||
|
||||
<QCardSection>
|
||||
<div class="text-caption text-grey-5 q-mb-xs">URL</div>
|
||||
<div class="text-body2 text-mono q-mb-md">
|
||||
{{ buildGraphicUrl(graphic) }}
|
||||
</div>
|
||||
|
||||
<div class="row items-center q-gutter-sm">
|
||||
<QBtn
|
||||
color="primary"
|
||||
icon="content_copy"
|
||||
label="Copiar URL"
|
||||
@click="copyUrl(graphic)"
|
||||
/>
|
||||
<QBtn
|
||||
color="secondary"
|
||||
icon="open_with"
|
||||
label="Drag into OBS"
|
||||
draggable="true"
|
||||
@dragstart="onDragStart($event, graphic)"
|
||||
/>
|
||||
</div>
|
||||
</QCardSection>
|
||||
</QCard>
|
||||
</div>
|
||||
</div>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user