feat: enhance floating mini timer with controls and pop-out button

MiniTimer shows project color dot, name, elapsed time, stop button,
and expand-to-main button. Timer.vue has pop-out button when running.
This commit is contained in:
Your Name
2026-02-18 10:46:25 +02:00
parent 5ac890aad4
commit bd3e0ba5a6

View File

@@ -1,27 +1,55 @@
<template>
<div class="mini-timer flex items-center justify-center h-screen bg-bg-base select-none" style="-webkit-app-region: drag">
<div class="text-center">
<p class="text-[2rem] font-medium font-[family-name:var(--font-heading)] tracking-tighter text-text-primary">
{{ timerStore.formattedTime }}
</p>
<p v-if="projectName" class="text-[0.6875rem] text-text-tertiary mt-1 truncate max-w-[180px]">
{{ projectName }}
</p>
</div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { invoke } from '@tauri-apps/api/core'
import { useTimerStore } from '../stores/timer'
import { useProjectsStore } from '../stores/projects'
import { Square, Maximize2 } from 'lucide-vue-next'
const timerStore = useTimerStore()
const projectsStore = useProjectsStore()
const projectName = computed(() => {
if (!timerStore.selectedProjectId) return ''
const project = projectsStore.projects.find(p => p.id === timerStore.selectedProjectId)
return project?.name || ''
if (!timerStore.selectedProjectId) return 'No project'
return projectsStore.projects.find(p => p.id === timerStore.selectedProjectId)?.name || 'Unknown'
})
const projectColor = computed(() => {
if (!timerStore.selectedProjectId) return '#6B7280'
return projectsStore.projects.find(p => p.id === timerStore.selectedProjectId)?.color || '#6B7280'
})
async function stopTimer() {
await timerStore.stop()
}
async function expandToMain() {
try {
await invoke('close_mini_timer')
} catch (e) {
console.error(e)
}
}
</script>
<template>
<div class="h-full w-full flex items-center gap-3 px-4 bg-bg-base select-none" style="-webkit-app-region: drag">
<span class="w-2.5 h-2.5 rounded-full shrink-0" :style="{ backgroundColor: projectColor }" />
<span class="text-[0.75rem] text-text-primary truncate flex-1">{{ projectName }}</span>
<span class="text-[1rem] font-mono text-accent-text font-medium tracking-tight">{{ timerStore.formattedTime }}</span>
<div class="flex items-center gap-1" style="-webkit-app-region: no-drag">
<button
v-if="timerStore.isRunning"
@click="stopTimer"
class="w-6 h-6 flex items-center justify-center rounded-full bg-status-error hover:bg-status-error/80 transition-colors"
>
<Square class="w-2.5 h-2.5 text-white" fill="white" />
</button>
<button
@click="expandToMain"
class="w-6 h-6 flex items-center justify-center rounded text-text-tertiary hover:text-text-secondary transition-colors"
>
<Maximize2 class="w-3 h-3" />
</button>
</div>
</div>
</template>