feat(time-tracking): add favicon indicator for active time tracking sessions (#2937)

This commit is contained in:
kolaente 2026-06-18 23:52:52 +02:00 committed by GitHub
parent 1e1e733c36
commit 9d18ba236f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -61,6 +61,7 @@ import {useAuthStore} from '@/stores/auth'
import {useBaseStore} from '@/stores/base'
import {useColorScheme} from '@/composables/useColorScheme'
import {useTimeTrackingFavicon} from '@/composables/useTimeTrackingFavicon'
import {useBodyClass} from '@/composables/useBodyClass'
import QuickAddOverlay from '@/components/quick-actions/QuickAddOverlay.vue'
import AddToHomeScreen from '@/components/home/AddToHomeScreen.vue'
@ -107,6 +108,7 @@ watch(accountDeletionConfirm, async (accountDeletionConfirm) => {
setLanguage(authStore.settings.language ?? DEFAULT_LANGUAGE)
useColorScheme()
useTimeTrackingFavicon()
</script>
<style src="@/styles/tailwind.css" />

View File

@ -0,0 +1,32 @@
import {watch} from 'vue'
import {createSharedComposable, tryOnMounted} from '@vueuse/core'
import {storeToRefs} from 'pinia'
import {useTimeTrackingStore} from '@/stores/timeTracking'
import {getFullBaseUrl} from '@/helpers/getFullBaseUrl'
const TRACKING_FAVICON = `${getFullBaseUrl()}images/icons/favicon-tracking-32x32.png`
function getFaviconLink(): HTMLLinkElement | null {
return document.querySelector<HTMLLinkElement>('link[rel="icon"]')
}
// Swaps in a favicon with a small red dot in the lower left corner while a timer
// is running, so an active time tracking session is visible even when the tab
// isn't focused.
export const useTimeTrackingFavicon = createSharedComposable(() => {
const {hasActiveTimer} = storeToRefs(useTimeTrackingStore())
const originalHref = getFaviconLink()?.getAttribute('href') ?? '/favicon.ico'
function update(active: boolean) {
const link = getFaviconLink()
if (link === null) {
return
}
link.href = active ? TRACKING_FAVICON : originalHref
}
watch(hasActiveTimer, update, {flush: 'post'})
tryOnMounted(() => update(hasActiveTimer.value))
})