Files
browser-wakatime/src/wakatimeScript.ts
2023-08-28 19:01:47 -05:00

86 lines
2.0 KiB
TypeScript

const twoMinutes = 120000;
interface DesignProject {
category: string;
editor: string;
language: string;
project: string;
}
const parseCanva = (): DesignProject | undefined => {
const projectName = (document.head.querySelector('meta[property="og:title"]') as HTMLMetaElement)
.content;
if (!projectName) return;
// make sure the page title matches the design input element's value, meaning this is a design file
const canvaProjectInput = Array.from(
document.querySelector('nav')?.querySelectorAll('input') ?? [],
).find((inp) => inp.value === projectName);
if (!canvaProjectInput) return;
return {
category: 'designing',
editor: 'Canva',
language: 'Canva Design',
project: projectName,
};
};
const parseFigma = (): DesignProject | undefined => {
const figmaProject = document.getElementsByClassName('gpu-view-content');
if (figmaProject.length === 0) return;
const projectName = (document.querySelector('span[data-testid="filename"]') as HTMLElement)
.innerText;
return {
category: 'designing',
editor: 'Figma',
language: 'Figma Design',
project: projectName,
};
};
const getParser: {
[key: string]:
| (() => { editor: string; language: string; project: string } | undefined)
| undefined;
} = {
'www.canva.com': parseCanva,
'www.figma.com': parseFigma,
};
const init = async () => {
const { hostname } = document.location;
const projectDetails = getParser[hostname]?.();
if (projectDetails) {
chrome.runtime.sendMessage({ projectDetails, recordHeartbeat: true });
}
};
function debounce(func: () => void, timeout = twoMinutes) {
let timer: NodeJS.Timeout | undefined;
return () => {
if (timer) {
return;
}
func();
timer = setTimeout(() => {
clearTimeout(timer);
timer = undefined;
}, timeout);
};
}
document.body.addEventListener(
'click',
debounce(() => init()),
true,
);
document.body.addEventListener(
'keypress',
debounce(() => init()),
true,
);