added the ability to reconnect

This commit is contained in:
arabcoders 2025-10-05 18:37:37 +03:00
parent 74103f3e56
commit d51ca37ace
4 changed files with 88 additions and 8 deletions

View 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>

View file

@ -6,8 +6,9 @@
<label class="label" for="download-url">
What you would like to download?
<span class="is-pulled-right">
<span class="icon has-text-primary is-pointer" @click="$emit('show_settings')" v-tooltip="'WebUI Settings'"><i
class="fas fa-cogs" /></span>
<span class="icon is-pointer" :class="connectionStatusColor" @click="$emit('show_settings')"
v-tooltip="'WebUI Settings'">
<i class="fas fa-cogs" /></span>
</span>
</label>
<div class="field has-addons">
@ -542,6 +543,18 @@ const showMessage = (item: StoreItem) => {
}
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>
<style scoped>

View file

@ -1,6 +1,7 @@
<template>
<template v-if="simpleMode">
<Connection :status="socket.connectionStatus" @reconnect="() => socket.reconnect()" />
<Simple @show_settings="() => show_settings = true" />
</template>
@ -15,14 +16,18 @@
<Shutdown v-if="app_shutdown" />
<div id="main_container" class="container" v-else>
<NewVersion v-if="newVersionIsAvailable" />
<Connection :status="socket.connectionStatus" @reconnect="() => socket.reconnect()" />
<nav class="navbar is-mobile is-dark">
<div class="navbar-brand pl-5">
<NuxtLink class="navbar-item is-text-overflow" to="/" @click.prevent="(e: MouseEvent) => changeRoute(e)"
v-tooltip="socket.isConnected ? 'Connected' : 'Connecting'">
<span class="is-text-overflow">
<span class="icon"><i class="fas fa-home" /></span>
<span class="has-text-bold" :class="`has-text-${socket.isConnected ? 'success' : 'danger'}`">
<span class="icon">
<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
</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 Shutdown from '~/components/shutdown.vue'
import Markdown from '~/components/Markdown.vue'
import Connection from '~/components/Connection.vue'
const Year = new Date().getFullYear()
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>

View file

@ -2,6 +2,8 @@ import { io, type Socket as IOSocket, type SocketOptions, type ManagerOptions }
import type { ConfigState } from "~/types/config";
import type { StoreItem } from "~/types/store";
export type connectionStatus = 'connected' | 'disconnected' | 'connecting';
export const useSocketStore = defineStore('socket', () => {
const runtimeConfig = useRuntimeConfig()
const config = useConfigStore()
@ -10,6 +12,7 @@ export const useSocketStore = defineStore('socket', () => {
const socket = ref<IOSocket | null>(null)
const isConnected = ref<boolean>(false)
const connectionStatus = ref<connectionStatus>('disconnected')
const emit = (event: string, data?: any): any => socket.value?.emit(event, data)
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));
}
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 opts = {
transports: ['websocket', 'polling'],
@ -44,10 +65,18 @@ export const useSocketStore = defineStore('socket', () => {
window.ws = socket.value;
}
connectionStatus.value = 'connecting';
socket.value = io(url, opts)
socket.value.on('connect', () => isConnected.value = true);
socket.value.on('disconnect', () => isConnected.value = false);
socket.value.on('connect', () => {
isConnected.value = true
connectionStatus.value = 'connected';
});
socket.value.on('disconnect', () => {
isConnected.value = false
connectionStatus.value = 'disconnected';
});
socket.value.on('connected', stream => {
const json = JSON.parse(stream)
@ -187,6 +216,10 @@ export const useSocketStore = defineStore('socket', () => {
connect();
}
return { connect, on, off, emit, socket, isConnected };
return {
connect, reconnect, disconnect,
on, off, emit,
socket, isConnected,
connectionStatus: readonly(connectionStatus) as Readonly<Ref<connectionStatus>>,
};
});