sounds, better files
This commit is contained in:
@@ -1,26 +1,46 @@
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div style="background-color: white; display: flex; flex-direction: row;gap: 0.5rem;padding: 0.5rem">
|
||||
<div style="max-width: 32px; height: 32px; overflow: hidden;">
|
||||
<div style="background-color: white; display: flex; flex-direction: row;gap: 0.5rem;padding: 0.5rem;margin-bottom:0.5rem; color: black">
|
||||
<FilesAside />
|
||||
<!-- <div style="max-width: 32px; height: 32px; overflow: hidden;">
|
||||
<google-cast-launcher style="--disconnected-color: black;" ></google-cast-launcher>
|
||||
</div>
|
||||
<button @click="openMapWindow">Open map window</button>
|
||||
<button @click="onStreamImage">Stream image</button>
|
||||
<button @click="onStreamImage">Stream image</button> -->
|
||||
</div>
|
||||
<fieldset>
|
||||
<legend>Image settings</legend>
|
||||
<label>Width</label>
|
||||
<input type="number" v-model="imageWidth" />
|
||||
<label>Screen Diameter</label>
|
||||
<input type="number" v-model="screenDiameterInch" />
|
||||
<label>Flip <input type="checkbox" v-model="flipped"></label>
|
||||
<label>Position (X/Y)</label>
|
||||
<input type="range" min="0" max="100" v-model="positionX" />
|
||||
<input type="range" min="0" max="100" v-model="positionY" />
|
||||
<button @click="positionX = 50;positionY = 50">center</button>
|
||||
</fieldset>
|
||||
<FileManager @openFile="openFile" />
|
||||
<FilesAside />
|
||||
<ScreenManager />
|
||||
<Tabs
|
||||
:tabs="[
|
||||
{label: 'Sounds', key: 'sounds'},
|
||||
{label: 'Settings', key: 'settings'},
|
||||
{label: 'Devices', key: 'devices'},
|
||||
]"
|
||||
>
|
||||
<template v-slot:settings>
|
||||
<fieldset>
|
||||
<legend>Image settings</legend>
|
||||
<label>Width</label>
|
||||
<input type="number" v-model="imageWidth" />
|
||||
<label>Screen Diameter</label>
|
||||
<input type="number" v-model="screenDiameterInch" />
|
||||
<label>Flip <input type="checkbox" v-model="flipped"></label>
|
||||
<label>Position (X/Y)</label>
|
||||
<input type="range" min="0" max="100" v-model="positionX" />
|
||||
<input type="range" min="0" max="100" v-model="positionY" />
|
||||
<button @click="positionX = 50;positionY = 50">center</button>
|
||||
</fieldset>
|
||||
</template>
|
||||
<template v-slot:devices>
|
||||
<RemoteDevices />
|
||||
</template>
|
||||
<template v-slot:sounds>
|
||||
<div style="padding: 1rem">
|
||||
<Soundboard />
|
||||
</div>
|
||||
</template>
|
||||
</Tabs>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@@ -28,6 +48,12 @@ import FileManager from '../../components/FileManager/FileManager.vue';
|
||||
import type { FileWithMeta } from '../../model/FileManager';
|
||||
import {ref, inject, watch} from 'vue';
|
||||
import {SenderSymbol} from '../../model/injectionSymbols';
|
||||
import Tabs from '../../components/Tabs.vue';
|
||||
import {VirtualFile} from '../../model/FileSystem/types';
|
||||
import ScreenManager from '../../components/ScreenManager/ScreenManager.vue';
|
||||
import RemoteDevices from '../../components/RemoteDevices/RemoteDevices.vue';
|
||||
import Soundboard from '../../components/Audio/Soundboard.vue';
|
||||
import FilesAside from '../../components/Files/FilesAside.vue';
|
||||
|
||||
const openedFile = ref<FileWithMeta>()
|
||||
const sender = inject(SenderSymbol);
|
||||
@@ -62,13 +88,14 @@ watch(() => [positionX.value, positionY.value, flipped.value], () => {
|
||||
})
|
||||
});
|
||||
|
||||
function openFile(file: FileWithMeta) {
|
||||
sender?.sendMessage({
|
||||
type: 'showFile',
|
||||
file,
|
||||
})
|
||||
imageWidth.value = file.width ?? 20;
|
||||
openedFile.value = file;
|
||||
function openFile(file: VirtualFile) {
|
||||
console.log('openFile', file);
|
||||
// sender?.sendMessage({
|
||||
// type: 'showFile',
|
||||
// file,
|
||||
// })
|
||||
// imageWidth.value = file.width ?? 20;
|
||||
// openedFile.value = file;
|
||||
}
|
||||
|
||||
function openMapWindow() {
|
||||
|
||||
50
src/modules/summon/Debug.vue
Normal file
50
src/modules/summon/Debug.vue
Normal file
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<div class="debug-window">
|
||||
<pre v-for="json in lastMessages" :class="{
|
||||
'debug-window__json': json.source === 'json',
|
||||
'debug-window__webrtc': json.source === 'webrtc',
|
||||
}">{{ json.message }}</pre>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {computed, ref, inject} from 'vue';
|
||||
import {Message} from '../../model/Remote/Channels/type';
|
||||
import { JsonChannelSymbol, WebRtcChannelSymbol } from '../../model/injectionSymbols';
|
||||
|
||||
const jsonMessages = ref<{source: 'json' | 'webrtc', message: Message}[]>([]);
|
||||
const lastMessages = computed(() => [...jsonMessages.value].reverse().slice(0, 10));
|
||||
console.log(jsonMessages, lastMessages);
|
||||
const channel = inject(JsonChannelSymbol)!;
|
||||
const webRTC = inject(WebRtcChannelSymbol)!;
|
||||
channel.on((message) => {
|
||||
jsonMessages.value.push({source: 'json', message});
|
||||
jsonMessages.value = jsonMessages.value.slice(-100);
|
||||
});
|
||||
|
||||
webRTC.on((message) => {
|
||||
jsonMessages.value.push({source: 'webrtc', message});
|
||||
jsonMessages.value = jsonMessages.value.slice(-100);
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.debug-window {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 400px;
|
||||
height: 800px;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
border: 2px solid white;
|
||||
z-index: 10000;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.debug-window__json {
|
||||
color: cadetblue;
|
||||
}
|
||||
|
||||
.debug-window__webrtc {
|
||||
color: greenyellow;
|
||||
}
|
||||
|
||||
</style>
|
||||
68
src/modules/summon/SummonApp.vue
Normal file
68
src/modules/summon/SummonApp.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<Debug />
|
||||
<canvas ref="canvas" style="max-width: 100%" />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {inject, ref} from 'vue';
|
||||
import Debug from './Debug.vue';
|
||||
import {WebRtcChannelSymbol} from '../../model/injectionSymbols';
|
||||
import {VirtualFile} from '../../model/FileSystem/types';
|
||||
|
||||
const webRtc = inject(WebRtcChannelSymbol)!;
|
||||
const canvas = ref<HTMLCanvasElement>();
|
||||
|
||||
const cachedFiles = new Map<string, Blob>();
|
||||
const fileToKey = (file: VirtualFile) => `${file.source}:${file.path.join('/')}`;
|
||||
|
||||
function sendScreenInfo() {
|
||||
webRtc.send({
|
||||
type: 'resolution',
|
||||
width: window.innerWidth * window.devicePixelRatio,
|
||||
height: window.innerHeight * window.devicePixelRatio,
|
||||
});
|
||||
}
|
||||
|
||||
function sendAudioInfo() {
|
||||
const ac = new AudioContext();
|
||||
webRtc.send({
|
||||
type: 'audioInfo',
|
||||
channels: ac.destination.channelCount,
|
||||
channelInterpretation: ac.destination.channelInterpretation,
|
||||
})
|
||||
}
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
sendScreenInfo();
|
||||
});
|
||||
|
||||
|
||||
webRtc.on((message) => {
|
||||
console.log('webRtc message', message);
|
||||
if (message.type === 'connected') {
|
||||
sendScreenInfo();
|
||||
sendAudioInfo();
|
||||
} else if (message.type === 'fileTransfered') {
|
||||
debugger;
|
||||
const key = fileToKey(message.meta);
|
||||
cachedFiles.set(key, message.blob);
|
||||
} else if (message.type === 'showFile') {
|
||||
debugger;
|
||||
const key = fileToKey(message.file);
|
||||
const blob = cachedFiles.get(key);
|
||||
if (blob) {
|
||||
const url = URL.createObjectURL(blob);
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
const ctx = canvas.value!.getContext('2d')!;
|
||||
canvas.value!.width = img.width;
|
||||
canvas.value!.height = img.height;
|
||||
ctx.drawImage(img, 0, 0);
|
||||
}
|
||||
img.src = url;
|
||||
}
|
||||
} else if (message.type === 'transform') {
|
||||
// canvas.value.style = `max-width: 100%;transform: scale(${message.scale}) translate(${message.x}%, ${message.y}%);transition: transform 100ms;`;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user