Add plausible
This commit is contained in:
parent
3193c509a7
commit
0e3067db19
5 changed files with 90 additions and 3 deletions
53
src/analytics.ts
Normal file
53
src/analytics.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import {
|
||||
init as plausibleInit,
|
||||
track as plausibleTrack,
|
||||
type PlausibleEventOptions,
|
||||
} from '@plausible-analytics/tracker';
|
||||
|
||||
const ANALYTICS_AUTO_CAPTURE_PAGEVIEWS = true;
|
||||
const ANALYTICS_DOMAIN = 'schmelczer.dev/photos';
|
||||
const ANALYTICS_ENDPOINT = 'https://stats.schmelczer.dev/status';
|
||||
const ANALYTICS_LOGGING = import.meta.env.DEV;
|
||||
|
||||
let isInitialized = false;
|
||||
|
||||
const track = (eventName: string, options: PlausibleEventOptions = {}) => {
|
||||
try {
|
||||
plausibleTrack(eventName, options);
|
||||
} catch (error) {
|
||||
console.warn(`Could not track analytics event "${eventName}".`, error);
|
||||
}
|
||||
};
|
||||
|
||||
export const initAnalytics = () => {
|
||||
if (isInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
plausibleInit({
|
||||
domain: ANALYTICS_DOMAIN,
|
||||
endpoint: ANALYTICS_ENDPOINT,
|
||||
autoCapturePageviews: ANALYTICS_AUTO_CAPTURE_PAGEVIEWS,
|
||||
logging: ANALYTICS_LOGGING,
|
||||
});
|
||||
isInitialized = true;
|
||||
} catch (error) {
|
||||
console.warn('Could not initialize analytics.', error);
|
||||
}
|
||||
};
|
||||
|
||||
export const trackPhotoView = ({
|
||||
photoId,
|
||||
source,
|
||||
}: {
|
||||
photoId: string;
|
||||
source: string;
|
||||
}) => {
|
||||
track('Photo View', {
|
||||
props: {
|
||||
photoId,
|
||||
source,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
import './index.scss';
|
||||
import { initAnalytics, trackPhotoView } from './analytics';
|
||||
import { PhotoGallery, requiredElement } from './photos';
|
||||
|
||||
document.documentElement.classList.add('js');
|
||||
|
||||
initAnalytics();
|
||||
|
||||
const gallery = requiredElement<HTMLElement>('#gallery', HTMLElement);
|
||||
const frame = requiredElement<HTMLElement>('#frame-content', HTMLElement);
|
||||
const toggle = requiredElement<HTMLButtonElement>(
|
||||
|
|
@ -14,4 +17,5 @@ new PhotoGallery({
|
|||
gallery,
|
||||
frame,
|
||||
toggle,
|
||||
onSelect: trackPhotoView,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ type GalleryOptions = {
|
|||
readonly frame: HTMLElement;
|
||||
readonly toggle: HTMLButtonElement;
|
||||
readonly autoAdvance?: boolean;
|
||||
readonly onSelect?: (info: { photoId: string; source: string }) => void;
|
||||
};
|
||||
|
||||
type SelectOptions = {
|
||||
readonly focusThumbnail?: boolean;
|
||||
readonly pause?: boolean;
|
||||
readonly source?: string;
|
||||
};
|
||||
|
||||
export const requiredElement = <T extends Element>(
|
||||
|
|
@ -118,7 +120,10 @@ export class PhotoGallery {
|
|||
}
|
||||
|
||||
event.preventDefault();
|
||||
this.selectById(thumbnail.dataset.photoId, { pause: true });
|
||||
this.selectById(thumbnail.dataset.photoId, {
|
||||
pause: true,
|
||||
source: 'thumbnail',
|
||||
});
|
||||
});
|
||||
|
||||
this.options.gallery.addEventListener('keydown', (event) => {
|
||||
|
|
@ -128,6 +133,7 @@ export class PhotoGallery {
|
|||
this.select(this.selectedIndex - 1, {
|
||||
focusThumbnail: true,
|
||||
pause: true,
|
||||
source: 'keyboard',
|
||||
});
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
|
|
@ -135,17 +141,23 @@ export class PhotoGallery {
|
|||
this.select(this.selectedIndex + 1, {
|
||||
focusThumbnail: true,
|
||||
pause: true,
|
||||
source: 'keyboard',
|
||||
});
|
||||
break;
|
||||
case 'Home':
|
||||
event.preventDefault();
|
||||
this.select(0, { focusThumbnail: true, pause: true });
|
||||
this.select(0, {
|
||||
focusThumbnail: true,
|
||||
pause: true,
|
||||
source: 'keyboard',
|
||||
});
|
||||
break;
|
||||
case 'End':
|
||||
event.preventDefault();
|
||||
this.select(this.thumbnails.length - 1, {
|
||||
focusThumbnail: true,
|
||||
pause: true,
|
||||
source: 'keyboard',
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
|
@ -202,6 +214,15 @@ export class PhotoGallery {
|
|||
if (options.pause) {
|
||||
this.pauseAutoAdvance();
|
||||
}
|
||||
|
||||
// Only user-initiated selections carry a source; auto-advance stays
|
||||
// untracked so the slideshow doesn't flood analytics every few seconds.
|
||||
if (options.source) {
|
||||
this.options.onSelect?.({
|
||||
photoId: thumbnail.dataset.photoId ?? '',
|
||||
source: options.source,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private updateSelectedThumbnail(index: number, shouldFocus: boolean): void {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue