feat: simple extension setup
This commit is contained in:
46
src/content.ts
Normal file
46
src/content.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { State, STORAGE_KEY } from "./types";
|
||||
|
||||
const KEY_BINDINGS: Record<string, string> = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
let enabled = false;
|
||||
|
||||
const clickButton = (selector: string): void => {
|
||||
const el = document.querySelector<HTMLElement>(selector);
|
||||
el?.click();
|
||||
};
|
||||
|
||||
const onKeyDown = (event: KeyboardEvent): void => {
|
||||
if (!enabled) return;
|
||||
|
||||
const target = event.target as HTMLElement;
|
||||
if (
|
||||
target.tagName === "INPUT" ||
|
||||
target.tagName === "TEXTAREA" ||
|
||||
target.isContentEditable
|
||||
) return;
|
||||
|
||||
const selector = KEY_BINDINGS[event.code];
|
||||
if (selector) {
|
||||
event.preventDefault();
|
||||
clickButton(selector);
|
||||
}
|
||||
};
|
||||
|
||||
const init = async (): Promise<void> => {
|
||||
const result = await chrome.storage.local.get(STORAGE_KEY);
|
||||
const state = result[STORAGE_KEY] as State | undefined;
|
||||
enabled = state?.enabled ?? true;
|
||||
|
||||
document.addEventListener("keydown", onKeyDown);
|
||||
|
||||
chrome.storage.onChanged.addListener((changes) => {
|
||||
if (STORAGE_KEY in changes) {
|
||||
const next = changes[STORAGE_KEY].newValue as State;
|
||||
enabled = next.enabled;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
init();
|
||||
49
src/popup.css
Normal file
49
src/popup.css
Normal file
@@ -0,0 +1,49 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 320px;
|
||||
padding: 16px;
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
background: #0f1117;
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 0.95rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.02em;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 0.75rem;
|
||||
color: #94a3b8;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
#toggle {
|
||||
width: 100%;
|
||||
padding: 9px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
letter-spacing: 0.05em;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
#toggle.on {
|
||||
background: #22c55e;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#toggle.off {
|
||||
background: #3f3f46;
|
||||
color: #94a3b8;
|
||||
}
|
||||
13
src/popup.html
Normal file
13
src/popup.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>WoV Tweaks</title>
|
||||
<link rel="stylesheet" href="popup.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Assassins Convention Tweaks</h1>
|
||||
<button id="toggle"></button>
|
||||
<script src="../dist/popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
34
src/popup.ts
Normal file
34
src/popup.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { State, STORAGE_KEY } from "./types";
|
||||
|
||||
const DEFAULT_STATE: State = {
|
||||
enabled: true,
|
||||
};
|
||||
|
||||
const getState = async (): Promise<State> => {
|
||||
const result = await chrome.storage.local.get(STORAGE_KEY);
|
||||
return (result[STORAGE_KEY] as State | undefined) ?? DEFAULT_STATE;
|
||||
};
|
||||
|
||||
const setState = async (state: State): Promise<void> => {
|
||||
await chrome.storage.local.set({ [STORAGE_KEY]: state });
|
||||
};
|
||||
|
||||
const render = (btn: HTMLButtonElement, enabled: boolean): void => {
|
||||
btn.textContent = enabled ? "ON" : "OFF";
|
||||
btn.className = enabled ? "on" : "off";
|
||||
};
|
||||
|
||||
const init = async (): Promise<void> => {
|
||||
const btn = document.getElementById("toggle") as HTMLButtonElement;
|
||||
const state = await getState();
|
||||
render(btn, state.enabled);
|
||||
|
||||
btn.addEventListener("click", async () => {
|
||||
const current = await getState();
|
||||
const next = { enabled: !current.enabled };
|
||||
await setState(next);
|
||||
render(btn, next.enabled);
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", init);
|
||||
5
src/types.ts
Normal file
5
src/types.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export type State = {
|
||||
enabled: boolean;
|
||||
};
|
||||
|
||||
export const STORAGE_KEY = "wov_assassins_convention_tweaks_state";
|
||||
Reference in New Issue
Block a user