mirror of
https://github.com/koel/koel
synced 2024-12-01 00:09:17 +00:00
feat: notify when app comes offline (#1561)
This commit is contained in:
parent
cadc2d1d92
commit
260152b417
5 changed files with 69 additions and 1 deletions
|
@ -3,6 +3,7 @@
|
|||
<DialogBox ref="dialog"/>
|
||||
<MessageToaster ref="toaster"/>
|
||||
<GlobalEventListeners/>
|
||||
<OfflineNotification v-if="offline"/>
|
||||
|
||||
<div v-if="authenticated" id="main" @dragend="onDragEnd" @dragover="onDragOver" @drop="onDrop">
|
||||
<Hotkeys/>
|
||||
|
@ -29,10 +30,12 @@ import { eventBus, hideOverlay, requireInjection, showOverlay } from '@/utils'
|
|||
import { commonStore, preferenceStore as preferences, queueStore } from '@/stores'
|
||||
import { authService, playbackService, socketListener, socketService, uploadService } from '@/services'
|
||||
import { CurrentSongKey, DialogBoxKey, MessageToasterKey, RouterKey } from '@/symbols'
|
||||
import { useNetworkStatus } from '@/composables'
|
||||
|
||||
import DialogBox from '@/components/ui/DialogBox.vue'
|
||||
import MessageToaster from '@/components/ui/MessageToaster.vue'
|
||||
import Overlay from '@/components/ui/Overlay.vue'
|
||||
import OfflineNotification from '@/components/ui/OfflineNotification.vue'
|
||||
|
||||
// Do not dynamic-import app footer, as it contains the <audio> element
|
||||
// that is necessary to properly initialize the playService and equalizer.
|
||||
|
@ -59,6 +62,8 @@ const currentSong = ref<Song | null>(null)
|
|||
const authenticated = ref(false)
|
||||
const showDropZone = ref(false)
|
||||
|
||||
const { offline } = useNetworkStatus()
|
||||
|
||||
/**
|
||||
* Request for notification permission if it's not provided and the user is OK with notifications.
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { createApp } from 'vue'
|
||||
import { clickaway, focus, tooltip } from '@/directives'
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
|
||||
import { FontAwesomeIcon, FontAwesomeLayers } from '@fortawesome/vue-fontawesome'
|
||||
import { RouterKey } from '@/symbols'
|
||||
import { routes } from '@/config'
|
||||
import Router from '@/router'
|
||||
|
@ -9,6 +9,7 @@ import App from './App.vue'
|
|||
createApp(App)
|
||||
.provide(RouterKey, new Router(routes))
|
||||
.component('icon', FontAwesomeIcon)
|
||||
.component('icon-layers', FontAwesomeLayers)
|
||||
.directive('koel-focus', focus)
|
||||
.directive('koel-clickaway', clickaway)
|
||||
.directive('koel-tooltip', tooltip)
|
||||
|
|
40
resources/assets/js/components/ui/OfflineNotification.vue
Normal file
40
resources/assets/js/components/ui/OfflineNotification.vue
Normal file
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<div class="offline">
|
||||
<icon-layers fixed-width>
|
||||
<icon :icon="faWifi" fixed-width size="xl"/>
|
||||
<icon :icon="faSlash" fixed-width size="lg" transform="up-2"/>
|
||||
</icon-layers>
|
||||
<span class="text">You’re offline.</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { faSlash, faWifi } from '@fortawesome/free-solid-svg-icons'</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.offline {
|
||||
color: #ed5135;
|
||||
width: 144px;
|
||||
height: 42px;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
position: fixed;
|
||||
z-index: 10000;
|
||||
left: 1.6rem;
|
||||
|
||||
bottom: calc(var(--footer-height) + 1.2rem);
|
||||
box-shadow: 0 2px 30px rgba(0, 0, 0, .3);
|
||||
}
|
||||
|
||||
.text {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.fa-slash {
|
||||
filter: drop-shadow(0 2px 0 #fff);
|
||||
}
|
||||
</style>
|
|
@ -9,3 +9,4 @@ export * from './useDragAndDrop'
|
|||
export * from './useUpload'
|
||||
export * from './useScreen'
|
||||
export * from './usePlaylistManagement'
|
||||
export * from './useNetworkStatus'
|
||||
|
|
21
resources/assets/js/composables/useNetworkStatus.ts
Normal file
21
resources/assets/js/composables/useNetworkStatus.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { computed, onUnmounted, ref } from 'vue'
|
||||
|
||||
export const useNetworkStatus = () => {
|
||||
const online = ref(navigator.onLine)
|
||||
const offline = computed(() => !online.value)
|
||||
|
||||
const updateOnlineStatus = () => (online.value = navigator.onLine)
|
||||
|
||||
window.addEventListener('online', updateOnlineStatus)
|
||||
window.addEventListener('offline', updateOnlineStatus)
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('online', updateOnlineStatus)
|
||||
window.removeEventListener('offline', updateOnlineStatus)
|
||||
})
|
||||
|
||||
return {
|
||||
online,
|
||||
offline
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue