mirror of
				https://github.com/CorentinTh/it-tools.git
				synced 2025-11-04 02:47:00 -05:00 
			
		
		
		
	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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user