mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-10-03 20:20:30 +00:00
restyle connection banner as floating pill and fix focus reconnect
This commit is contained in:
@@ -1,35 +1,51 @@
|
||||
<template>
|
||||
<BaseBanner
|
||||
v-if="!isOnline"
|
||||
:text="$t('globals.messages.noInternetConnection')"
|
||||
color-class="bg-warning text-warning-foreground"
|
||||
/>
|
||||
<BaseBanner
|
||||
v-else-if="connectionFailed"
|
||||
:text="$t('globals.messages.connectionFailedRefresh')"
|
||||
color-class="bg-destructive text-destructive-foreground"
|
||||
/>
|
||||
<BaseBanner
|
||||
v-else-if="showReconnecting"
|
||||
:text="$t('globals.messages.connecting')"
|
||||
color-class="bg-warning text-warning-foreground"
|
||||
/>
|
||||
<div
|
||||
v-if="banner"
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
aria-atomic="true"
|
||||
class="fixed top-3 left-1/2 -translate-x-1/2 z-50 flex items-center gap-2 rounded-full px-4 py-1.5 text-sm shadow-md"
|
||||
:class="banner.colorClass"
|
||||
>
|
||||
<div class="w-2 h-2 rounded-full bg-current animate-pulse"></div>
|
||||
{{ banner.text }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch, onUnmounted } from 'vue'
|
||||
import { ref, computed, watch, onUnmounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useOnline } from '@vueuse/core'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useConnectionStore } from '@/stores/connection'
|
||||
import BaseBanner from '@shared-ui/components/BaseBanner.vue'
|
||||
|
||||
const RECONNECTING_DELAY_MS = 1500
|
||||
|
||||
const { t } = useI18n()
|
||||
const isOnline = useOnline()
|
||||
const { connecting, connectionFailed } = storeToRefs(useConnectionStore())
|
||||
const showReconnecting = ref(false)
|
||||
let reconnectingTimer = null
|
||||
|
||||
const banner = computed(() => {
|
||||
if (!isOnline.value)
|
||||
return {
|
||||
text: t('globals.messages.noInternetConnection'),
|
||||
colorClass: 'bg-warning text-warning-foreground'
|
||||
}
|
||||
if (connectionFailed.value)
|
||||
return {
|
||||
text: t('globals.messages.connectionFailedRefresh'),
|
||||
colorClass: 'bg-destructive text-destructive-foreground'
|
||||
}
|
||||
if (showReconnecting.value)
|
||||
return {
|
||||
text: t('globals.messages.connecting'),
|
||||
colorClass: 'bg-warning text-warning-foreground'
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
// Most drops recover on the first retry, so hold the banner back instead of flashing it.
|
||||
watch(connecting, (value) => {
|
||||
clearTimeout(reconnectingTimer)
|
||||
|
||||
@@ -2,14 +2,9 @@ import { ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useConnectionStore = defineStore('connection', () => {
|
||||
const connected = ref(false)
|
||||
const connecting = ref(false)
|
||||
const connectionFailed = ref(false)
|
||||
|
||||
const setConnected = (value) => {
|
||||
connected.value = value
|
||||
}
|
||||
|
||||
const setConnecting = (value) => {
|
||||
connecting.value = value
|
||||
}
|
||||
@@ -19,11 +14,9 @@ export const useConnectionStore = defineStore('connection', () => {
|
||||
}
|
||||
|
||||
return {
|
||||
connected,
|
||||
connecting,
|
||||
connectionFailed,
|
||||
|
||||
setConnected,
|
||||
setConnecting,
|
||||
setConnectionFailed
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ export class WebSocketClient {
|
||||
this.reconnectInterval = 1000
|
||||
this.reconnectAttempts = 0
|
||||
this.isReconnecting = false
|
||||
this.connectionStore.setConnected(true)
|
||||
this.connectionStore.setConnecting(false)
|
||||
this.connectionStore.setConnectionFailed(false)
|
||||
this.lastPong = Date.now()
|
||||
@@ -155,7 +154,6 @@ export class WebSocketClient {
|
||||
reconnect () {
|
||||
if (this.isReconnecting) return
|
||||
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
||||
this.connectionStore.setConnected(false)
|
||||
this.connectionStore.setConnecting(false)
|
||||
this.connectionStore.setConnectionFailed(true)
|
||||
return
|
||||
@@ -164,7 +162,6 @@ export class WebSocketClient {
|
||||
this.isReconnecting = true
|
||||
this.reconnectAttempts++
|
||||
|
||||
this.connectionStore.setConnected(false)
|
||||
this.connectionStore.setConnecting(true)
|
||||
// The online listener resets the attempt counter, so a retry can follow a give up.
|
||||
this.connectionStore.setConnectionFailed(false)
|
||||
@@ -195,6 +192,8 @@ export class WebSocketClient {
|
||||
|
||||
window.addEventListener('focus', () => {
|
||||
if (this.socket?.readyState !== WebSocket.OPEN) {
|
||||
this.reconnectAttempts = 0
|
||||
this.reconnectInterval = 1000
|
||||
this.reconnect()
|
||||
}
|
||||
})
|
||||
@@ -322,7 +321,6 @@ export class WebSocketClient {
|
||||
close () {
|
||||
this.manualClose = true
|
||||
this.clearPing()
|
||||
this.connectionStore.setConnected(false)
|
||||
this.connectionStore.setConnecting(false)
|
||||
this.connectionStore.setConnectionFailed(false)
|
||||
if (this.socket) {
|
||||
|
||||
Reference in New Issue
Block a user