initial commit: wwcompanion v1
This commit is contained in:
148
settings.js
Normal file
148
settings.js
Normal file
@@ -0,0 +1,148 @@
|
||||
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");
|
||||
|
||||
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 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 = [] } =
|
||||
await getStorage(["apiKey", "model", "systemPrompt", "resume", "tasks"]);
|
||||
|
||||
apiKeyInput.value = apiKey;
|
||||
modelInput.value = model;
|
||||
systemPromptInput.value = systemPrompt;
|
||||
resumeInput.value = resume;
|
||||
|
||||
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
|
||||
});
|
||||
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";
|
||||
});
|
||||
|
||||
loadSettings();
|
||||
Reference in New Issue
Block a user