diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/SearchBar.vue | 64 | ||||
-rw-r--r-- | src/layouts/base.layout.vue | 5 | ||||
-rw-r--r-- | src/modules/tracker/tracker.services.ts | 18 | ||||
-rw-r--r-- | src/pages/About.vue | 4 | ||||
-rw-r--r-- | src/plugins/plausible.plugin.ts | 4 | ||||
-rw-r--r-- | src/shims.d.ts | 7 |
6 files changed, 66 insertions, 36 deletions
diff --git a/src/components/SearchBar.vue b/src/components/SearchBar.vue index dd63506..78d6fd7 100644 --- a/src/components/SearchBar.vue +++ b/src/components/SearchBar.vue @@ -1,23 +1,24 @@ <script lang="ts" setup> import { useFuzzySearch } from '@/composable/fuzzySearch'; +import { useTracker } from '@/modules/tracker/tracker.services'; import { tools } from '@/tools'; import type { Tool } from '@/tools/tools.types'; import { SearchRound } from '@vicons/material'; import { useMagicKeys, whenever } from '@vueuse/core'; +import type { NInput } from 'naive-ui'; import { computed, h, ref } from 'vue'; import { useRouter } from 'vue-router'; import SearchBarItem from './SearchBarItem.vue'; -const router = useRouter(); -const queryString = ref(''); +const toolToOption = (tool: Tool) => ({ label: tool.name, value: tool.path, tool }); -const { searchResult } = useFuzzySearch({ - search: queryString, - data: tools, - options: { keys: [{ name: 'name', weight: 2 }, 'description', 'keywords'] }, -}); +const router = useRouter(); +const { tracker } = useTracker(); -const toolToOption = (tool: Tool) => ({ label: tool.name, value: tool.path, tool }); +const queryString = ref(''); +const inputEl = ref<HTMLElement>(); +const displayDropDown = ref(true); +const isMac = computed(() => window.navigator.userAgent.toLowerCase().includes('mac')); const options = computed(() => { if (queryString.value === '') { @@ -27,12 +28,11 @@ const options = computed(() => { return searchResult.value.map(toolToOption); }); -function onSelect(path: string) { - router.push(path); - queryString.value = ''; -} - -const focusTarget = ref(); +const { searchResult } = useFuzzySearch({ + search: queryString, + data: tools, + options: { keys: [{ name: 'name', weight: 2 }, 'description', 'keywords'] }, +}); const keys = useMagicKeys({ passive: false, @@ -47,18 +47,33 @@ const keys = useMagicKeys({ }, }); -whenever(keys.ctrl_k, () => { - focusTarget.value.focus(); -}); -whenever(keys.meta_k, () => { - focusTarget.value.focus(); -}); +whenever(keys.ctrl_k, claimFocus); +whenever(keys.meta_k, claimFocus); +whenever(keys.escape, releaseFocus); function renderOption({ tool }: { tool: Tool }) { return h(SearchBarItem, { tool }); } -const isMac = computed(() => window.navigator.userAgent.toLowerCase().includes('mac')); +function onSelect(path: string) { + router.push(path); + queryString.value = ''; +} + +function claimFocus() { + displayDropDown.value = true; + + inputEl.value?.focus(); +} + +function releaseFocus() { + displayDropDown.value = false; +} + +function onFocus() { + tracker.trackEvent({ eventName: 'Search-bar focused' }); + displayDropDown.value = true; +} </script> <template> @@ -69,12 +84,13 @@ const isMac = computed(() => window.navigator.userAgent.toLowerCase().includes(' :on-select="(value) => onSelect(String(value))" :render-label="renderOption" :default-value="'aa'" - :get-show="() => true" - :on-focus="() => $tracker.trackEvent({ eventName: 'Search-bar focused' })" + :get-show="() => displayDropDown" + :on-focus="onFocus" + @update:value="() => (displayDropDown = true)" > <template #default="{ handleInput, handleBlur, handleFocus, value: slotValue }"> <n-input - ref="focusTarget" + ref="inputEl" round clearable :placeholder="`Search a tool (use ${isMac ? 'Cmd' : 'Ctrl'} + K to focus)`" diff --git a/src/layouts/base.layout.vue b/src/layouts/base.layout.vue index 5c050d3..4ee2997 100644 --- a/src/layouts/base.layout.vue +++ b/src/layouts/base.layout.vue @@ -9,6 +9,7 @@ import { config } from '@/config'; import MenuIconItem from '@/components/MenuIconItem.vue'; import type { Tool } from '@/tools/tools.types'; import { useToolStore } from '@/tools/tools.store'; +import { useTracker } from '@/modules/tracker/tracker.services'; import SearchBar from '../components/SearchBar.vue'; import HeroGradient from '../assets/hero-gradient.svg?component'; import MenuLayout from '../components/MenuLayout.vue'; @@ -23,6 +24,8 @@ const commitSha = config.app.lastCommitSha.slice(0, 7); const makeLabel = (tool: Tool) => () => h(RouterLink, { to: tool.path }, { default: () => tool.name }); const makeIcon = (tool: Tool) => () => h(MenuIconItem, { tool }); +const { tracker } = useTracker(); + const toolStore = useToolStore(); const menuOptions = computed<MenuGroupOption[]>(() => @@ -157,7 +160,7 @@ const menuOptions = computed<MenuGroupOption[]>(() => target="_blank" class="support-button" :bordered="false" - @click="() => $tracker.trackEvent({ eventName: 'Support button clicked' })" + @click="() => tracker.trackEvent({ eventName: 'Support button clicked' })" > Buy me a coffee <n-icon v-if="!styleStore.isSmallScreen" :component="Heart" style="margin-left: 5px" /> diff --git a/src/modules/tracker/tracker.services.ts b/src/modules/tracker/tracker.services.ts index c05dccc..bd3c0ec 100644 --- a/src/modules/tracker/tracker.services.ts +++ b/src/modules/tracker/tracker.services.ts @@ -1,6 +1,8 @@ +import _ from 'lodash'; import type Plausible from 'plausible-tracker'; +import { inject } from 'vue'; -export { createTrackerService }; +export { createTrackerService, useTracker }; function createTrackerService({ plausible }: { plausible: ReturnType<typeof Plausible> }) { return { @@ -9,3 +11,17 @@ function createTrackerService({ plausible }: { plausible: ReturnType<typeof Plau }, }; } + +function useTracker() { + const plausible: ReturnType<typeof Plausible> | undefined = inject('plausible'); + + if (_.isNil(plausible)) { + throw new Error('Plausible must be instantiated'); + } + + const tracker = createTrackerService({ plausible }); + + return { + tracker, + }; +} diff --git a/src/pages/About.vue b/src/pages/About.vue index ca717ff..c033e16 100644 --- a/src/pages/About.vue +++ b/src/pages/About.vue @@ -1,7 +1,9 @@ <script setup lang="ts"> +import { useTracker } from '@/modules/tracker/tracker.services'; import { useHead } from '@vueuse/head'; useHead({ title: 'About - IT Tools' }); +const { tracker } = useTracker(); </script> <template> @@ -25,7 +27,7 @@ useHead({ title: 'About - IT Tools' }); href="https://github.com/sponsors/CorentinTh" rel="noopener" target="_blank" - @click="() => $tracker.trackEvent({ eventName: 'Support button clicked' })" + @click="() => tracker.trackEvent({ eventName: 'Support button clicked' })" > sponsoring me </n-button >. diff --git a/src/plugins/plausible.plugin.ts b/src/plugins/plausible.plugin.ts index 04bb2a2..10975ea 100644 --- a/src/plugins/plausible.plugin.ts +++ b/src/plugins/plausible.plugin.ts @@ -1,5 +1,5 @@ import { config } from '@/config'; -import { createTrackerService } from '@/modules/tracker/tracker.services'; + import Plausible from 'plausible-tracker'; import type { App } from 'vue'; @@ -8,6 +8,6 @@ export const plausible = { const plausible = Plausible(config.plausible); plausible.enableAutoPageviews(); - app.config.globalProperties.$tracker = createTrackerService({ plausible }); + app.provide('plausible', plausible); }, }; diff --git a/src/shims.d.ts b/src/shims.d.ts index 34ae761..f8798e5 100644 --- a/src/shims.d.ts +++ b/src/shims.d.ts @@ -1,10 +1,3 @@ -import type { TrackerService } from './modules/tracker/tracker.types'; -declare module 'vue' { - interface ComponentCustomProperties { - $tracker: TrackerService; - } -} - declare module '*.vue' { import type { ComponentOptions, ComponentOptions } from 'vue'; const Component: ComponentOptions; |