feat: global shortcut for quick entry dialog
This commit is contained in:
20
src/App.vue
20
src/App.vue
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, watch } from 'vue'
|
import { onMounted, ref, watch } from 'vue'
|
||||||
import { invoke } from '@tauri-apps/api/core'
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
import TitleBar from './components/TitleBar.vue'
|
import TitleBar from './components/TitleBar.vue'
|
||||||
import NavRail from './components/NavRail.vue'
|
import NavRail from './components/NavRail.vue'
|
||||||
@@ -16,6 +16,7 @@ import type { SoundEvent } from './utils/audio'
|
|||||||
import TourOverlay from './components/TourOverlay.vue'
|
import TourOverlay from './components/TourOverlay.vue'
|
||||||
import RecurringPromptDialog from './components/RecurringPromptDialog.vue'
|
import RecurringPromptDialog from './components/RecurringPromptDialog.vue'
|
||||||
import TimerSaveDialog from './components/TimerSaveDialog.vue'
|
import TimerSaveDialog from './components/TimerSaveDialog.vue'
|
||||||
|
import QuickEntryDialog from './components/QuickEntryDialog.vue'
|
||||||
import { useOnboardingStore } from './stores/onboarding'
|
import { useOnboardingStore } from './stores/onboarding'
|
||||||
import { useProjectsStore } from './stores/projects'
|
import { useProjectsStore } from './stores/projects'
|
||||||
import { useInvoicesStore } from './stores/invoices'
|
import { useInvoicesStore } from './stores/invoices'
|
||||||
@@ -24,6 +25,7 @@ const settingsStore = useSettingsStore()
|
|||||||
const recurringStore = useRecurringStore()
|
const recurringStore = useRecurringStore()
|
||||||
const timerStore = useTimerStore()
|
const timerStore = useTimerStore()
|
||||||
const { announcement } = useAnnouncer()
|
const { announcement } = useAnnouncer()
|
||||||
|
const showQuickEntry = ref(false)
|
||||||
|
|
||||||
function getProjectName(projectId?: number): string {
|
function getProjectName(projectId?: number): string {
|
||||||
if (!projectId) return ''
|
if (!projectId) return ''
|
||||||
@@ -59,6 +61,15 @@ async function registerShortcuts() {
|
|||||||
await win.show()
|
await win.show()
|
||||||
await win.setFocus()
|
await win.setFocus()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const quickEntryKey = settingsStore.settings.shortcut_quick_entry || 'CmdOrCtrl+Shift+N'
|
||||||
|
await register(quickEntryKey, async () => {
|
||||||
|
const { getCurrentWindow } = await import('@tauri-apps/api/window')
|
||||||
|
const win = getCurrentWindow()
|
||||||
|
await win.show()
|
||||||
|
await win.setFocus()
|
||||||
|
showQuickEntry.value = true
|
||||||
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to register shortcuts:', e)
|
console.error('Failed to register shortcuts:', e)
|
||||||
}
|
}
|
||||||
@@ -215,7 +226,7 @@ watch(() => settingsStore.settings.ui_font, (newFont) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => [settingsStore.settings.shortcut_toggle_timer, settingsStore.settings.shortcut_show_app], () => {
|
watch(() => [settingsStore.settings.shortcut_toggle_timer, settingsStore.settings.shortcut_show_app, settingsStore.settings.shortcut_quick_entry], () => {
|
||||||
registerShortcuts()
|
registerShortcuts()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -284,6 +295,11 @@ watch(() => settingsStore.settings.persistent_notifications, (val) => {
|
|||||||
@discard="timerStore.handleSaveDialogDiscard"
|
@discard="timerStore.handleSaveDialogDiscard"
|
||||||
@cancel="timerStore.handleSaveDialogCancel"
|
@cancel="timerStore.handleSaveDialogCancel"
|
||||||
/>
|
/>
|
||||||
|
<QuickEntryDialog
|
||||||
|
:show="showQuickEntry"
|
||||||
|
@close="showQuickEntry = false"
|
||||||
|
@saved="showQuickEntry = false"
|
||||||
|
/>
|
||||||
<div id="route-announcer" class="sr-only" aria-live="polite" aria-atomic="true"></div>
|
<div id="route-announcer" class="sr-only" aria-live="polite" aria-atomic="true"></div>
|
||||||
<div id="announcer" class="sr-only" aria-live="assertive" aria-atomic="true">{{ announcement }}</div>
|
<div id="announcer" class="sr-only" aria-live="assertive" aria-atomic="true">{{ announcement }}</div>
|
||||||
<TourOverlay />
|
<TourOverlay />
|
||||||
|
|||||||
@@ -570,6 +570,18 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p class="text-[0.8125rem] text-text-primary">Quick Entry</p>
|
||||||
|
<p class="text-[0.6875rem] text-text-tertiary mt-0.5">Open quick entry dialog from anywhere</p>
|
||||||
|
</div>
|
||||||
|
<AppShortcutRecorder
|
||||||
|
:model-value="shortcutQuickEntry"
|
||||||
|
@update:model-value="(v: string) => { shortcutQuickEntry = v; saveShortcutSettings() }"
|
||||||
|
label="Quick entry shortcut"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Divider -->
|
<!-- Divider -->
|
||||||
<div class="border-t border-border-subtle" />
|
<div class="border-t border-border-subtle" />
|
||||||
|
|
||||||
@@ -1414,6 +1426,7 @@ const themeMode = ref('dark')
|
|||||||
const accentColor = ref('amber')
|
const accentColor = ref('amber')
|
||||||
const shortcutToggleTimer = ref('CmdOrCtrl+Shift+T')
|
const shortcutToggleTimer = ref('CmdOrCtrl+Shift+T')
|
||||||
const shortcutShowApp = ref('CmdOrCtrl+Shift+Z')
|
const shortcutShowApp = ref('CmdOrCtrl+Shift+Z')
|
||||||
|
const shortcutQuickEntry = ref('CmdOrCtrl+Shift+N')
|
||||||
const timelineRecording = ref(false)
|
const timelineRecording = ref(false)
|
||||||
const timerFont = ref('JetBrains Mono')
|
const timerFont = ref('JetBrains Mono')
|
||||||
const timerFontOptions = TIMER_FONTS
|
const timerFontOptions = TIMER_FONTS
|
||||||
@@ -1779,6 +1792,7 @@ async function saveUIFontSetting() {
|
|||||||
async function saveShortcutSettings() {
|
async function saveShortcutSettings() {
|
||||||
await settingsStore.updateSetting('shortcut_toggle_timer', shortcutToggleTimer.value)
|
await settingsStore.updateSetting('shortcut_toggle_timer', shortcutToggleTimer.value)
|
||||||
await settingsStore.updateSetting('shortcut_show_app', shortcutShowApp.value)
|
await settingsStore.updateSetting('shortcut_show_app', shortcutShowApp.value)
|
||||||
|
await settingsStore.updateSetting('shortcut_quick_entry', shortcutQuickEntry.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save timer font setting
|
// Save timer font setting
|
||||||
@@ -2124,6 +2138,7 @@ onMounted(async () => {
|
|||||||
accentColor.value = settingsStore.settings.accent_color || 'amber'
|
accentColor.value = settingsStore.settings.accent_color || 'amber'
|
||||||
shortcutToggleTimer.value = settingsStore.settings.shortcut_toggle_timer || 'CmdOrCtrl+Shift+T'
|
shortcutToggleTimer.value = settingsStore.settings.shortcut_toggle_timer || 'CmdOrCtrl+Shift+T'
|
||||||
shortcutShowApp.value = settingsStore.settings.shortcut_show_app || 'CmdOrCtrl+Shift+Z'
|
shortcutShowApp.value = settingsStore.settings.shortcut_show_app || 'CmdOrCtrl+Shift+Z'
|
||||||
|
shortcutQuickEntry.value = settingsStore.settings.shortcut_quick_entry || 'CmdOrCtrl+Shift+N'
|
||||||
dailyGoalHours.value = parseFloat(settingsStore.settings.daily_goal_hours) || 8
|
dailyGoalHours.value = parseFloat(settingsStore.settings.daily_goal_hours) || 8
|
||||||
weeklyGoalHours.value = parseFloat(settingsStore.settings.weekly_goal_hours) || 40
|
weeklyGoalHours.value = parseFloat(settingsStore.settings.weekly_goal_hours) || 40
|
||||||
roundingEnabled.value = settingsStore.settings.rounding_enabled === 'true'
|
roundingEnabled.value = settingsStore.settings.rounding_enabled === 'true'
|
||||||
|
|||||||
Reference in New Issue
Block a user