revert ad color, fix path names, throttle buttons. work on channel creation

This commit is contained in:
Jonathan Baecker 2024-10-01 18:19:14 +02:00
parent c3da356bc7
commit 64150a8262
17 changed files with 102 additions and 83 deletions

View File

@ -50,10 +50,10 @@
</div> </div>
<label class="form-control w-full mt-3"> <label class="form-control w-full mt-3">
<div class="label"> <div class="label">
<span class="label-text">{{ t('config.hlsPath') }}</span> <span class="label-text">{{ t('config.publicPath') }}</span>
</div> </div>
<input <input
v-model="configStore.channels[configStore.id].hls_path" v-model="configStore.channels[configStore.id].public"
type="text" type="text"
class="input input-bordered w-full" class="input input-bordered w-full"
/> />
@ -64,7 +64,7 @@
<span class="label-text">{{ t('config.playlistPath') }}</span> <span class="label-text">{{ t('config.playlistPath') }}</span>
</div> </div>
<input <input
v-model="configStore.channels[configStore.id].playlist_path" v-model="configStore.channels[configStore.id].playlists"
type="text" type="text"
class="input input-bordered w-full" class="input input-bordered w-full"
/> />
@ -75,7 +75,7 @@
<span class="label-text">{{ t('config.storagePath') }}</span> <span class="label-text">{{ t('config.storagePath') }}</span>
</div> </div>
<input <input
v-model="configStore.channels[configStore.id].storage_path" v-model="configStore.channels[configStore.id].storage"
type="text" type="text"
class="input input-bordered w-full" class="input input-bordered w-full"
/> />
@ -83,7 +83,7 @@
</template> </template>
<div class="join my-4"> <div class="join my-4">
<button class="join-item btn btn-primary" @click="addUpdateChannel()"> <button class="join-item btn btn-primary" :class="saved ? 'btn-primary' : 'btn-error'" @click="addUpdateChannel()">
{{ t('config.save') }} {{ t('config.save') }}
</button> </button>
<button <button
@ -103,31 +103,36 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const { $_ } = useNuxtApp() import { cloneDeep } from 'lodash-es'
const { t } = useI18n() const { t } = useI18n()
const authStore = useAuth() const authStore = useAuth()
const configStore = useConfig() const configStore = useConfig()
const indexStore = useIndex() const indexStore = useIndex()
const saved = ref(true)
function rmId(path: string) { function rmId(path: string) {
return path.replace(/\/\d+$/, '') return path.replace(/\/\d+$/, '')
} }
function newChannel() { function newChannel() {
const channels = $_.cloneDeep(configStore.channels) const channels = cloneDeep(configStore.channels)
const newChannel = $_.cloneDeep(configStore.channels[configStore.channels.length - 1]) const newChannel = cloneDeep(configStore.channels[configStore.channels.length - 1])
newChannel.id = channels.length + 1 newChannel.id = channels.length + 1
newChannel.name = `Channel ${newChannel.id}` newChannel.name = `Channel ${newChannel.id}`
newChannel.preview_url = `${window.location.protocol}//${window.location.host}/${newChannel.id}/live/stream.m3u8` newChannel.preview_url = `${window.location.protocol}//${window.location.host}/${newChannel.id}/live/stream.m3u8`
newChannel.hls_path = `${rmId(newChannel.hls_path)}/${newChannel.id}` newChannel.public = `${rmId(newChannel.public)}/${newChannel.id}`
newChannel.playlist_path = `${rmId(newChannel.playlist_path)}/${newChannel.id}` newChannel.playlists = `${rmId(newChannel.playlists)}/${newChannel.id}`
newChannel.storage_path = `${rmId(newChannel.storage_path)}/${newChannel.id}` newChannel.storage = `${rmId(newChannel.storage)}/${newChannel.id}`
channels.push(newChannel) channels.push(newChannel)
configStore.channels = channels configStore.channels = channels
configStore.id = configStore.channels.length - 1 configStore.id = configStore.channels.length - 1
saved.value = false
} }
async function addUpdateChannel() { async function addUpdateChannel() {
@ -138,13 +143,14 @@ async function addUpdateChannel() {
if (update.status && update.status < 400) { if (update.status && update.status < 400) {
indexStore.msgAlert('success', t('config.updateChannelSuccess'), 2) indexStore.msgAlert('success', t('config.updateChannelSuccess'), 2)
saved.value = true
} else { } else {
indexStore.msgAlert('error', t('config.updateChannelFailed'), 2) indexStore.msgAlert('error', t('config.updateChannelFailed'), 2)
} }
} }
async function deleteChannel() { async function deleteChannel() {
const config = $_.cloneDeep(configStore.channels) const config = cloneDeep(configStore.channels)
const id = config[configStore.id].id const id = config[configStore.id].id
if (id === 1) { if (id === 1) {

View File

@ -67,8 +67,8 @@
</div> </div>
<div class="grow"> <div class="grow">
<strong>{{ t('player.duration') }}:</strong> <strong>{{ t('player.duration') }}:</strong>
{{ secToHMS(playlistStore.current.duration) }} | {{ secToHMS(playlistStore.current.duration) }} | <strong>{{ t('player.in') }}:</strong>
<strong>{{ t('player.in') }}:</strong> {{ secToHMS(playlistStore.current.in) }} | {{ secToHMS(playlistStore.current.in) }} |
<strong>{{ t('player.out') }}:</strong> <strong>{{ t('player.out') }}:</strong>
{{ secToHMS(playlistStore.current.out) }} {{ secToHMS(playlistStore.current.out) }}
@ -80,7 +80,11 @@
<div class="h-1/3"> <div class="h-1/3">
<progress <progress
class="progress progress-accent w-full" class="progress progress-accent w-full"
:value="playlistStore.progressValue" :value="
playlistStore.progressValue && playlistStore.progressValue <= 100
? playlistStore.progressValue
: 0
"
max="100" max="100"
/> />
</div> </div>
@ -165,6 +169,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { throttle } from 'lodash-es'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import mpegts from 'mpegts.js' import mpegts from 'mpegts.js'
@ -203,9 +208,7 @@ const mpegtsOptions = ref({
liveBufferLatencyChasing: true, liveBufferLatencyChasing: true,
}) })
const streamUrl = ref( const streamUrl = ref(`/data/event/${configStore.channels[configStore.id].id}?endpoint=playout&uuid=${authStore.uuid}`)
`/data/event/${configStore.channels[configStore.id].id}?endpoint=playout&uuid=${authStore.uuid}`
)
// 'http://127.0.0.1:8787/data/event/1?endpoint=playout&uuid=f2f8c29b-712a-48c5-8919-b535d3a05a3a' // 'http://127.0.0.1:8787/data/event/1?endpoint=playout&uuid=f2f8c29b-712a-48c5-8919-b535d3a05a3a'
const { status, data, error, close } = useEventSource(streamUrl, [], { const { status, data, error, close } = useEventSource(streamUrl, [], {
@ -256,9 +259,9 @@ watch([status, error], async () => {
if (errorCounter.value > 11) { if (errorCounter.value > 11) {
await authStore.obtainUuid() await authStore.obtainUuid()
streamUrl.value = `/data/event/${ streamUrl.value = `/data/event/${configStore.channels[configStore.id].id}?endpoint=playout&uuid=${
configStore.channels[configStore.id].id authStore.uuid
}?endpoint=playout&uuid=${authStore.uuid}` }`
errorCounter.value = 0 errorCounter.value = 0
} }
} }
@ -280,9 +283,7 @@ watch([data], () => {
watch([id], () => { watch([id], () => {
resetStatus() resetStatus()
streamUrl.value = `/data/event/${configStore.channels[configStore.id].id}?endpoint=playout&uuid=${ streamUrl.value = `/data/event/${configStore.channels[configStore.id].id}?endpoint=playout&uuid=${authStore.uuid}`
authStore.uuid
}`
if (timer.value) { if (timer.value) {
clearTimeout(timer.value) clearTimeout(timer.value)
@ -313,20 +314,19 @@ function resetStatus() {
playlistStore.current = currentDefault playlistStore.current = currentDefault
} }
async function controlProcess(state: string) { const controlProcess = throttle(async (state: string) => {
/* /*
Control playout (start, stop, restart) Control playout (start, stop, restart)
*/ */
const channel = configStore.channels[configStore.id].id const channel = configStore.channels[configStore.id].id
await $fetch(`/api/control/${channel}/process/`, { await $fetch(`/api/control/${channel}/process/`, {
method: 'POST', method: 'POST',
headers: { ...configStore.contentType, ...authStore.authHeader }, headers: { ...configStore.contentType, ...authStore.authHeader },
body: JSON.stringify({ command: state }), body: JSON.stringify({ command: state }),
}) })
} }, 800)
async function controlPlayout(state: string) { const controlPlayout = throttle(async (state: string) => {
/* /*
Control playout: Control playout:
- jump to next clip - jump to next clip
@ -340,5 +340,5 @@ async function controlPlayout(state: string) {
headers: { ...configStore.contentType, ...authStore.authHeader }, headers: { ...configStore.contentType, ...authStore.authHeader },
body: JSON.stringify({ control: state }), body: JSON.stringify({ control: state }),
}) })
} }, 800)
</script> </script>

View File

@ -347,7 +347,7 @@ function addFolderToTemplate(event: any, item: TemplateItem) {
event.item.remove() event.item.remove()
const storagePath = configStore.channels[configStore.id].storage_path const storagePath = configStore.channels[configStore.id].storage
const navPath = mediaStore.folderCrumbs[mediaStore.folderCrumbs.length - 1].path const navPath = mediaStore.folderCrumbs[mediaStore.folderCrumbs.length - 1].path
const sourcePath = `${storagePath}/${navPath}/${mediaStore.folderList.folders[o].name}`.replace(/\/[/]+/g, '/') const sourcePath = `${storagePath}/${navPath}/${mediaStore.folderList.folders[o].name}`.replace(/\/[/]+/g, '/')

View File

@ -78,7 +78,7 @@
'!bg-lime-500/30': '!bg-lime-500/30':
playlistStore.playoutIsRunning && listDate === todayDate && index === currentIndex, playlistStore.playoutIsRunning && listDate === todayDate && index === currentIndex,
'!bg-amber-600/40': element.overtime, '!bg-amber-600/40': element.overtime,
'text-blue-300': element.category === 'advertisement', 'text-base-content/60': element.category === 'advertisement',
}" }"
> >
<td v-if="!configStore.playout.playlist.infinit" class="ps-4 py-2 text-left"> <td v-if="!configStore.playout.playlist.infinit" class="ps-4 py-2 text-left">
@ -259,7 +259,7 @@ function addClip(event: any) {
event.item?.remove() event.item?.remove()
const storagePath = configStore.channels[configStore.id].storage_path const storagePath = configStore.channels[configStore.id].storage
const sourcePath = `${storagePath}/${mediaStore.folderTree.source}/${mediaStore.folderTree.files[o].name}`.replace( const sourcePath = `${storagePath}/${mediaStore.folderTree.source}/${mediaStore.folderTree.files[o].name}`.replace(
/\/[/]+/g, /\/[/]+/g,
'/' '/'

View File

@ -200,7 +200,7 @@ export default {
updatePlayoutFailed: 'Update playout config fehlgeschlagen!', updatePlayoutFailed: 'Update playout config fehlgeschlagen!',
forbiddenPlaylistPath: 'Zugriff untersagt: Playlist-Ordner kann nicht geöffnet werden.', forbiddenPlaylistPath: 'Zugriff untersagt: Playlist-Ordner kann nicht geöffnet werden.',
noPlayoutConfig: 'Keine Playout-Konfiguration gefunden!', noPlayoutConfig: 'Keine Playout-Konfiguration gefunden!',
hlsPath: 'HLS-Pfad', publicPath: 'Public (HLS) Pfad',
playlistPath: 'Wiedergabelistenpfad', playlistPath: 'Wiedergabelistenpfad',
storagePath: 'Speicherpfad', storagePath: 'Speicherpfad',
sharedStorage: 'Gemeinsamer Speicher ist aktiviert, verwende denselben Speicherstamm für alle Kanäle!', sharedStorage: 'Gemeinsamer Speicher ist aktiviert, verwende denselben Speicherstamm für alle Kanäle!',

View File

@ -199,7 +199,7 @@ export default {
updatePlayoutFailed: 'Update playout config failed!', updatePlayoutFailed: 'Update playout config failed!',
forbiddenPlaylistPath: 'Access forbidden: Playlist folder cannot be opened.', forbiddenPlaylistPath: 'Access forbidden: Playlist folder cannot be opened.',
noPlayoutConfig: 'No playout config found!', noPlayoutConfig: 'No playout config found!',
hlsPath: 'HLS Path', publicPath: 'Public (HLS) Path',
playlistPath: 'Playlist Path', playlistPath: 'Playlist Path',
storagePath: 'Storage Path', storagePath: 'Storage Path',
sharedStorage: 'Shared storage is enabled, use the same storage root for all channels!', sharedStorage: 'Shared storage is enabled, use the same storage root for all channels!',

View File

@ -199,7 +199,7 @@ export default {
updatePlayoutFailed: 'Falha na atualização da configuração do playout!', updatePlayoutFailed: 'Falha na atualização da configuração do playout!',
forbiddenPlaylistPath: 'Acesso proibido: A pasta da lista de reprodução não pode ser aberta', forbiddenPlaylistPath: 'Acesso proibido: A pasta da lista de reprodução não pode ser aberta',
noPlayoutConfig: 'Nenhuma configuração de playout encontrada!', noPlayoutConfig: 'Nenhuma configuração de playout encontrada!',
hlsPath: 'HLS Path', publicPath: 'Public (HLS) Path',
playlistPath: 'Playlist Path', playlistPath: 'Playlist Path',
storagePath: 'Storage Path', storagePath: 'Storage Path',
sharedStorage: 'O armazenamento compartilhado está ativado, use a mesma raiz de armazenamento para todos os canais', sharedStorage: 'O armazenamento compartilhado está ativado, use a mesma raiz de armazenamento para todos os canais',

View File

@ -199,7 +199,7 @@ export default {
updatePlayoutFailed: 'Обновление конфигурации воспроизведения не удалось!', updatePlayoutFailed: 'Обновление конфигурации воспроизведения не удалось!',
forbiddenPlaylistPath: 'Доступ запрещен: Папка плейлиста не может быть открыта.', forbiddenPlaylistPath: 'Доступ запрещен: Папка плейлиста не может быть открыта.',
noPlayoutConfig: 'Конфигурация воспроизведения не найдена!', noPlayoutConfig: 'Конфигурация воспроизведения не найдена!',
hlsPath: 'HLS Path', publicPath: 'Public (HLS) Path',
playlistPath: 'Playlist Path', playlistPath: 'Playlist Path',
storagePath: 'Storage Path', storagePath: 'Storage Path',
sharedStorage: 'Общее хранилище включено, используйте один и тот же корень хранилища для всех каналов!', sharedStorage: 'Общее хранилище включено, используйте один и тот же корень хранилища для всех каналов!',

View File

@ -17,7 +17,7 @@
"bootstrap-icons": "^1.11.3", "bootstrap-icons": "^1.11.3",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"lodash": "^4.17.21", "lodash-es": "^4.17.21",
"mpegts.js": "^1.7.3", "mpegts.js": "^1.7.3",
"nuxt": "3.13.2", "nuxt": "3.13.2",
"pinia": "^2.2.2", "pinia": "^2.2.2",
@ -29,7 +29,7 @@
"@nuxt/eslint": "^0.5.7", "@nuxt/eslint": "^0.5.7",
"@nuxtjs/i18n": "^8.5.5", "@nuxtjs/i18n": "^8.5.5",
"@nuxtjs/tailwindcss": "^6.12.1", "@nuxtjs/tailwindcss": "^6.12.1",
"@types/lodash": "^4.17.9", "@types/lodash-es": "^4.17.12",
"@types/video.js": "^7.3.58", "@types/video.js": "^7.3.58",
"daisyui": "^4.12.10", "daisyui": "^4.12.10",
"mini-svg-data-uri": "^1.4.4", "mini-svg-data-uri": "^1.4.4",
@ -3558,6 +3558,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/lodash-es": {
"version": "4.17.12",
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/lodash": "*"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.7.4", "version": "22.7.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz",
@ -8988,6 +8998,12 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
"node_modules/lodash.defaults": { "node_modules/lodash.defaults": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",

View File

@ -21,7 +21,7 @@
"bootstrap-icons": "^1.11.3", "bootstrap-icons": "^1.11.3",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"jwt-decode": "^4.0.0", "jwt-decode": "^4.0.0",
"lodash": "^4.17.21", "lodash-es": "^4.17.21",
"mpegts.js": "^1.7.3", "mpegts.js": "^1.7.3",
"nuxt": "3.13.2", "nuxt": "3.13.2",
"pinia": "^2.2.2", "pinia": "^2.2.2",
@ -33,7 +33,7 @@
"@nuxt/eslint": "^0.5.7", "@nuxt/eslint": "^0.5.7",
"@nuxtjs/i18n": "^8.5.5", "@nuxtjs/i18n": "^8.5.5",
"@nuxtjs/tailwindcss": "^6.12.1", "@nuxtjs/tailwindcss": "^6.12.1",
"@types/lodash": "^4.17.9", "@types/lodash-es": "^4.17.12",
"@types/video.js": "^7.3.58", "@types/video.js": "^7.3.58",
"daisyui": "^4.12.10", "daisyui": "^4.12.10",
"mini-svg-data-uri": "^1.4.4", "mini-svg-data-uri": "^1.4.4",

View File

@ -329,6 +329,7 @@ watch([width], () => {
const horizontal = ref(false) const horizontal = ref(false)
const deleteName = ref('') const deleteName = ref('')
const renameOldName = ref('') const renameOldName = ref('')
const renameOldPath = ref('')
const renameNewName = ref('') const renameNewName = ref('')
const previewName = ref('') const previewName = ref('')
const previewUrl = ref('') const previewUrl = ref('')
@ -513,8 +514,13 @@ async function deleteFileOrFolder(del: boolean) {
} }
function setRenameValues(path: string) { function setRenameValues(path: string) {
renameNewName.value = path const index = path.lastIndexOf('/')
renameOldName.value = path const dir = path.substring(0, index + 1) || '/'
const file = path.substring(index + 1)
renameOldName.value = file
renameOldPath.value = dir
renameNewName.value = file
} }
async function renameFile(ren: boolean) { async function renameFile(ren: boolean) {
@ -527,7 +533,10 @@ async function renameFile(ren: boolean) {
await fetch(`/api/file/${configStore.channels[configStore.id].id}/rename/`, { await fetch(`/api/file/${configStore.channels[configStore.id].id}/rename/`, {
method: 'POST', method: 'POST',
headers: { ...configStore.contentType, ...authStore.authHeader }, headers: { ...configStore.contentType, ...authStore.authHeader },
body: JSON.stringify({ source: renameOldName.value, target: renameNewName.value }), body: JSON.stringify({
source: `${renameOldPath.value}${renameOldName.value}`,
target: `${renameOldPath.value}${renameNewName.value}`,
}),
}) })
.then(async (res) => { .then(async (res) => {
if (res.status >= 400) { if (res.status >= 400) {
@ -542,6 +551,7 @@ async function renameFile(ren: boolean) {
} }
renameOldName.value = '' renameOldName.value = ''
renameOldPath.value = ''
renameNewName.value = '' renameNewName.value = ''
} }

View File

@ -174,7 +174,7 @@
v-model="newSource.source" v-model="newSource.source"
type="text" type="text"
class="input input-sm input-bordered w-auto" class="input input-sm input-bordered w-auto"
:disabled="newSource.source.includes(configStore.channels[configStore.id].storage_path)" :disabled="newSource.source.includes(configStore.channels[configStore.id].storage)"
/> />
</label> </label>
@ -230,9 +230,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { cloneDeep } from 'lodash-es'
const colorMode = useColorMode() const colorMode = useColorMode()
const { locale, t } = useI18n() const { locale, t } = useI18n()
const { $_, $dayjs } = useNuxtApp() const { $dayjs } = useNuxtApp()
const { width } = useWindowSize({ initialWidth: 800 }) const { width } = useWindowSize({ initialWidth: 800 })
const { mediaType } = stringFormatter() const { mediaType } = stringFormatter()
const { processPlaylist, genUID } = playlistOperations() const { processPlaylist, genUID } = playlistOperations()
@ -314,7 +316,7 @@ function closePlayer() {
function setPreviewData(path: string) { function setPreviewData(path: string) {
let fullPath = path let fullPath = path
const storagePath = configStore.channels[configStore.id].storage_path const storagePath = configStore.channels[configStore.id].storage
const lastIndex = storagePath.lastIndexOf('/') const lastIndex = storagePath.lastIndexOf('/')
if (!path.includes('/')) { if (!path.includes('/')) {
@ -428,7 +430,7 @@ function loopClips() {
for (const item of playlistStore.playlist) { for (const item of playlistStore.playlist) {
if (length < configStore.playlistLength) { if (length < configStore.playlistLength) {
item.uid = genUID() item.uid = genUID()
tempList.push($_.cloneDeep(item)) tempList.push(cloneDeep(item))
length += item.out - item.in length += item.out - item.in
} else { } else {
break break
@ -493,7 +495,7 @@ async function savePlaylist(save: boolean) {
return return
} }
const saveList = processPlaylist(listDate.value, $_.cloneDeep(playlistStore.playlist), true) const saveList = processPlaylist(listDate.value, cloneDeep(playlistStore.playlist), true)
await $fetch(`/api/playlist/${configStore.channels[configStore.id].id}/`, { await $fetch(`/api/playlist/${configStore.channels[configStore.id].id}/`, {
method: 'POST', method: 'POST',

View File

@ -1,17 +0,0 @@
import lodash from 'lodash'
import type { LoDashStatic } from 'lodash'
declare module '#app' {
interface NuxtApp {
$_: LoDashStatic
}
}
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$_: LoDashStatic
}
}
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.provide('_', lodash)
})

View File

@ -40,10 +40,10 @@ export const useAuth = defineStore('auth', {
password, password,
} }
await $fetch<LoginObj>('/auth/login/', { await $fetch('/auth/login/', {
method: 'POST', method: 'POST',
body: JSON.stringify(payload), body: JSON.stringify(payload),
async onResponse({ response }) { async onResponse(response: LoginObj) {
code = response.status code = response.status
}, },
}) })
@ -60,7 +60,7 @@ export const useAuth = defineStore('auth', {
}, },
async obtainUuid() { async obtainUuid() {
await $fetch<DataAuth>('/api/generate-uuid', { await $fetch('/api/generate-uuid', {
method: 'POST', method: 'POST',
headers: this.authHeader, headers: this.authHeader,
}) })

View File

@ -1,4 +1,4 @@
import _ from 'lodash' import { cloneDeep } from 'lodash-es'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
export const useConfig = defineStore('config', { export const useConfig = defineStore('config', {
@ -70,7 +70,7 @@ export const useConfig = defineStore('config', {
this.utcOffset = objs[0].utc_offset this.utcOffset = objs[0].utc_offset
this.channels = objs this.channels = objs
this.channelsRaw = _.cloneDeep(objs) this.channelsRaw = cloneDeep(objs)
this.configCount = objs.length this.configCount = objs.length
}) })
.catch((e) => { .catch((e) => {
@ -84,9 +84,9 @@ export const useConfig = defineStore('config', {
extra_extensions: '', extra_extensions: '',
name: 'Channel 1', name: 'Channel 1',
preview_url: '', preview_url: '',
hls_path: '', public: '',
playlist_path: '', playlists: '',
storage_path: '', storage: '',
uts_offset: 0, uts_offset: 0,
}, },
] ]
@ -97,7 +97,7 @@ export const useConfig = defineStore('config', {
async setChannelConfig(obj: Channel): Promise<any> { async setChannelConfig(obj: Channel): Promise<any> {
const authStore = useAuth() const authStore = useAuth()
const stringObj = _.cloneDeep(obj) const stringObj = cloneDeep(obj)
let response let response
if (this.channelsRaw.some((e) => e.id === stringObj.id)) { if (this.channelsRaw.some((e) => e.id === stringObj.id)) {
@ -125,7 +125,7 @@ export const useConfig = defineStore('config', {
} }
this.channels = guiConfigs this.channels = guiConfigs
this.channelsRaw = _.cloneDeep(guiConfigs) this.channelsRaw = cloneDeep(guiConfigs)
this.configCount = guiConfigs.length this.configCount = guiConfigs.length
} }

View File

@ -1,4 +1,5 @@
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { differenceWith, isEqual, omit } from 'lodash-es'
import utc from 'dayjs/plugin/utc.js' import utc from 'dayjs/plugin/utc.js'
import timezone from 'dayjs/plugin/timezone.js' import timezone from 'dayjs/plugin/timezone.js'
@ -28,13 +29,13 @@ export const usePlaylist = defineStore('playlist', {
getters: {}, getters: {},
actions: { actions: {
async getPlaylist(date: string) { async getPlaylist(date: string) {
const { $_, $i18n } = useNuxtApp() const { $i18n } = useNuxtApp()
const authStore = useAuth() const authStore = useAuth()
const configStore = useConfig() const configStore = useConfig()
const indexStore = useIndex() const indexStore = useIndex()
const channel = configStore.channels[configStore.id].id const channel = configStore.channels[configStore.id].id
await $fetch<Playlist>(`/api/playlist/${channel}?date=${date}`, { await $fetch(`/api/playlist/${channel}?date=${date}`, {
method: 'GET', method: 'GET',
headers: authStore.authHeader, headers: authStore.authHeader,
}) })
@ -47,8 +48,8 @@ export const usePlaylist = defineStore('playlist', {
this.playlist.length > 0 && this.playlist.length > 0 &&
programData.length > 0 && programData.length > 0 &&
(this.playlist[0].date === date || configStore.playout.playlist.infinit) && (this.playlist[0].date === date || configStore.playout.playlist.infinit) &&
$_.differenceWith(this.playlist, programData, (a, b) => { differenceWith(this.playlist, programData, (a, b) => {
return $_.isEqual($_.omit(a, ['uid']), $_.omit(b, ['uid'])) return isEqual(omit(a, ['uid']), omit(b, ['uid']))
}).length > 0 }).length > 0
) { ) {
indexStore.msgAlert('warning', $i18n.t('player.unsavedProgram'), 3) indexStore.msgAlert('warning', $i18n.t('player.unsavedProgram'), 3)

View File

@ -11,6 +11,7 @@ declare global {
interface LoginObj { interface LoginObj {
message: string message: string
status: number
user?: { user?: {
id: number id: number
mail: string mail: string
@ -28,9 +29,9 @@ declare global {
extra_extensions: string | string[] extra_extensions: string | string[]
name: string name: string
preview_url: string preview_url: string
hls_path: string public: string
playlist_path: string playlists: string
storage_path: string storage: string
uts_offset?: number uts_offset?: number
} }