Files
RenewCMS/web/src/components/OfflineBanner.vue
T

72 lines
1.6 KiB
Vue

<script setup lang="ts">
import { translate } from '@/i18n'
import { computed, onMounted, onUnmounted, ref } from 'vue'
const DEFAULT_MESSAGE =
"You're offline. You can keep writing, but saving and publishing will wait until you're back online."
const ROOMY_BLEED_ROOT = 'w-auto -mx-4 -mt-5 mb-5 lg:-mx-8 lg:-mt-8 lg:mb-8'
const BLEED_UI = {
root: 'w-auto -mx-4 -mt-4 mb-4 lg:-mx-6 lg:-mt-6 lg:mb-6',
container: 'h-auto min-h-10 max-w-none justify-start gap-2.5 px-4 py-2.5 sm:px-4 lg:px-4',
left: 'hidden lg:hidden',
icon: 'size-4',
title: 'whitespace-normal font-normal text-wrap',
}
const FLUSH_UI = { ...BLEED_UI, root: 'w-auto' }
const props = withDefaults(
defineProps<{
message?: string
icon?: string
bleed?: boolean
roomy?: boolean
flush?: boolean
}>(),
{
message: DEFAULT_MESSAGE,
icon: undefined,
bleed: false,
roomy: false,
flush: false,
},
)
const bleedUi = computed(() => (props.roomy ? { ...BLEED_UI, root: ROOMY_BLEED_ROOT } : BLEED_UI))
const bannerUi = computed(() => {
if (props.flush) {
return FLUSH_UI
}
return props.bleed ? bleedUi.value : undefined
})
const isOffline = ref(!navigator.onLine)
function updateOnlineStatus() {
isOffline.value = !navigator.onLine
}
onMounted(() => {
window.addEventListener('online', updateOnlineStatus)
window.addEventListener('offline', updateOnlineStatus)
})
onUnmounted(() => {
window.removeEventListener('online', updateOnlineStatus)
window.removeEventListener('offline', updateOnlineStatus)
})
</script>
<template>
<UBanner
v-if="isOffline"
color="neutral"
:icon="icon"
:title="translate(message)"
:ui="bannerUi"
/>
</template>