refactor(tracker): better tracker injection
This commit is contained in:
		
							parent
							
								
									bf88836dbe
								
							
						
					
					
						commit
						def60e7248
					
				| @ -1,24 +1,25 @@ | ||||
| <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 { searchResult } = useFuzzySearch({ | ||||
|   search: queryString, | ||||
|   data: tools, | ||||
|   options: { keys: [{ name: 'name', weight: 2 }, 'description', 'keywords'] }, | ||||
| }); | ||||
| 
 | ||||
| const toolToOption = (tool: Tool) => ({ label: tool.name, value: tool.path, tool }); | ||||
| 
 | ||||
| const router = useRouter(); | ||||
| const { tracker } = useTracker(); | ||||
| 
 | ||||
| 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 === '') { | ||||
|     return tools.map(toolToOption); | ||||
| @ -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)`" | ||||
|  | ||||
| @ -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" /> | ||||
|  | ||||
| @ -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, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
|       >. | ||||
|  | ||||
| @ -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); | ||||
|   }, | ||||
| }; | ||||
|  | ||||
							
								
								
									
										7
									
								
								src/shims.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								src/shims.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -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; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user