Reduce confirmation box usage with optional WebUI flag.
This commit is contained in:
parent
c13c4427a7
commit
0156052ab9
15 changed files with 213 additions and 150 deletions
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
|
|
@ -74,4 +74,13 @@
|
|||
"spellright.documentTypes": [
|
||||
"latex"
|
||||
],
|
||||
"search.exclude": {
|
||||
"ui/.nuxt": true,
|
||||
"ui/.output": true,
|
||||
"ui/dist": true,
|
||||
"ui/exported": true,
|
||||
"ui/node_modules": true,
|
||||
"ui/.out": true,
|
||||
"**/.venv": true,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
</label>
|
||||
<div class="control">
|
||||
<input type="text" class="input" id="name" v-model="form.name" :disabled="addInProgress"
|
||||
placeholder="For the problematic channel or video name.">
|
||||
placeholder="For the problematic channel or video name.">
|
||||
</div>
|
||||
<span class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
</label>
|
||||
<div class="control">
|
||||
<input type="text" class="input" id="filter" v-model="form.filter" :disabled="addInProgress"
|
||||
placeholder="availability = 'needs_auth' & channel_id = 'channel_id'">
|
||||
placeholder="availability = 'needs_auth' & channel_id = 'channel_id'">
|
||||
</div>
|
||||
<span class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
|
|
@ -150,6 +150,7 @@ const props = defineProps({
|
|||
})
|
||||
|
||||
const toast = useNotification()
|
||||
const box = useConfirm()
|
||||
const form = reactive(JSON.parse(JSON.stringify(props.item)))
|
||||
const import_string = ref('')
|
||||
const showImport = useStorage('showImport', false);
|
||||
|
|
@ -219,7 +220,7 @@ const importItem = async () => {
|
|||
return
|
||||
}
|
||||
|
||||
if ((form.filter || form.cli) && false === confirm('This will overwrite the current data. Are you sure?')) {
|
||||
if ((form.filter || form.cli) && false === box.confirm('This will overwrite the current data. Are you sure?', true)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -386,6 +386,7 @@ const config = useConfigStore()
|
|||
const stateStore = useStateStore()
|
||||
const socket = useSocketStore()
|
||||
const toast = useNotification()
|
||||
const box = useConfirm()
|
||||
|
||||
const selectedElms = ref([])
|
||||
const masterSelectAll = ref(false)
|
||||
|
|
@ -488,7 +489,7 @@ const deleteSelectedItems = () => {
|
|||
msg += '\nThis will delete the files from the server if they exist.'
|
||||
}
|
||||
|
||||
if (false === confirm(msg)) {
|
||||
if (false === box.confirm(msg, config.app.remove_files)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -506,7 +507,7 @@ const deleteSelectedItems = () => {
|
|||
|
||||
const clearCompleted = () => {
|
||||
let msg = 'Are you sure you want to clear all completed downloads?'
|
||||
if (false === confirm(msg)) {
|
||||
if (false === box.confirm(msg)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -518,7 +519,7 @@ const clearCompleted = () => {
|
|||
}
|
||||
|
||||
const clearIncomplete = () => {
|
||||
if (false === confirm('Are you sure you want to clear all in-complete downloads?')) {
|
||||
if (false === box.confirm('Are you sure you want to clear all in-complete downloads?')) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -598,7 +599,7 @@ const setStatus = item => {
|
|||
}
|
||||
|
||||
const requeueIncomplete = () => {
|
||||
if (false === confirm('Are you sure you want to re-queue all incomplete downloads?')) {
|
||||
if (false === box.confirm('Are you sure you want to re-queue all incomplete downloads?')) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -612,7 +613,7 @@ const requeueIncomplete = () => {
|
|||
}
|
||||
|
||||
const archiveItem = item => {
|
||||
if (!confirm(`Archive '${item.title ?? item.id ?? item.url ?? '??'}'?`)) {
|
||||
if (!box.confirm(`Archive '${item.title ?? item.id ?? item.url ?? '??'}'?`)) {
|
||||
return
|
||||
}
|
||||
socket.emit('archive_item', item)
|
||||
|
|
@ -621,7 +622,7 @@ const archiveItem = item => {
|
|||
|
||||
const removeItem = item => {
|
||||
const msg = `Remove '${item.title ?? item.id ?? item.url ?? '??'}'?\n this will delete the file from the server.`
|
||||
if (config.app.remove_files && !confirm(msg)) {
|
||||
if (false === box.confirm(msg, config.app.remove_files)) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ const emitter = defineEmits(['getInfo', 'clear_form'])
|
|||
const config = useConfigStore()
|
||||
const socket = useSocketStore()
|
||||
const toast = useNotification()
|
||||
const box = useConfirm()
|
||||
|
||||
const showAdvanced = useStorage('show_advanced', false)
|
||||
const addInProgress = ref(false)
|
||||
|
|
@ -261,7 +262,7 @@ const addDownload = async () => {
|
|||
}
|
||||
|
||||
const resetConfig = () => {
|
||||
if (true !== confirm('Reset your local configuration?')) {
|
||||
if (true !== box.confirm('Reset your local configuration?')) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -295,6 +295,7 @@ const requestMethods = ['POST', 'PUT'];
|
|||
const requestType = ['json', 'form'];
|
||||
const showImport = useStorage('showImport', false);
|
||||
const import_string = ref('');
|
||||
const box = useConfirm()
|
||||
|
||||
const checkInfo = async () => {
|
||||
const required = ['name', 'request.url', 'request.method', 'request.type', 'request.data_key'];
|
||||
|
|
@ -331,7 +332,6 @@ const checkInfo = async () => {
|
|||
emitter('submit', { reference: toRaw(props.reference), item: toRaw(form) });
|
||||
}
|
||||
|
||||
|
||||
const importItem = async () => {
|
||||
let val = import_string.value.trim()
|
||||
if (!val) {
|
||||
|
|
@ -359,7 +359,7 @@ const importItem = async () => {
|
|||
}
|
||||
|
||||
if (form.target) {
|
||||
if (false === confirm('This will overwrite the current form fields. Are you sure?')) {
|
||||
if (false === box.confirm('This will overwrite the current form fields. Are you sure?', true)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,7 +221,8 @@ const config = useConfigStore()
|
|||
const toast = useNotification()
|
||||
const form = reactive(JSON.parse(JSON.stringify(props.preset)))
|
||||
const import_string = ref('')
|
||||
const showImport = useStorage('showImport', false);
|
||||
const showImport = useStorage('showImport', false)
|
||||
const box = useConfirm()
|
||||
|
||||
onMounted(() => {
|
||||
if (props.preset?.cli && '' !== props.preset?.cli) {
|
||||
|
|
@ -328,7 +329,7 @@ const importItem = async () => {
|
|||
return
|
||||
}
|
||||
|
||||
if (form.cli && false === confirm('This will overwrite the current data. Are you sure?')) {
|
||||
if (form.cli && false === box.confirm('This will overwrite the current data. Are you sure?', true)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -235,12 +235,13 @@ import { ucFirst } from '~/utils/index'
|
|||
import { isEmbedable, getEmbedable } from '~/utils/embedable'
|
||||
|
||||
const emitter = defineEmits(['getInfo'])
|
||||
const config = useConfigStore();
|
||||
const stateStore = useStateStore();
|
||||
const socket = useSocketStore();
|
||||
const config = useConfigStore()
|
||||
const stateStore = useStateStore()
|
||||
const socket = useSocketStore()
|
||||
const box = useConfirm()
|
||||
|
||||
const selectedElms = ref([]);
|
||||
const masterSelectAll = ref(false);
|
||||
const selectedElms = ref([])
|
||||
const masterSelectAll = ref(false)
|
||||
const showQueue = useStorage('showQueue', true)
|
||||
const hideThumbnail = useStorage('hideThumbnailQueue', false)
|
||||
const display_style = useStorage('display_style', 'cards')
|
||||
|
|
@ -252,11 +253,11 @@ const bg_opacity = useStorage('random_bg_opacity', 0.85)
|
|||
|
||||
watch(masterSelectAll, (value) => {
|
||||
for (const key in stateStore.queue) {
|
||||
const element = stateStore.queue[key];
|
||||
const element = stateStore.queue[key]
|
||||
if (value) {
|
||||
selectedElms.value.push(element._id);
|
||||
selectedElms.value.push(element._id)
|
||||
} else {
|
||||
selectedElms.value = [];
|
||||
selectedElms.value = []
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -266,35 +267,35 @@ const hasQueuedItems = computed(() => stateStore.count('queue') > 0)
|
|||
|
||||
const setIcon = item => {
|
||||
if ('downloading' === item.status && item.is_live) {
|
||||
return 'fa-globe fa-spin';
|
||||
return 'fa-globe fa-spin'
|
||||
}
|
||||
|
||||
if ('downloading' === item.status) {
|
||||
return 'fa-download';
|
||||
return 'fa-download'
|
||||
}
|
||||
|
||||
if ('postprocessing' === item.status) {
|
||||
return 'fa-cog fa-spin';
|
||||
return 'fa-cog fa-spin'
|
||||
}
|
||||
|
||||
if (null === item.status && true === config.paused) {
|
||||
return 'fa-pause-circle';
|
||||
return 'fa-pause-circle'
|
||||
}
|
||||
|
||||
if (!item.status) {
|
||||
return 'fa-question';
|
||||
return 'fa-question'
|
||||
}
|
||||
|
||||
return 'fa-spinner fa-spin';
|
||||
return 'fa-spinner fa-spin'
|
||||
}
|
||||
|
||||
const setStatus = item => {
|
||||
if (null === item.status && true === config.paused) {
|
||||
return 'Paused';
|
||||
return 'Paused'
|
||||
}
|
||||
|
||||
if ('downloading' === item.status && item.is_live) {
|
||||
return 'Live Streaming';
|
||||
return 'Live Streaming'
|
||||
}
|
||||
|
||||
if ('preparing' === item.status) {
|
||||
|
|
@ -302,7 +303,7 @@ const setStatus = item => {
|
|||
}
|
||||
|
||||
if (!item.status) {
|
||||
return 'Unknown..';
|
||||
return 'Unknown..'
|
||||
}
|
||||
|
||||
return ucFirst(item.status)
|
||||
|
|
@ -324,84 +325,82 @@ const setIconColor = item => {
|
|||
return ''
|
||||
}
|
||||
|
||||
|
||||
|
||||
const ETAPipe = value => {
|
||||
if (value === null || 0 === value) {
|
||||
return 'Live';
|
||||
return 'Live'
|
||||
}
|
||||
if (value < 60) {
|
||||
return `${Math.round(value)}s`;
|
||||
return `${Math.round(value)}s`
|
||||
}
|
||||
if (value < 3600) {
|
||||
return `${Math.floor(value / 60)}m ${Math.round(value % 60)}s`;
|
||||
return `${Math.floor(value / 60)}m ${Math.round(value % 60)}s`
|
||||
}
|
||||
const hours = Math.floor(value / 3600)
|
||||
const minutes = value % 3600
|
||||
return `${hours}h ${Math.floor(minutes / 60)}m ${Math.round(minutes % 60)}s`;
|
||||
return `${hours}h ${Math.floor(minutes / 60)}m ${Math.round(minutes % 60)}s`
|
||||
}
|
||||
|
||||
const speedPipe = value => {
|
||||
if (null === value || 0 === value) {
|
||||
return '0KB/s';
|
||||
return '0KB/s'
|
||||
}
|
||||
|
||||
const k = 1024;
|
||||
const dm = 2;
|
||||
const sizes = ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s', 'EB/s', 'ZB/s', 'YB/s'];
|
||||
const i = Math.floor(Math.log(value) / Math.log(k));
|
||||
return parseFloat((value / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||
const k = 1024
|
||||
const dm = 2
|
||||
const sizes = ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s', 'EB/s', 'ZB/s', 'YB/s']
|
||||
const i = Math.floor(Math.log(value) / Math.log(k))
|
||||
return parseFloat((value / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
|
||||
}
|
||||
|
||||
const percentPipe = value => {
|
||||
if (value === null || 0 === value) {
|
||||
return '00.00';
|
||||
return '00.00'
|
||||
}
|
||||
return parseFloat(value).toFixed(2);
|
||||
return parseFloat(value).toFixed(2)
|
||||
}
|
||||
|
||||
const updateProgress = (item) => {
|
||||
let string = '';
|
||||
let string = ''
|
||||
|
||||
if (null === item.status && true === config.paused) {
|
||||
return 'Paused';
|
||||
return 'Paused'
|
||||
}
|
||||
|
||||
if ('postprocessing' === item.status) {
|
||||
return 'Post-processors are running.';
|
||||
return 'Post-processors are running.'
|
||||
}
|
||||
|
||||
if ('preparing' === item.status) {
|
||||
return ag(item, 'extras.external_downloader') ? 'External downloader.' : 'Preparing';
|
||||
return ag(item, 'extras.external_downloader') ? 'External downloader.' : 'Preparing'
|
||||
}
|
||||
|
||||
if (null != item.status) {
|
||||
string += item.percent && !item.is_live ? percentPipe(item.percent) + '%' : 'Live';
|
||||
string += item.percent && !item.is_live ? percentPipe(item.percent) + '%' : 'Live'
|
||||
}
|
||||
|
||||
string += item.speed ? ' - ' + speedPipe(item.speed) : ' - Waiting..';
|
||||
string += item.speed ? ' - ' + speedPipe(item.speed) : ' - Waiting..'
|
||||
|
||||
if (null != item.status && item.eta) {
|
||||
string += ' - ' + ETAPipe(item.eta);
|
||||
string += ' - ' + ETAPipe(item.eta)
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
const confirmCancel = item => {
|
||||
if (true !== confirm(`Are you sure you want to cancel (${item.title})?`)) {
|
||||
return false;
|
||||
if (true !== box.confirm(`Are you sure you want to cancel (${item.title})?`)) {
|
||||
return false
|
||||
}
|
||||
cancelItems(item._id);
|
||||
return true;
|
||||
cancelItems(item._id)
|
||||
return true
|
||||
}
|
||||
|
||||
const cancelSelected = () => {
|
||||
if (true !== confirm('Are you sure you want to cancel selected items?')) {
|
||||
if (true !== box.confirm('Are you sure you want to cancel selected items?')) {
|
||||
return false;
|
||||
}
|
||||
cancelItems(selectedElms.value);
|
||||
selectedElms.value = [];
|
||||
cancelItems(selectedElms.value)
|
||||
selectedElms.value = []
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -410,20 +409,21 @@ const cancelItems = item => {
|
|||
|
||||
if (typeof item === 'object') {
|
||||
for (const key in item) {
|
||||
items.push(item[key]);
|
||||
items.push(item[key])
|
||||
}
|
||||
} else {
|
||||
items.push(item);
|
||||
items.push(item)
|
||||
}
|
||||
|
||||
if (items.length < 0) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
items.forEach(id => socket.emit('item_cancel', id));
|
||||
items.forEach(id => socket.emit('item_cancel', id))
|
||||
}
|
||||
|
||||
const pImg = e => e.target.naturalHeight > e.target.naturalWidth ? e.target.classList.add('image-portrait') : null
|
||||
|
||||
watch(embed_url, v => {
|
||||
if (!bg_enable.value) {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -9,71 +9,93 @@
|
|||
</span>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="field">
|
||||
<label class="label" for="random_bg">Color scheme</label>
|
||||
<div class="control">
|
||||
<label for="auto" class="radio">
|
||||
<input id="auto" type="radio" v-model="selectedTheme" value="auto">
|
||||
System Default
|
||||
</label>
|
||||
<label for="light" class="radio">
|
||||
<input id="light" type="radio" v-model="selectedTheme" value="light">
|
||||
Light
|
||||
</label>
|
||||
<label for="dark" class="radio">
|
||||
<input id="dark" type="radio" v-model="selectedTheme" value="dark">
|
||||
Dark
|
||||
</label>
|
||||
</div>
|
||||
<p class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>Select the color scheme for the WebUI.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-6">
|
||||
<div class="field">
|
||||
<label class="label" for="random_bg">Color scheme</label>
|
||||
<div class="control">
|
||||
<label for="auto" class="radio">
|
||||
<input id="auto" type="radio" v-model="selectedTheme" value="auto">
|
||||
System Default
|
||||
</label>
|
||||
<label for="light" class="radio">
|
||||
<input id="light" type="radio" v-model="selectedTheme" value="light">
|
||||
Light
|
||||
</label>
|
||||
<label for="dark" class="radio">
|
||||
<input id="dark" type="radio" v-model="selectedTheme" value="dark">
|
||||
Dark
|
||||
</label>
|
||||
</div>
|
||||
<p class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>Select the color scheme for the WebUI.</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="random_bg">Backgrounds</label>
|
||||
<div class="control">
|
||||
<input id="random_bg" type="checkbox" class="switch is-success" v-model="bg_enable">
|
||||
<label for="random_bg" class="is-unselectable"> Enable</label>
|
||||
</div>
|
||||
<p class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>Use random background image.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="random_bg">Backgrounds</label>
|
||||
<div class="control">
|
||||
<input id="random_bg" type="checkbox" class="switch is-success" v-model="bg_enable">
|
||||
<label for="random_bg" class="is-unselectable"> Enable</label>
|
||||
</div>
|
||||
<p class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>
|
||||
Use random background image.
|
||||
<NuxtLink @click="$emit('reload_bg')" class="is-bold" v-if="bg_enable">
|
||||
Reload
|
||||
</NuxtLink>
|
||||
<span class="icon" v-if="isLoading"><i class="fa fa-spin fa-spinner" /></span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="label" for="random_bg_opacity">
|
||||
Background Visibility: (<code>{{ bg_opacity }}</code>)
|
||||
</label>
|
||||
<div class="control">
|
||||
<input id="random_bg_opacity" style="width: 100%" type="range" v-model="bg_opacity" min="0.50" max="1.00"
|
||||
step="0.05">
|
||||
<div class="field">
|
||||
<label class="label" for="random_bg_opacity">
|
||||
Background Visibility: (<code>{{ bg_opacity }}</code>)
|
||||
</label>
|
||||
<div class="control">
|
||||
<input id="random_bg_opacity" style="width: 100%" type="range" v-model="bg_opacity" min="0.50"
|
||||
max="1.00" step="0.05">
|
||||
</div>
|
||||
<p class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>How visible the background image should be.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>How visible the background image should be.</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<div class="field">
|
||||
<label class="label" for="reduce_confirm">Reduce confirm box usage</label>
|
||||
<div class="control">
|
||||
<input id="reduce_confirm" type="checkbox" class="switch is-success" v-model="reduce_confirm">
|
||||
<label for="reduce_confirm" class="is-unselectable">
|
||||
{{ reduce_confirm ? 'Enabled' : 'Disabled' }}
|
||||
</label>
|
||||
</div>
|
||||
<p class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>Reduce the usage of confirm boxes in the WebUI.</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field" v-if="bg_enable">
|
||||
<label class="label" for="random_bg_opacity">
|
||||
Reload the currently displayed background image.
|
||||
</label>
|
||||
<div class="control">
|
||||
<button class="button is-info" @click="$emit('reload_bg')" :class="{ 'is-loading': isLoading }"
|
||||
:disabled="isLoading">
|
||||
<span class="icon-text">
|
||||
<span class="icon"><i class="fas fa-sync-alt" /></span>
|
||||
<span>Reload</span>
|
||||
</span>
|
||||
</button>
|
||||
<div class="field">
|
||||
<label class="label" for="allow_toasts">Show notification toasts</label>
|
||||
<div class="control">
|
||||
<input id="allow_toasts" type="checkbox" class="switch is-success" v-model="allow_toasts">
|
||||
<label for="allow_toasts" class="is-unselectable">
|
||||
{{ allow_toasts ? 'Enabled' : 'Disabled' }}
|
||||
</label>
|
||||
</div>
|
||||
<p class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span class="has-text-danger is-bold">
|
||||
Show notification toasts. If disabled, you will not see errors reported or anything else.
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>Change the displayed picture.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -96,5 +118,7 @@ defineProps({
|
|||
const bg_enable = useStorage('random_bg', true)
|
||||
const bg_opacity = useStorage('random_bg_opacity', 0.85)
|
||||
const selectedTheme = useStorage('theme', 'auto')
|
||||
const allow_toasts = useStorage('allow_toasts', true)
|
||||
const reduce_confirm = useStorage('reduce_confirm', false)
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -232,11 +232,12 @@
|
|||
import { useStorage } from '@vueuse/core'
|
||||
import { CronExpressionParser } from 'cron-parser'
|
||||
|
||||
const emitter = defineEmits(['cancel', 'submit']);
|
||||
const toast = useNotification();
|
||||
const config = useConfigStore();
|
||||
const showImport = useStorage('showImport', false);
|
||||
const import_string = ref('');
|
||||
const emitter = defineEmits(['cancel', 'submit'])
|
||||
const toast = useNotification()
|
||||
const config = useConfigStore()
|
||||
const showImport = useStorage('showImport', false)
|
||||
const import_string = ref('')
|
||||
const box = useConfirm()
|
||||
|
||||
const props = defineProps({
|
||||
reference: {
|
||||
|
|
@ -255,49 +256,49 @@ const props = defineProps({
|
|||
},
|
||||
})
|
||||
|
||||
const form = reactive(props.task);
|
||||
const form = reactive(props.task)
|
||||
|
||||
onMounted(() => {
|
||||
if (!props.task?.preset || '' === props.task.preset) {
|
||||
form.preset = toRaw(config.app.default_preset);
|
||||
form.preset = toRaw(config.app.default_preset)
|
||||
}
|
||||
})
|
||||
|
||||
const checkInfo = async () => {
|
||||
const required = ['name', 'url'];
|
||||
const required = ['name', 'url']
|
||||
for (const key of required) {
|
||||
if (!form[key]) {
|
||||
toast.error(`The ${key} field is required.`);
|
||||
return;
|
||||
toast.error(`The ${key} field is required.`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (form.timer) {
|
||||
try {
|
||||
CronExpressionParser.parse(form.timer);
|
||||
CronExpressionParser.parse(form.timer)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
toast.error(`Invalid CRON expression. ${e.message}`);
|
||||
return;
|
||||
toast.error(`Invalid CRON expression. ${e.message}`)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
new URL(form.url);
|
||||
new URL(form.url)
|
||||
} catch (e) {
|
||||
toast.error('Invalid URL');
|
||||
return;
|
||||
toast.error('Invalid URL')
|
||||
return
|
||||
}
|
||||
|
||||
if (form?.cli && '' !== form.cli) {
|
||||
const options = await convertOptions(form.cli);
|
||||
const options = await convertOptions(form.cli)
|
||||
if (null === options) {
|
||||
return
|
||||
}
|
||||
form.cli = form.cli.trim(" ")
|
||||
}
|
||||
|
||||
emitter('submit', { reference: toRaw(props.reference), task: toRaw(form) });
|
||||
emitter('submit', { reference: toRaw(props.reference), task: toRaw(form) })
|
||||
}
|
||||
|
||||
const importItem = async () => {
|
||||
|
|
@ -327,7 +328,7 @@ const importItem = async () => {
|
|||
}
|
||||
|
||||
if (form.url || form.timer) {
|
||||
if (false === confirm('This will overwrite the current form fields. Are you sure?')) {
|
||||
if (false === box.confirm('This will overwrite the current form fields. Are you sure?', true)) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
@ -391,7 +392,7 @@ const convertOptions = async args => {
|
|||
toast.error(e.message)
|
||||
}
|
||||
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
|
||||
const hasFormatInConfig = computed(() => {
|
||||
|
|
|
|||
19
ui/composables/useConfirm.ts
Normal file
19
ui/composables/useConfirm.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { useStorage } from '@vueuse/core'
|
||||
|
||||
const reduceConfirm = useStorage<boolean>('reduce_confirm', false)
|
||||
|
||||
function confirm(msg: string, force: boolean = false): boolean {
|
||||
if (false === force && true === reduceConfirm.value) {
|
||||
return true
|
||||
}
|
||||
|
||||
return window.confirm(msg)
|
||||
}
|
||||
|
||||
function alert(msg: string): boolean {
|
||||
return window.confirm(msg)
|
||||
}
|
||||
|
||||
export default function useConfirm() {
|
||||
return { confirm, alert, reduceConfirm }
|
||||
}
|
||||
|
|
@ -116,6 +116,7 @@ import { request } from '~/utils/index'
|
|||
const toast = useNotification()
|
||||
const config = useConfigStore()
|
||||
const socket = useSocketStore()
|
||||
const box = useConfirm()
|
||||
|
||||
const items = ref([])
|
||||
const item = ref({})
|
||||
|
|
@ -213,7 +214,7 @@ const updateItems = async items => {
|
|||
}
|
||||
|
||||
const deleteItem = async (item) => {
|
||||
if (true !== confirm(`Delete '${item.name}'?`)) {
|
||||
if (true !== box.confirm(`Delete '${item.name}'?`, true)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ const emitter = defineEmits(['getInfo'])
|
|||
const config = useConfigStore()
|
||||
const stateStore = useStateStore()
|
||||
const socket = useSocketStore()
|
||||
const box = useConfirm()
|
||||
|
||||
const get_info = ref('')
|
||||
const bg_enable = useStorage('random_bg', true)
|
||||
const bg_opacity = useStorage('random_bg_opacity', 0.85)
|
||||
|
|
@ -91,7 +93,7 @@ watch(() => stateStore.queue, () => {
|
|||
}, { deep: true })
|
||||
|
||||
const pauseDownload = () => {
|
||||
if (false === confirm('Are you sure you want to pause all non-active downloads?')) {
|
||||
if (false === box.confirm('Are you sure you want to pause all non-active downloads?')) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ import { request } from '~/utils/index'
|
|||
const toast = useNotification()
|
||||
const config = useConfigStore()
|
||||
const socket = useSocketStore()
|
||||
const box = useConfirm()
|
||||
|
||||
const allowedEvents = ref([])
|
||||
const notifications = ref([])
|
||||
|
|
@ -234,7 +235,7 @@ const updateData = async notifications => {
|
|||
}
|
||||
|
||||
const deleteItem = async item => {
|
||||
if (true !== confirm(`Are you sure you want to delete notification target (${item.name})?`)) {
|
||||
if (true !== box.confirm(`Are you sure you want to delete notification target (${item.name})?`)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -294,7 +295,7 @@ const editItem = item => {
|
|||
const join_events = events => (!events || events.length < 1) ? 'ALL' : events.map(e => ucFirst(e)).join(', ')
|
||||
|
||||
const sendTest = async () => {
|
||||
if (true !== confirm('Are you sure you want to send a test notification?')) {
|
||||
if (true !== box.confirm('Are you sure you want to send a test notification?')) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ import { request } from '~/utils/index'
|
|||
const toast = useNotification()
|
||||
const config = useConfigStore()
|
||||
const socket = useSocketStore()
|
||||
const box = useConfirm()
|
||||
|
||||
const presets = ref([])
|
||||
const preset = ref({})
|
||||
|
|
@ -249,7 +250,7 @@ const updatePresets = async (items) => {
|
|||
}
|
||||
|
||||
const deleteItem = async (item) => {
|
||||
if (true !== confirm(`Delete preset '${item.name}'?`)) {
|
||||
if (true !== box.confirm(`Delete preset '${item.name}'?`, true)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ import { request } from '~/utils/index'
|
|||
const toast = useNotification()
|
||||
const config = useConfigStore()
|
||||
const socket = useSocketStore()
|
||||
const box = useConfirm()
|
||||
|
||||
const tasks = ref([])
|
||||
const task = ref({})
|
||||
|
|
@ -216,7 +217,7 @@ const updateTasks = async items => {
|
|||
}
|
||||
|
||||
const deleteItem = async item => {
|
||||
if (true !== confirm(`Are you sure you want to delete (${item.name})?`)) {
|
||||
if (true !== box.confirm(`Are you sure you want to delete (${item.name})?`, true)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -290,7 +291,7 @@ const tryParse = expression => {
|
|||
}
|
||||
|
||||
const runNow = item => {
|
||||
if (true !== confirm(`Run '${item.name}' now? it will also run at the scheduled time.`)) {
|
||||
if (true !== box.confirm(`Run '${item.name}' now? it will also run at the scheduled time.`)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue