minor design update for index page.

This commit is contained in:
arabcoders 2025-06-21 20:47:18 +03:00
parent a188c20099
commit a2f5c770c6
3 changed files with 173 additions and 87 deletions

View file

@ -234,7 +234,7 @@
<div class="columns is-multiline" v-else> <div class="columns is-multiline" v-else>
<LateLoader :unrender="true" :min-height="showThumbnails ? 410 : 210" class="column is-6" <LateLoader :unrender="true" :min-height="showThumbnails ? 410 : 210" class="column is-6"
v-for="item in sortCompleted" :key="item._id"> v-for="item in filteredItems(sortCompleted)" :key="item._id">
<div class="card is-flex is-full-height is-flex-direction-column" <div class="card is-flex is-full-height is-flex-direction-column"
:class="{ 'is-bordered-danger': item.status === 'error', 'is-bordered-info': item.live_in || item.is_live }"> :class="{ 'is-bordered-danger': item.status === 'error', 'is-bordered-info': item.live_in || item.is_live }">
<header class="card-header"> <header class="card-header">
@ -286,18 +286,8 @@
</template> </template>
</figure> </figure>
</div> </div>
<div class="card-content is-flex-grow-1"> <div class="card-content">
<div class="columns is-mobile is-multiline"> <div class="columns is-mobile is-multiline">
<div class="column is-12" v-if="item.error">
<div class="is-text-overflow is-pointer" @click="toggle_class($event)">
<span class="has-text-danger">{{ item.error }}</span>
</div>
</div>
<div class="column is-12" v-if="showMessage(item)">
<div class="is-text-overflow is-pointer" @click="toggle_class($event)">
<span class="has-text-danger">{{ item.msg }}</span>
</div>
</div>
<div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable"> <div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable">
<span class="icon-text"> <span class="icon-text">
<span class="icon" :class="setIconColor(item)"><i :class="[setIcon(item), is_queued(item)]" /></span> <span class="icon" :class="setIconColor(item)"><i :class="[setIcon(item), is_queued(item)]" /></span>
@ -329,14 +319,6 @@
</span> </span>
</a> </a>
</div> </div>
<div class="column is-half-mobile">
<a class="button is-danger is-fullwidth" @click="removeItem(item)">
<span class="icon-text is-block">
<span class="icon"><i class="fa-solid fa-trash-can" /></span>
<span>Remove</span>
</span>
</a>
</div>
<div class="column is-half-mobile" v-if="item.filename && item.status === 'finished'"> <div class="column is-half-mobile" v-if="item.filename && item.status === 'finished'">
<a class="button is-link is-fullwidth" :href="makeDownload(config, item)" <a class="button is-link is-fullwidth" :href="makeDownload(config, item)"
@ -347,7 +329,17 @@
</span> </span>
</a> </a>
</div> </div>
<div class="column" v-if="item.url && !config.app.basic_mode">
<div class="column is-half-mobile">
<a class="button is-danger is-fullwidth" @click="removeItem(item)">
<span class="icon-text is-block">
<span class="icon"><i class="fa-solid fa-trash-can" /></span>
<span>Remove</span>
</span>
</a>
</div>
<div class="column">
<Dropdown icons="fa-solid fa-cogs" label="Actions"> <Dropdown icons="fa-solid fa-cogs" label="Actions">
<template v-if="'finished' === item.status && item.filename"> <template v-if="'finished' === item.status && item.filename">
<NuxtLink @click="playVideo(item)" class="dropdown-item"> <NuxtLink @click="playVideo(item)" class="dropdown-item">
@ -365,12 +357,13 @@
<hr class="dropdown-divider" /> <hr class="dropdown-divider" />
</template> </template>
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url)"> <NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url)" v-if="!config.app.basic_mode">
<span class="icon"><i class="fa-solid fa-info" /></span> <span class="icon"><i class="fa-solid fa-info" /></span>
<span>yt-dlp Information</span> <span>yt-dlp Information</span>
</NuxtLink> </NuxtLink>
<NuxtLink class="dropdown-item" @click="emitter('getItemInfo', item._id)"> <NuxtLink class="dropdown-item" @click="emitter('getItemInfo', item._id)"
v-if="!config.app.basic_mode">
<span class="icon"><i class="fa-solid fa-info-circle" /></span> <span class="icon"><i class="fa-solid fa-info-circle" /></span>
<span>Local Information</span> <span>Local Information</span>
</NuxtLink> </NuxtLink>
@ -383,7 +376,7 @@
</NuxtLink> </NuxtLink>
</template> </template>
<template v-if="'finished' !== item.status && config.app?.keep_archive"> <template v-if="'finished' !== item.status && config.app?.keep_archive && !config.app.basic_mode">
<hr class="dropdown-divider" /> <hr class="dropdown-divider" />
<NuxtLink class="dropdown-item has-text-danger" @click="addArchiveDialog(item)"> <NuxtLink class="dropdown-item has-text-danger" @click="addArchiveDialog(item)">
<span class="icon"><i class="fa-solid fa-box-archive" /></span> <span class="icon"><i class="fa-solid fa-box-archive" /></span>
@ -391,7 +384,8 @@
</NuxtLink> </NuxtLink>
</template> </template>
<template v-if="'finished' === item.status && item.filename && config.app?.keep_archive"> <template
v-if="'finished' === item.status && item.filename && config.app?.keep_archive && !config.app.basic_mode">
<hr class="dropdown-divider" /> <hr class="dropdown-divider" />
<NuxtLink class="dropdown-item" @click="removeFromArchiveDialog(item)"> <NuxtLink class="dropdown-item" @click="removeFromArchiveDialog(item)">
<span class="icon"><i class="fa-solid fa-box-archive" /></span> <span class="icon"><i class="fa-solid fa-box-archive" /></span>
@ -400,6 +394,19 @@
</template> </template>
</Dropdown> </Dropdown>
</div> </div>
</div>
<div class="columns is-mobile is-multiline" v-if="item.error || showMessage(item)">
<div class="column is-12" v-if="item.error">
<div class="is-text-overflow is-pointer" @click="toggle_class($event)">
<span class="has-text-danger">{{ item.error }}</span>
</div>
</div>
<div class="column is-12" v-if="showMessage(item)">
<div class="is-text-overflow is-pointer" @click="toggle_class($event)">
<span class="has-text-danger">{{ item.msg }}</span>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -408,8 +415,12 @@
<div class="columns is-multiline" v-if="!hasItems"> <div class="columns is-multiline" v-if="!hasItems">
<div class="column is-12"> <div class="column is-12">
<Message message_class="has-background-warning-90 has-text-dark" title="No results for downloaded items."
icon="fas fa-search" :useClose="true" @close="() => emitter('clear_search')" v-if="query">
<span class="is-block">No results found for '<span class="is-underlined is-bold">{{ query }}</span>'.</span>
</Message>
<Message message_class="has-background-success-90 has-text-dark" title="No records in history." <Message message_class="has-background-success-90 has-text-dark" title="No records in history."
icon="fas fa-circle-check" v-if="socket.isConnected" /> icon="fas fa-circle-check" v-else-if="socket.isConnected" />
<Message message_class="has-background-info-90 has-text-dark" title="Connecting.." icon="fas fa-spinner fa-spin" <Message message_class="has-background-info-90 has-text-dark" title="Connecting.." icon="fas fa-spinner fa-spin"
v-else /> v-else />
</div> </div>
@ -446,12 +457,17 @@ import { getEmbedable, isEmbedable } from '~/utils/embedable'
import { formatBytes, makeDownload, uri } from '~/utils/index' import { formatBytes, makeDownload, uri } from '~/utils/index'
import Dropdown from './Dropdown.vue' import Dropdown from './Dropdown.vue'
const emitter = defineEmits(['getInfo', 'add_new', 'getItemInfo']) const emitter = defineEmits(['getInfo', 'add_new', 'getItemInfo', 'clear_search'])
const props = defineProps({ const props = defineProps({
thumbnails: { thumbnails: {
type: Boolean, type: Boolean,
default: true default: true
},
query: {
type: String,
required: false,
default: '',
} }
}) })
@ -461,34 +477,42 @@ const socket = useSocketStore()
const toast = useNotification() const toast = useNotification()
const box = useConfirm() const box = useConfirm()
const selectedElms = ref([])
const masterSelectAll = ref(false)
const showCompleted = useStorage('showCompleted', true) const showCompleted = useStorage('showCompleted', true)
const hideThumbnail = useStorage('hideThumbnailHistory', false) const hideThumbnail = useStorage('hideThumbnailHistory', false)
const direction = useStorage('sortCompleted', 'desc') const direction = useStorage('sortCompleted', 'desc')
const display_style = useStorage('display_style', 'cards') const display_style = useStorage('display_style', 'cards')
const table_container = ref(false) const bg_enable = useStorage('random_bg', true)
const bg_opacity = useStorage('random_bg_opacity', 0.85)
const selectedElms = ref([])
const masterSelectAll = ref(false)
const table_container = ref(false)
const embed_url = ref('') const embed_url = ref('')
const video_item = ref(null) const video_item = ref(null)
const dialog_confirm = ref({ const dialog_confirm = ref({
visible: false, visible: false,
title: 'Confirm Action', title: 'Confirm Action',
confirm: (opts) => { }, confirm: () => { },
message: '', message: '',
options: [ options: [
{ key: 'remove_history', label: 'Also, Remove from history.' }, { key: 'remove_history', label: 'Also, Remove from history.' },
], ],
}) })
const showThumbnails = computed(() => props.thumbnails && !hideThumbnail.value)
const playVideo = item => video_item.value = item const playVideo = item => video_item.value = item
const closeVideo = () => video_item.value = null const closeVideo = () => video_item.value = null
const showThumbnails = computed(() => props.thumbnails && !hideThumbnail.value) const filteredItems = items => !props.query ? items : items.filter(filterItem)
const bg_enable = useStorage('random_bg', true) const filterItem = item => {
const bg_opacity = useStorage('random_bg_opacity', 0.85) const q = props.query?.toLowerCase()
if (!q) {
return true
}
return Object.values(item).some(v => typeof v === 'string' && v.toLowerCase().includes(q))
}
watch(masterSelectAll, (value) => { watch(masterSelectAll, (value) => {
for (const key in stateStore.history) { for (const key in stateStore.history) {
@ -512,7 +536,7 @@ const sortCompleted = computed(() => {
}) })
const hasSelected = computed(() => selectedElms.value.length > 0) const hasSelected = computed(() => selectedElms.value.length > 0)
const hasItems = computed(() => stateStore.count('history') > 0) const hasItems = computed(() => filteredItems(sortCompleted.value).length > 0)
const showMessage = (item) => { const showMessage = (item) => {
if (!item?.msg || item.msg === item?.error) { if (!item?.msg || item.msg === item?.error) {

View file

@ -4,12 +4,12 @@
<span class="icon"> <span class="icon">
<i class="fas" :class="showQueue ? 'fa-solid fa-arrow-up' : 'fa-solid fa-arrow-down'" /> <i class="fas" :class="showQueue ? 'fa-solid fa-arrow-up' : 'fa-solid fa-arrow-down'" />
</span> </span>
<span>Queue <span v-if="hasQueuedItems">({{ stateStore.count('queue') }})</span></span> <span>Queue <span v-if="hasQueuedItems">({{ filteredItems.length }})</span></span>
</span> </span>
</h1> </h1>
<div v-if="showQueue"> <div v-if="showQueue">
<div class="columns is-multiline is-mobile has-text-centered" v-if="hasQueuedItems"> <div class="columns is-multiline is-mobile has-text-centered" v-if="filteredItems.length > 0">
<div class="column is-half-mobile" v-if="'cards' === display_style"> <div class="column is-half-mobile" v-if="'cards' === display_style">
<button type="button" class="button is-fullwidth is-ghost" @click="masterSelectAll = !masterSelectAll"> <button type="button" class="button is-fullwidth is-ghost" @click="masterSelectAll = !masterSelectAll">
<span class="icon-text is-block"> <span class="icon-text is-block">
@ -34,8 +34,8 @@
</div> </div>
<div class="columns is-multiline" v-if="'list' === display_style"> <div class="columns is-multiline" v-if="'list' === display_style">
<div class="column is-12" v-if="hasQueuedItems"> <div class="column is-12" v-if="filteredItems.length > 0">
<div class="table-container is-responsive"> <div :class="{ 'table-container': table_container }">
<table class="table is-striped is-hoverable is-fullwidth is-bordered" <table class="table is-striped is-hoverable is-fullwidth is-bordered"
style="min-width: 1300px; table-layout: fixed;"> style="min-width: 1300px; table-layout: fixed;">
<thead> <thead>
@ -58,7 +58,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="item in stateStore.queue" :key="item._id"> <tr v-for="item in filteredItems" :key="item._id">
<td class="has-text-centered is-vcentered"> <td class="has-text-centered is-vcentered">
<label class="checkbox is-block"> <label class="checkbox is-block">
<input class="completed-checkbox" type="checkbox" v-model="selectedElms" <input class="completed-checkbox" type="checkbox" v-model="selectedElms"
@ -105,26 +105,34 @@
:data-datetime="item.datetime" v-rtime="item.datetime" /> :data-datetime="item.datetime" v-rtime="item.datetime" />
</td> </td>
<td class="is-vcentered is-items-center"> <td class="is-vcentered is-items-center">
<div class="field is-grouped is-grouped-centered"> <Dropdown icons="fa-solid fa-cogs" @open_state="s => table_container = !s"
<div class="control" v-if="isEmbedable(item.url)"> :button_classes="'is-small'" label="Actions">
<button @click="() => embed_url = getEmbedable(item.url)" v-tooltip="'Play video'" <template v-if="isEmbedable(item.url)">
class="button is-danger is-small"> <NuxtLink class="dropdown-item has-text-danger" @click="embed_url = getEmbedable(item.url)">
<span class="icon"><i class="fa-solid fa-play" /></span> <span class="icon"><i class="fa-solid fa-play" /></span>
</button> <span>Play video</span>
</div> </NuxtLink>
<div class="control"> <hr class="dropdown-divider" />
<button class="button is-warning is-small" @click="confirmCancel(item);" </template>
v-tooltip="'Cancel download'">
<span class="icon"><i class="fa-solid fa-eject" /></span> <NuxtLink class="dropdown-item has-text-warning" @click="confirmCancel(item);">
</button> <span class="icon"><i class="fa-solid fa-eject" /></span>
</div> <span>Cancel Item</span>
<div class="control" v-if="item.url && !config.app.basic_mode"> </NuxtLink>
<button class="button is-info is-small" @click="emitter('getInfo', item.url)"
v-tooltip="'Show video information'"> <hr class="dropdown-divider" v-if="!config.app.basic_mode" />
<span class="icon"><i class="fa-solid fa-info" /></span>
</button> <NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url)" v-if="!config.app.basic_mode">
</div> <span class="icon"><i class="fa-solid fa-info" /></span>
</div> <span>yt-dlp Information</span>
</NuxtLink>
<NuxtLink class="dropdown-item" @click="emitter('getItemInfo', item._id)"
v-if="!config.app.basic_mode">
<span class="icon"><i class="fa-solid fa-info-circle" /></span>
<span>Local Information</span>
</NuxtLink>
</Dropdown>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -135,8 +143,8 @@
<div class="columns is-multiline" v-else> <div class="columns is-multiline" v-else>
<LateLoader :unrender="true" :min-height="showThumbnails ? 475 : 265" class="column is-6" <LateLoader :unrender="true" :min-height="showThumbnails ? 475 : 265" class="column is-6"
v-for="item in stateStore.queue" :key="item._id"> v-for="item in filteredItems" :key="item._id">
<div class="card is-flex is-full-height is-flex-direction-column"> <div class="card">
<header class="card-header"> <header class="card-header">
<div class="card-header-title is-text-overflow is-block" v-tooltip="item.title"> <div class="card-header-title is-text-overflow is-block" v-tooltip="item.title">
<NuxtLink target="_blank" :href="item.url">{{ item.title }}</NuxtLink> <NuxtLink target="_blank" :href="item.url">{{ item.title }}</NuxtLink>
@ -149,11 +157,6 @@
{{ formatTime(item.extras.duration) }} {{ formatTime(item.extras.duration) }}
</span> </span>
</div> </div>
<div class="control" v-if="!showThumbnails && isEmbedable(item.url)">
<NuxtLink @click="embed_url = getEmbedable(item.url)" v-tooltip="'Play video'">
<span class="icon has-text-danger"><i class="fa-solid fa-play" /></span>
</NuxtLink>
</div>
<div class="control"> <div class="control">
<button @click="hideThumbnail = !hideThumbnail" v-if="thumbnails"> <button @click="hideThumbnail = !hideThumbnail" v-if="thumbnails">
<span class="icon"><i class="fa-solid" <span class="icon"><i class="fa-solid"
@ -184,7 +187,7 @@
</template> </template>
</figure> </figure>
</div> </div>
<div class="card-content is-flex-grow-1"> <div class="card-content">
<div class="columns is-multiline is-mobile"> <div class="columns is-multiline is-mobile">
<div class="column is-12"> <div class="column is-12">
<div class="progress-bar is-unselectable"> <div class="progress-bar is-unselectable">
@ -217,11 +220,27 @@
<span>Cancel</span> <span>Cancel</span>
</button> </button>
</div> </div>
<div class="column is-half-mobile" v-if="item.url && !config.app.basic_mode"> <div class="column is-half-mobile">
<button class="button is-info is-fullwidth" @click="emitter('getInfo', item.url)"> <Dropdown icons="fa-solid fa-cogs" @open_state="s => table_container = !s" label="Actions">
<span class="icon"><i class="fa-solid fa-info" /></span> <template v-if="isEmbedable(item.url)">
<span>Information</span> <NuxtLink class="dropdown-item has-text-danger" @click="embed_url = getEmbedable(item.url)">
</button> <span class="icon"><i class="fa-solid fa-play" /></span>
<span>Play video</span>
</NuxtLink>
<hr class="dropdown-divider" />
</template>
<NuxtLink class="dropdown-item" @click="emitter('getInfo', item.url)" v-if="!config.app.basic_mode">
<span class="icon"><i class="fa-solid fa-info" /></span>
<span>yt-dlp Information</span>
</NuxtLink>
<NuxtLink class="dropdown-item" @click="emitter('getItemInfo', item._id)"
v-if="!config.app.basic_mode">
<span class="icon"><i class="fa-solid fa-info-circle" /></span>
<span>Local Information</span>
</NuxtLink>
</Dropdown>
</div> </div>
</div> </div>
</div> </div>
@ -229,6 +248,14 @@
</LateLoader> </LateLoader>
</div> </div>
<div class="columns is-multiline" v-if="hasQueuedItems && filteredItems.length < 1 && query">
<div class="column is-12">
<Message message_class="has-background-warning-90 has-text-dark" title="No results for queued items"
icon="fas fa-search" :useClose="true" @close="() => emitter('clear_search')" v-if="query">
<span class="is-block">No results found for '<span class="is-underlined is-bold">{{ query }}</span>'.</span>
</Message>
</div>
</div>
<div class="modal is-active" v-if="embed_url"> <div class="modal is-active" v-if="embed_url">
<div class="modal-background" @click="embed_url = ''"></div> <div class="modal-background" @click="embed_url = ''"></div>
@ -246,11 +273,16 @@ import { useStorage } from '@vueuse/core'
import { ucFirst } from '~/utils/index' import { ucFirst } from '~/utils/index'
import { isEmbedable, getEmbedable } from '~/utils/embedable' import { isEmbedable, getEmbedable } from '~/utils/embedable'
const emitter = defineEmits(['getInfo']) const emitter = defineEmits(['getInfo', 'clear_search', 'getItemInfo'])
const props = defineProps({ const props = defineProps({
thumbnails: { thumbnails: {
type: Boolean, type: Boolean,
default: true default: true
},
query: {
type: String,
required: false,
default: ''
} }
}) })
const config = useConfigStore() const config = useConfigStore()
@ -258,18 +290,19 @@ const stateStore = useStateStore()
const socket = useSocketStore() const socket = useSocketStore()
const box = useConfirm() const box = useConfirm()
const selectedElms = ref([])
const masterSelectAll = ref(false)
const showQueue = useStorage('showQueue', true) const showQueue = useStorage('showQueue', true)
const hideThumbnail = useStorage('hideThumbnailQueue', false) const hideThumbnail = useStorage('hideThumbnailQueue', false)
const display_style = useStorage('display_style', 'cards') const display_style = useStorage('display_style', 'cards')
const showThumbnails = computed(() => props.thumbnails && !hideThumbnail.value)
const embed_url = ref('')
const bg_enable = useStorage('random_bg', true) const bg_enable = useStorage('random_bg', true)
const bg_opacity = useStorage('random_bg_opacity', 0.85) const bg_opacity = useStorage('random_bg_opacity', 0.85)
const selectedElms = ref([])
const masterSelectAll = ref(false)
const embed_url = ref('')
const table_container = ref(false)
const showThumbnails = computed(() => props.thumbnails && !hideThumbnail.value)
watch(masterSelectAll, (value) => { watch(masterSelectAll, (value) => {
for (const key in stateStore.queue) { for (const key in stateStore.queue) {
const element = stateStore.queue[key] const element = stateStore.queue[key]
@ -281,6 +314,14 @@ watch(masterSelectAll, (value) => {
} }
}) })
const filteredItems = computed(() => {
const q = props.query?.toLowerCase();
if (!q) {
return Object.values(stateStore.queue)
}
return Object.values(stateStore.queue).filter(i => Object.values(i).some(v => typeof v === 'string' && v.toLowerCase().includes(q)));
});
const hasSelected = computed(() => selectedElms.value.length > 0) const hasSelected = computed(() => selectedElms.value.length > 0)
const hasQueuedItems = computed(() => stateStore.count('queue') > 0) const hasQueuedItems = computed(() => stateStore.count('queue') > 0)

View file

@ -11,6 +11,19 @@
<div class="is-pulled-right" v-if="socket.isConnected"> <div class="is-pulled-right" v-if="socket.isConnected">
<div class="field is-grouped"> <div class="field is-grouped">
<p class="control has-icons-left" v-if="toggleFilter">
<input type="search" v-model.lazy="query" class="input" id="filter"
placeholder="Filter displayed content">
<span class="icon is-left"><i class="fas fa-filter" /></span>
</p>
<p class="control">
<button class="button is-danger is-light" v-tooltip.bottom="'Filter'"
@click="toggleFilter = !toggleFilter">
<span class="icon"><i class="fas fa-filter" /></span>
</button>
</p>
<p class="control" v-if="!config.app.basic_mode && false === config.app.basic_mode"> <p class="control" v-if="!config.app.basic_mode && false === config.app.basic_mode">
<button class="button is-warning" @click="pauseDownload" v-if="false === config.paused" <button class="button is-warning" @click="pauseDownload" v-if="false === config.paused"
v-tooltip.bottom="'Pause non-active downloads.'"> v-tooltip.bottom="'Pause non-active downloads.'">
@ -49,10 +62,11 @@
<NewDownload v-if="config.showForm || config.app.basic_mode" @getInfo="url => get_info = url" :item="item_form" <NewDownload v-if="config.showForm || config.app.basic_mode" @getInfo="url => get_info = url" :item="item_form"
@clear_form="item_form = {}" @remove_archive="" /> @clear_form="item_form = {}" @remove_archive="" />
<Queue @getInfo="(url: string) => view_info(url, false)" :thumbnails="show_thumbnail" <Queue @getInfo="(url: string) => view_info(url, false)" :thumbnails="show_thumbnail" :query="query"
@getItemInfo="(id: string) => view_info(`/api/history/${id}`, true)" /> @getItemInfo="(id: string) => view_info(`/api/history/${id}`, true)" @clear_search="query = ''" />
<History @getInfo="(url: string) => view_info(url, false)" @add_new="item => toNewDownload(item)" <History @getInfo="(url: string) => view_info(url, false)" @add_new="item => toNewDownload(item)" :query="query"
:thumbnails="show_thumbnail" @getItemInfo="(id: string) => view_info(`/api/history/${id}`, true)" /> :thumbnails="show_thumbnail" @getItemInfo="(id: string) => view_info(`/api/history/${id}`, true)"
@clear_search="query = ''" />
<GetInfo v-if="get_info" :link="get_info" :useUrl="get_info_use_url" @closeModel="close_info()" /> <GetInfo v-if="get_info" :link="get_info" :useUrl="get_info_use_url" @closeModel="close_info()" />
</div> </div>
</template> </template>
@ -64,15 +78,22 @@ const config = useConfigStore()
const stateStore = useStateStore() const stateStore = useStateStore()
const socket = useSocketStore() const socket = useSocketStore()
const box = useConfirm() const box = useConfirm()
const get_info = ref<string>('')
const get_info_use_url = ref<boolean>(false)
const bg_enable = useStorage<boolean>('random_bg', true) const bg_enable = useStorage<boolean>('random_bg', true)
const bg_opacity = useStorage<number>('random_bg_opacity', 0.85) const bg_opacity = useStorage<number>('random_bg_opacity', 0.85)
const display_style = useStorage<string>('display_style', 'cards') const display_style = useStorage<string>('display_style', 'cards')
const show_thumbnail = useStorage<boolean>('show_thumbnail', true) const show_thumbnail = useStorage<boolean>('show_thumbnail', true)
const get_info = ref<string>('')
const get_info_use_url = ref<boolean>(false)
const item_form = ref({}) const item_form = ref({})
const query = ref()
const toggleFilter = ref(false)
watch(toggleFilter, () => {
if (!toggleFilter.value) {
query.value = ''
}
});
onMounted(() => { onMounted(() => {
if (!config.app.ui_update_title) { if (!config.app.ui_update_title) {