ffplayout/pages/message.vue
2023-01-11 10:54:25 +01:00

500 lines
18 KiB
Vue

<template>
<div>
<Menu />
<div class="container mt-5">
<div class="preset-div">
<div class="row">
<div class="col">
<select class="form-select" v-model="selected" @change="onChange($event)">
<option v-for="item in presets">{{ item.name }}</option>
</select>
</div>
<div class="col-2">
<div class="btn-group" role="group">
<button class="btn btn-primary" title="Save Preset" @click="savePreset()">
<i class="bi-cloud-upload" />
</button>
<button
class="btn btn-primary"
title="New Preset"
data-bs-toggle="modal"
data-bs-target="#createModal"
>
<i class="bi-file-plus" />
</button>
<button
class="btn btn-primary"
title="Delete Preset"
data-bs-toggle="modal"
data-bs-target="#deleteModal"
>
<i class="bi-file-minus" />
</button>
</div>
</div>
</div>
</div>
<form @submit.prevent="submitMessage">
<textarea class="form-control message" v-model="form.text" rows="7" placeholder="Message" />
<div class="row mt-3">
<div class="col">
<input
class="form-control mt-1"
v-model="form.x"
type="text"
title="X Axis"
placeholder="X"
required
/>
<input
class="form-control mt-2"
v-model="form.y"
type="text"
title="Y Axis"
placeholder="Y"
required
/>
<div class="row mt-2">
<div class="col">
<label for="input-size">Size</label>
<input
id="input-size"
class="form-control mt-2"
v-model="form.fontSize"
type="number"
required
/>
</div>
<div class="col">
<label for="input-spacing">Spacing</label>
<input
id="input-spacing"
class="form-control mt-2"
v-model="form.fontSpacing"
type="number"
required
/>
</div>
</div>
<div class="row mt-2">
<div class="col">
<label for="input-color">Font Color</label>
<input
id="input-color"
class="form-control mt-2"
v-model="form.fontColor"
type="color"
required
/>
</div>
<div class="col">
<label for="input-alpha">Font Alpha</label>
<input
id="input-alpha"
class="form-control mt-2"
v-model="form.fontAlpha"
type="number"
min="0"
max="1"
step="0.01"
/>
</div>
</div>
</div>
<div class="col">
<div class="form-check">
<input id="input-box" type="checkbox" class="form-check-input" v-model="form.showBox" />
<label for="input-box" class="form-check-label">Show Box</label>
</div>
<div class="row">
<div class="col">
<label for="input-box-color">Box Color</label>
<input
id="input-box-color"
class="form-control mt-2"
v-model="form.boxColor"
type="color"
required
/>
</div>
<div class="col">
<label for="input-box-alpha" class="form-check-label">Box Alpha</label>
<input
id="input-box-alpha"
class="form-control mt-2"
v-model="form.boxAlpha"
type="number"
min="0"
max="1"
step="0.01"
/>
</div>
<label for="input-border-w" class="form-check-label">Border Width</label>
<input
id="input-border-w"
class="form-control mt-2"
v-model="form.border"
type="number"
required
/>
<label for="input-overall-alpha" class="form-check-label mt-2">Overall Alpha</label>
<input
id="input-overall-alpha"
class="form-control mt-2"
v-model="form.overallAlpha"
type="text"
required
/>
</div>
</div>
</div>
<div class="row">
<div class="col sub-btn">
<button class="btn btn-primary send-btn" type="submit">Send</button>
</div>
<div class="col">
<div
v-if="indexStore.showAlert"
class="alert show alert-dismissible fade login-alert"
:class="indexStore.alertVariant"
role="alert"
>
{{ indexStore.alertMsg }}
<button
type="button"
class="btn-close"
data-bs-dismiss="alert"
aria-label="Close"
@click="indexStore.resetAlert()"
></button>
</div>
</div>
</div>
</form>
</div>
<div class="modal fade" id="createModal" tabindex="-1" aria-labelledby="createModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="createModalLabel">New Preset</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Cancel"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="preset-name" class="col-form-label">Name:</label>
<input type="text" class="form-control" id="preset-name" v-model="newPresetName" />
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Cancel</button>
<button
type="button"
class="btn btn-primary"
@click="createNewPreset()"
data-bs-dismiss="modal"
>
Save
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="deleteModalLabel">Delete Preset</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Cancel"></button>
</div>
<div class="modal-body">Are you sure that you want to delete preset: "{{ selected }}"?</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" @click="deletePreset()" data-bs-dismiss="modal">
Ok
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useAuth } from '~/stores/auth'
import { useConfig } from '~/stores/config'
import { useIndex } from '~/stores/index'
const authStore = useAuth()
const configStore = useConfig()
const indexStore = useIndex()
const { numberToHex, hexToNumber } = stringFormatter()
const contentType = { 'content-type': 'application/json;charset=UTF-8' }
definePageMeta({
middleware: ['auth'],
})
useHead({
title: 'Messages | ffplayout'
})
interface Preset {
id: number
name: string
text: string
x: string
y: string
fontSize: number
fontSpacing: number
fontColor: string
fontAlpha: number
showBox: boolean
boxColor: string
boxAlpha: number
border: number
overallAlpha: number
}
interface PresetName {
name: string
value: number
}
const form = ref({
id: 0,
name: '',
text: '',
x: '0',
y: '0',
fontSize: 24,
fontSpacing: 4,
fontColor: '#ffffff',
fontAlpha: 1.0,
showBox: true,
boxColor: '#000000',
boxAlpha: 0.8,
border: 4,
overallAlpha: '1',
})
const selected = ref(null)
const newPresetName = ref('')
const presets = ref([] as PresetName[])
onMounted(() => {
getPreset(-1)
})
onBeforeUnmount(() => {
indexStore.resetAlert()
})
async function getPreset(index: number) {
fetch(`api/presets/${configStore.configGui[configStore.configID].id}`, {
method: 'GET',
headers: authStore.authHeader,
})
.then((response) => response.json())
.then((data) => {
if (index === -1) {
presets.value = [{ value: -1, name: '' }]
for (let i = 0; i < data.length; i++) {
const elem = data[i]
presets.value.push({ value: i, name: elem.name })
}
form.value = {
id: 0,
name: '',
text: '',
x: '0',
y: '0',
fontSize: 24,
fontSpacing: 4,
fontColor: '#ffffff',
fontAlpha: 1.0,
showBox: true,
boxColor: '#000000',
boxAlpha: 0.8,
border: 4,
overallAlpha: '1',
}
} else {
const fColor = data[index].fontcolor.split('@')
const bColor = data[index].boxcolor.split('@')
form.value = {
id: data[index].id,
name: data[index].name,
text: data[index].text,
x: data[index].x,
y: data[index].y,
fontSize: data[index].fontsize,
fontSpacing: data[index].line_spacing,
fontColor: fColor[0],
fontAlpha: fColor[1] ? hexToNumber(fColor[1]) : 1.0,
showBox: data[index].box === '1' ? true : false,
boxColor: bColor[0],
boxAlpha: bColor[1] ? hexToNumber(bColor[1]) : 1.0,
border: data[index].boxborderw,
overallAlpha: data[index].alpha,
}
}
})
}
function onChange(event: any) {
selected.value = event.target.value
getPreset(event.target.selectedIndex - 1)
}
async function savePreset() {
if (selected.value) {
const preset = {
id: form.value.id,
name: form.value.name,
text: form.value.text,
x: form.value.x,
y: form.value.y,
fontsize: form.value.fontSize,
line_spacing: form.value.fontSpacing,
fontcolor:
form.value.fontAlpha === 1
? form.value.fontColor
: form.value.fontColor + '@' + numberToHex(form.value.fontAlpha),
box: form.value.showBox ? '1' : '0',
boxcolor:
form.value.boxAlpha === 1
? form.value.boxColor
: form.value.boxColor + '@' + numberToHex(form.value.boxAlpha),
boxborderw: form.value.border,
alpha: form.value.overallAlpha,
channel_id: configStore.configGui[configStore.configID].id,
}
const response = await fetch(`api/presets/${form.value.id}`, {
method: 'PUT',
headers: { ...contentType, ...authStore.authHeader },
body: JSON.stringify(preset),
})
if (response.status === 200) {
indexStore.alertVariant = 'alert-success'
indexStore.alertMsg = 'Save Preset done!'
} else {
indexStore.alertVariant = 'alert-danger'
indexStore.alertMsg = 'Save Preset failed!'
}
indexStore.showAlert = true
}
}
async function createNewPreset() {
const preset = {
name: newPresetName.value,
text: form.value.text,
x: form.value.x.toString(),
y: form.value.y.toString(),
fontsize: form.value.fontSize.toString(),
line_spacing: form.value.fontSpacing.toString(),
fontcolor:
form.value.fontAlpha === 1
? form.value.fontColor
: form.value.fontColor + '@' + numberToHex(form.value.fontAlpha),
box: form.value.showBox ? '1' : '0',
boxcolor:
form.value.boxAlpha === 1
? form.value.boxColor
: form.value.boxColor + '@' + numberToHex(form.value.boxAlpha),
boxborderw: form.value.border.toString(),
alpha: form.value.overallAlpha.toString(),
channel_id: configStore.configGui[configStore.configID].id,
}
const response = await fetch('api/presets/', {
method: 'POST',
headers: { ...contentType, ...authStore.authHeader },
body: JSON.stringify(preset),
})
if (response.status === 200) {
indexStore.alertVariant = 'alert-success'
indexStore.alertMsg = 'Save Preset done!'
getPreset(-1)
} else {
indexStore.alertVariant = 'alert-danger'
indexStore.alertMsg = 'Save Preset failed!'
}
indexStore.showAlert = true
}
async function deletePreset() {
if (selected.value && selected.value !== '') {
await fetch(`api/presets/${form.value.id}`, {
method: 'DELETE',
headers: authStore.authHeader,
})
getPreset(-1)
}
}
async function submitMessage() {
const obj = {
text: form.value.text,
x: form.value.x.toString(),
y: form.value.y.toString(),
fontsize: form.value.fontSize.toString(),
line_spacing: form.value.fontSpacing.toString(),
fontcolor: form.value.fontColor + '@' + numberToHex(form.value.fontAlpha),
alpha: form.value.overallAlpha.toString(),
box: form.value.showBox ? '1' : '0',
boxcolor: form.value.boxColor + '@' + numberToHex(form.value.boxAlpha),
boxborderw: form.value.border.toString(),
}
const response = await fetch(`api/control/${configStore.configGui[configStore.configID].id}/text/`, {
method: 'POST',
headers: { ...contentType, ...authStore.authHeader },
body: JSON.stringify(obj),
})
if (response.status === 200) {
indexStore.alertVariant = 'alert-success'
indexStore.alertMsg = 'Sending success...'
} else {
indexStore.alertVariant = 'alert-danger'
indexStore.alertMsg = 'Sending failed...'
}
indexStore.showAlert = true
}
</script>
<style scoped>
.preset-div {
width: 50%;
margin-bottom: 2em;
}
.sub-btn {
min-width: 90px;
max-width: 100px;
}
</style>