Files
wwcompanion/settings.js

166 lines
4.8 KiB
JavaScript

const apiKeyInput = document.getElementById("apiKey");
const modelInput = document.getElementById("model");
const systemPromptInput = document.getElementById("systemPrompt");
const resumeInput = document.getElementById("resume");
const saveBtn = document.getElementById("saveBtn");
const addTaskBtn = document.getElementById("addTaskBtn");
const tasksContainer = document.getElementById("tasks");
const statusEl = document.getElementById("status");
const toggleKeyBtn = document.getElementById("toggleKey");
const themeSelect = document.getElementById("themeSelect");
function getStorage(keys) {
return new Promise((resolve) => chrome.storage.local.get(keys, resolve));
}
function setStatus(message) {
statusEl.textContent = message;
if (!message) return;
setTimeout(() => {
if (statusEl.textContent === message) statusEl.textContent = "";
}, 2000);
}
function applyTheme(theme) {
const value = theme || "system";
document.documentElement.dataset.theme = value;
}
function newTaskId() {
if (crypto?.randomUUID) return crypto.randomUUID();
return `task-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`;
}
function buildTaskCard(task) {
const card = document.createElement("div");
card.className = "task-card";
card.dataset.id = task.id || newTaskId();
const nameField = document.createElement("div");
nameField.className = "field";
const nameLabel = document.createElement("label");
nameLabel.textContent = "Name";
const nameInput = document.createElement("input");
nameInput.type = "text";
nameInput.value = task.name || "";
nameInput.className = "task-name";
nameField.appendChild(nameLabel);
nameField.appendChild(nameInput);
const textField = document.createElement("div");
textField.className = "field";
const textLabel = document.createElement("label");
textLabel.textContent = "Task prompt";
const textArea = document.createElement("textarea");
textArea.rows = 6;
textArea.value = task.text || "";
textArea.className = "task-text";
textField.appendChild(textLabel);
textField.appendChild(textArea);
const actions = document.createElement("div");
actions.className = "task-actions";
const duplicateBtn = document.createElement("button");
duplicateBtn.type = "button";
duplicateBtn.className = "ghost";
duplicateBtn.textContent = "Duplicate";
const deleteBtn = document.createElement("button");
deleteBtn.type = "button";
deleteBtn.className = "ghost";
deleteBtn.textContent = "Delete";
duplicateBtn.addEventListener("click", () => {
const copy = {
id: newTaskId(),
name: `${nameInput.value || "Untitled"} Copy`,
text: textArea.value
};
const newCard = buildTaskCard(copy);
card.insertAdjacentElement("afterend", newCard);
});
deleteBtn.addEventListener("click", () => {
card.remove();
});
actions.appendChild(duplicateBtn);
actions.appendChild(deleteBtn);
card.appendChild(nameField);
card.appendChild(textField);
card.appendChild(actions);
return card;
}
function collectTasks() {
const cards = [...tasksContainer.querySelectorAll(".task-card")];
return cards.map((card) => {
const nameInput = card.querySelector(".task-name");
const textArea = card.querySelector(".task-text");
return {
id: card.dataset.id || newTaskId(),
name: (nameInput?.value || "Untitled Task").trim(),
text: (textArea?.value || "").trim()
};
});
}
async function loadSettings() {
const {
apiKey = "",
model = "",
systemPrompt = "",
resume = "",
tasks = [],
theme = "system"
} = await getStorage(["apiKey", "model", "systemPrompt", "resume", "tasks", "theme"]);
apiKeyInput.value = apiKey;
modelInput.value = model;
systemPromptInput.value = systemPrompt;
resumeInput.value = resume;
themeSelect.value = theme;
applyTheme(theme);
tasksContainer.innerHTML = "";
if (!tasks.length) {
tasksContainer.appendChild(
buildTaskCard({ id: newTaskId(), name: "", text: "" })
);
return;
}
for (const task of tasks) {
tasksContainer.appendChild(buildTaskCard(task));
}
}
async function saveSettings() {
const tasks = collectTasks();
await chrome.storage.local.set({
apiKey: apiKeyInput.value.trim(),
model: modelInput.value.trim(),
systemPrompt: systemPromptInput.value,
resume: resumeInput.value,
tasks,
theme: themeSelect.value
});
setStatus("Saved.");
}
saveBtn.addEventListener("click", () => void saveSettings());
addTaskBtn.addEventListener("click", () => {
tasksContainer.appendChild(buildTaskCard({ id: newTaskId(), name: "", text: "" }));
});
toggleKeyBtn.addEventListener("click", () => {
const isPassword = apiKeyInput.type === "password";
apiKeyInput.type = isPassword ? "text" : "password";
toggleKeyBtn.textContent = isPassword ? "Hide" : "Show";
});
themeSelect.addEventListener("change", () => applyTheme(themeSelect.value));
loadSettings();