added the ability to reconnect
This commit is contained in:
parent
74103f3e56
commit
d51ca37ace
4 changed files with 88 additions and 8 deletions
16
ui/app/components/Connection.vue
Normal file
16
ui/app/components/Connection.vue
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<template>
|
||||||
|
<Message message_class="p-2 m-2 is-success has-background-warning-90 has-text-dark" v-if="status === 'disconnected'">
|
||||||
|
<span class="icon"><i class="fas fa-info-circle" /></span>
|
||||||
|
<span>
|
||||||
|
Connection lost, <NuxtLink class="is-bold" @click.prevent="() => $emit('reconnect')">Click here</NuxtLink>
|
||||||
|
to reconnect.
|
||||||
|
</span>
|
||||||
|
</Message>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Message from '~/components/Message.vue'
|
||||||
|
import type { connectionStatus } from '~/stores/SocketStore'
|
||||||
|
defineProps<{ 'status': connectionStatus }>()
|
||||||
|
defineEmits<{ (e: "reconnect"): void }>()
|
||||||
|
</script>
|
||||||
|
|
@ -6,8 +6,9 @@
|
||||||
<label class="label" for="download-url">
|
<label class="label" for="download-url">
|
||||||
What you would like to download?
|
What you would like to download?
|
||||||
<span class="is-pulled-right">
|
<span class="is-pulled-right">
|
||||||
<span class="icon has-text-primary is-pointer" @click="$emit('show_settings')" v-tooltip="'WebUI Settings'"><i
|
<span class="icon is-pointer" :class="connectionStatusColor" @click="$emit('show_settings')"
|
||||||
class="fas fa-cogs" /></span>
|
v-tooltip="'WebUI Settings'">
|
||||||
|
<i class="fas fa-cogs" /></span>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
|
|
@ -542,6 +543,18 @@ const showMessage = (item: StoreItem) => {
|
||||||
}
|
}
|
||||||
return (item.msg?.length || 0) > 0
|
return (item.msg?.length || 0) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const connectionStatusColor = computed(() => {
|
||||||
|
switch (socketStore.connectionStatus) {
|
||||||
|
case 'connected':
|
||||||
|
return 'has-text-success'
|
||||||
|
case 'connecting':
|
||||||
|
return 'has-text-warning fa-spin'
|
||||||
|
case 'disconnected':
|
||||||
|
default:
|
||||||
|
return 'has-text-danger'
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<template v-if="simpleMode">
|
<template v-if="simpleMode">
|
||||||
|
<Connection :status="socket.connectionStatus" @reconnect="() => socket.reconnect()" />
|
||||||
<Simple @show_settings="() => show_settings = true" />
|
<Simple @show_settings="() => show_settings = true" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -15,14 +16,18 @@
|
||||||
<Shutdown v-if="app_shutdown" />
|
<Shutdown v-if="app_shutdown" />
|
||||||
<div id="main_container" class="container" v-else>
|
<div id="main_container" class="container" v-else>
|
||||||
<NewVersion v-if="newVersionIsAvailable" />
|
<NewVersion v-if="newVersionIsAvailable" />
|
||||||
|
<Connection :status="socket.connectionStatus" @reconnect="() => socket.reconnect()" />
|
||||||
<nav class="navbar is-mobile is-dark">
|
<nav class="navbar is-mobile is-dark">
|
||||||
|
|
||||||
<div class="navbar-brand pl-5">
|
<div class="navbar-brand pl-5">
|
||||||
<NuxtLink class="navbar-item is-text-overflow" to="/" @click.prevent="(e: MouseEvent) => changeRoute(e)"
|
<NuxtLink class="navbar-item is-text-overflow" to="/" @click.prevent="(e: MouseEvent) => changeRoute(e)"
|
||||||
v-tooltip="socket.isConnected ? 'Connected' : 'Connecting'">
|
v-tooltip="socket.isConnected ? 'Connected' : 'Connecting'">
|
||||||
<span class="is-text-overflow">
|
<span class="is-text-overflow">
|
||||||
<span class="icon"><i class="fas fa-home" /></span>
|
<span class="icon">
|
||||||
<span class="has-text-bold" :class="`has-text-${socket.isConnected ? 'success' : 'danger'}`">
|
<i v-if="'connecting' === socket.connectionStatus" class="fas fa-arrows-rotate fa-spin" />
|
||||||
|
<i v-else class="fas fa-home" />
|
||||||
|
</span>
|
||||||
|
<span class="has-text-bold" :class="connectionStatusColor">
|
||||||
YTPTube
|
YTPTube
|
||||||
</span>
|
</span>
|
||||||
<span class="has-text-bold" v-if="config?.app?.instance_title">: {{ config.app.instance_title }}</span>
|
<span class="has-text-bold" v-if="config?.app?.instance_title">: {{ config.app.instance_title }}</span>
|
||||||
|
|
@ -191,6 +196,7 @@ import Dialog from '~/components/Dialog.vue'
|
||||||
import Simple from '~/components/Simple.vue'
|
import Simple from '~/components/Simple.vue'
|
||||||
import Shutdown from '~/components/shutdown.vue'
|
import Shutdown from '~/components/shutdown.vue'
|
||||||
import Markdown from '~/components/Markdown.vue'
|
import Markdown from '~/components/Markdown.vue'
|
||||||
|
import Connection from '~/components/Connection.vue'
|
||||||
|
|
||||||
const Year = new Date().getFullYear()
|
const Year = new Date().getFullYear()
|
||||||
const selectedTheme = useStorage('theme', 'auto')
|
const selectedTheme = useStorage('theme', 'auto')
|
||||||
|
|
@ -470,4 +476,16 @@ const shutdownApp = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const connectionStatusColor = computed(() => {
|
||||||
|
switch (socket.connectionStatus) {
|
||||||
|
case 'connected':
|
||||||
|
return 'has-text-success'
|
||||||
|
case 'connecting':
|
||||||
|
return 'has-text-warning'
|
||||||
|
case 'disconnected':
|
||||||
|
default:
|
||||||
|
return 'has-text-danger'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import { io, type Socket as IOSocket, type SocketOptions, type ManagerOptions }
|
||||||
import type { ConfigState } from "~/types/config";
|
import type { ConfigState } from "~/types/config";
|
||||||
import type { StoreItem } from "~/types/store";
|
import type { StoreItem } from "~/types/store";
|
||||||
|
|
||||||
|
export type connectionStatus = 'connected' | 'disconnected' | 'connecting';
|
||||||
|
|
||||||
export const useSocketStore = defineStore('socket', () => {
|
export const useSocketStore = defineStore('socket', () => {
|
||||||
const runtimeConfig = useRuntimeConfig()
|
const runtimeConfig = useRuntimeConfig()
|
||||||
const config = useConfigStore()
|
const config = useConfigStore()
|
||||||
|
|
@ -10,6 +12,7 @@ export const useSocketStore = defineStore('socket', () => {
|
||||||
|
|
||||||
const socket = ref<IOSocket | null>(null)
|
const socket = ref<IOSocket | null>(null)
|
||||||
const isConnected = ref<boolean>(false)
|
const isConnected = ref<boolean>(false)
|
||||||
|
const connectionStatus = ref<connectionStatus>('disconnected')
|
||||||
|
|
||||||
const emit = (event: string, data?: any): any => socket.value?.emit(event, data)
|
const emit = (event: string, data?: any): any => socket.value?.emit(event, data)
|
||||||
const on = (event: string | string[], callback: (...args: any[]) => void, withEvent: boolean = false) => {
|
const on = (event: string | string[], callback: (...args: any[]) => void, withEvent: boolean = false) => {
|
||||||
|
|
@ -26,6 +29,24 @@ export const useSocketStore = defineStore('socket', () => {
|
||||||
event.forEach(e => socket.value?.off(e, callback));
|
event.forEach(e => socket.value?.off(e, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const reconnect = () => {
|
||||||
|
if (true === isConnected.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
connect();
|
||||||
|
connectionStatus.value = 'connecting';
|
||||||
|
}
|
||||||
|
|
||||||
|
const disconnect = () => {
|
||||||
|
if (null === socket.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
socket.value.disconnect();
|
||||||
|
socket.value = null;
|
||||||
|
isConnected.value = false;
|
||||||
|
connectionStatus.value = 'disconnected';
|
||||||
|
}
|
||||||
|
|
||||||
const connect = () => {
|
const connect = () => {
|
||||||
const opts = {
|
const opts = {
|
||||||
transports: ['websocket', 'polling'],
|
transports: ['websocket', 'polling'],
|
||||||
|
|
@ -44,10 +65,18 @@ export const useSocketStore = defineStore('socket', () => {
|
||||||
window.ws = socket.value;
|
window.ws = socket.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connectionStatus.value = 'connecting';
|
||||||
socket.value = io(url, opts)
|
socket.value = io(url, opts)
|
||||||
|
|
||||||
socket.value.on('connect', () => isConnected.value = true);
|
socket.value.on('connect', () => {
|
||||||
socket.value.on('disconnect', () => isConnected.value = false);
|
isConnected.value = true
|
||||||
|
connectionStatus.value = 'connected';
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.value.on('disconnect', () => {
|
||||||
|
isConnected.value = false
|
||||||
|
connectionStatus.value = 'disconnected';
|
||||||
|
});
|
||||||
|
|
||||||
socket.value.on('connected', stream => {
|
socket.value.on('connected', stream => {
|
||||||
const json = JSON.parse(stream)
|
const json = JSON.parse(stream)
|
||||||
|
|
@ -187,6 +216,10 @@ export const useSocketStore = defineStore('socket', () => {
|
||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
return { connect, on, off, emit, socket, isConnected };
|
connect, reconnect, disconnect,
|
||||||
|
on, off, emit,
|
||||||
|
socket, isConnected,
|
||||||
|
connectionStatus: readonly(connectionStatus) as Readonly<Ref<connectionStatus>>,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue