UI/UX changes, added feature to switch to other LLM APIs
This commit is contained in:
108
settings.js
108
settings.js
@@ -1,4 +1,7 @@
|
||||
const apiKeyInput = document.getElementById("apiKey");
|
||||
const apiBaseUrlInput = document.getElementById("apiBaseUrl");
|
||||
const apiKeyHeaderInput = document.getElementById("apiKeyHeader");
|
||||
const apiKeyPrefixInput = document.getElementById("apiKeyPrefix");
|
||||
const modelInput = document.getElementById("model");
|
||||
const systemPromptInput = document.getElementById("systemPrompt");
|
||||
const resumeInput = document.getElementById("resume");
|
||||
@@ -8,6 +11,13 @@ const tasksContainer = document.getElementById("tasks");
|
||||
const statusEl = document.getElementById("status");
|
||||
const toggleKeyBtn = document.getElementById("toggleKey");
|
||||
const themeSelect = document.getElementById("themeSelect");
|
||||
const resetApiBtn = document.getElementById("resetApiBtn");
|
||||
|
||||
const OPENAI_DEFAULTS = {
|
||||
apiBaseUrl: "https://api.openai.com/v1",
|
||||
apiKeyHeader: "Authorization",
|
||||
apiKeyPrefix: "Bearer "
|
||||
};
|
||||
|
||||
function getStorage(keys) {
|
||||
return new Promise((resolve) => chrome.storage.local.get(keys, resolve));
|
||||
@@ -60,14 +70,56 @@ function buildTaskCard(task) {
|
||||
|
||||
const actions = document.createElement("div");
|
||||
actions.className = "task-actions";
|
||||
const moveUpBtn = document.createElement("button");
|
||||
moveUpBtn.type = "button";
|
||||
moveUpBtn.className = "ghost icon-btn move-up";
|
||||
moveUpBtn.textContent = "↑";
|
||||
moveUpBtn.setAttribute("aria-label", "Move task up");
|
||||
moveUpBtn.setAttribute("title", "Move up");
|
||||
const moveDownBtn = document.createElement("button");
|
||||
moveDownBtn.type = "button";
|
||||
moveDownBtn.className = "ghost icon-btn move-down";
|
||||
moveDownBtn.textContent = "↓";
|
||||
moveDownBtn.setAttribute("aria-label", "Move task down");
|
||||
moveDownBtn.setAttribute("title", "Move down");
|
||||
const addBelowBtn = document.createElement("button");
|
||||
addBelowBtn.type = "button";
|
||||
addBelowBtn.className = "ghost icon-btn add-below";
|
||||
addBelowBtn.textContent = "+";
|
||||
addBelowBtn.setAttribute("aria-label", "Add task below");
|
||||
addBelowBtn.setAttribute("title", "Add below");
|
||||
const duplicateBtn = document.createElement("button");
|
||||
duplicateBtn.type = "button";
|
||||
duplicateBtn.className = "ghost";
|
||||
duplicateBtn.className = "ghost duplicate";
|
||||
duplicateBtn.textContent = "Duplicate";
|
||||
duplicateBtn.setAttribute("aria-label", "Duplicate task");
|
||||
duplicateBtn.setAttribute("title", "Duplicate");
|
||||
const deleteBtn = document.createElement("button");
|
||||
deleteBtn.type = "button";
|
||||
deleteBtn.className = "ghost";
|
||||
deleteBtn.textContent = "Delete";
|
||||
deleteBtn.className = "ghost icon-btn delete";
|
||||
deleteBtn.textContent = "🗑";
|
||||
deleteBtn.setAttribute("aria-label", "Delete task");
|
||||
deleteBtn.setAttribute("title", "Delete");
|
||||
|
||||
moveUpBtn.addEventListener("click", () => {
|
||||
const previous = card.previousElementSibling;
|
||||
if (!previous) return;
|
||||
tasksContainer.insertBefore(card, previous);
|
||||
updateTaskControls();
|
||||
});
|
||||
|
||||
moveDownBtn.addEventListener("click", () => {
|
||||
const next = card.nextElementSibling;
|
||||
if (!next) return;
|
||||
tasksContainer.insertBefore(card, next.nextElementSibling);
|
||||
updateTaskControls();
|
||||
});
|
||||
|
||||
addBelowBtn.addEventListener("click", () => {
|
||||
const newCard = buildTaskCard({ id: newTaskId(), name: "", text: "" });
|
||||
card.insertAdjacentElement("afterend", newCard);
|
||||
updateTaskControls();
|
||||
});
|
||||
|
||||
duplicateBtn.addEventListener("click", () => {
|
||||
const copy = {
|
||||
@@ -77,12 +129,17 @@ function buildTaskCard(task) {
|
||||
};
|
||||
const newCard = buildTaskCard(copy);
|
||||
card.insertAdjacentElement("afterend", newCard);
|
||||
updateTaskControls();
|
||||
});
|
||||
|
||||
deleteBtn.addEventListener("click", () => {
|
||||
card.remove();
|
||||
updateTaskControls();
|
||||
});
|
||||
|
||||
actions.appendChild(moveUpBtn);
|
||||
actions.appendChild(moveDownBtn);
|
||||
actions.appendChild(addBelowBtn);
|
||||
actions.appendChild(duplicateBtn);
|
||||
actions.appendChild(deleteBtn);
|
||||
|
||||
@@ -93,6 +150,16 @@ function buildTaskCard(task) {
|
||||
return card;
|
||||
}
|
||||
|
||||
function updateTaskControls() {
|
||||
const cards = [...tasksContainer.querySelectorAll(".task-card")];
|
||||
cards.forEach((card, index) => {
|
||||
const moveUpBtn = card.querySelector(".move-up");
|
||||
const moveDownBtn = card.querySelector(".move-down");
|
||||
if (moveUpBtn) moveUpBtn.disabled = index === 0;
|
||||
if (moveDownBtn) moveDownBtn.disabled = index === cards.length - 1;
|
||||
});
|
||||
}
|
||||
|
||||
function collectTasks() {
|
||||
const cards = [...tasksContainer.querySelectorAll(".task-card")];
|
||||
return cards.map((card) => {
|
||||
@@ -109,14 +176,30 @@ function collectTasks() {
|
||||
async function loadSettings() {
|
||||
const {
|
||||
apiKey = "",
|
||||
apiBaseUrl = "",
|
||||
apiKeyHeader = "",
|
||||
apiKeyPrefix = "",
|
||||
model = "",
|
||||
systemPrompt = "",
|
||||
resume = "",
|
||||
tasks = [],
|
||||
theme = "system"
|
||||
} = await getStorage(["apiKey", "model", "systemPrompt", "resume", "tasks", "theme"]);
|
||||
} = await getStorage([
|
||||
"apiKey",
|
||||
"apiBaseUrl",
|
||||
"apiKeyHeader",
|
||||
"apiKeyPrefix",
|
||||
"model",
|
||||
"systemPrompt",
|
||||
"resume",
|
||||
"tasks",
|
||||
"theme"
|
||||
]);
|
||||
|
||||
apiKeyInput.value = apiKey;
|
||||
apiBaseUrlInput.value = apiBaseUrl;
|
||||
apiKeyHeaderInput.value = apiKeyHeader;
|
||||
apiKeyPrefixInput.value = apiKeyPrefix;
|
||||
modelInput.value = model;
|
||||
systemPromptInput.value = systemPrompt;
|
||||
resumeInput.value = resume;
|
||||
@@ -128,18 +211,23 @@ async function loadSettings() {
|
||||
tasksContainer.appendChild(
|
||||
buildTaskCard({ id: newTaskId(), name: "", text: "" })
|
||||
);
|
||||
updateTaskControls();
|
||||
return;
|
||||
}
|
||||
|
||||
for (const task of tasks) {
|
||||
tasksContainer.appendChild(buildTaskCard(task));
|
||||
}
|
||||
updateTaskControls();
|
||||
}
|
||||
|
||||
async function saveSettings() {
|
||||
const tasks = collectTasks();
|
||||
await chrome.storage.local.set({
|
||||
apiKey: apiKeyInput.value.trim(),
|
||||
apiBaseUrl: apiBaseUrlInput.value.trim(),
|
||||
apiKeyHeader: apiKeyHeaderInput.value.trim(),
|
||||
apiKeyPrefix: apiKeyPrefixInput.value,
|
||||
model: modelInput.value.trim(),
|
||||
systemPrompt: systemPromptInput.value,
|
||||
resume: resumeInput.value,
|
||||
@@ -152,6 +240,7 @@ async function saveSettings() {
|
||||
saveBtn.addEventListener("click", () => void saveSettings());
|
||||
addTaskBtn.addEventListener("click", () => {
|
||||
tasksContainer.appendChild(buildTaskCard({ id: newTaskId(), name: "", text: "" }));
|
||||
updateTaskControls();
|
||||
});
|
||||
|
||||
toggleKeyBtn.addEventListener("click", () => {
|
||||
@@ -161,5 +250,16 @@ toggleKeyBtn.addEventListener("click", () => {
|
||||
});
|
||||
|
||||
themeSelect.addEventListener("change", () => applyTheme(themeSelect.value));
|
||||
resetApiBtn.addEventListener("click", async () => {
|
||||
apiBaseUrlInput.value = OPENAI_DEFAULTS.apiBaseUrl;
|
||||
apiKeyHeaderInput.value = OPENAI_DEFAULTS.apiKeyHeader;
|
||||
apiKeyPrefixInput.value = OPENAI_DEFAULTS.apiKeyPrefix;
|
||||
await chrome.storage.local.set({
|
||||
apiBaseUrl: OPENAI_DEFAULTS.apiBaseUrl,
|
||||
apiKeyHeader: OPENAI_DEFAULTS.apiKeyHeader,
|
||||
apiKeyPrefix: OPENAI_DEFAULTS.apiKeyPrefix
|
||||
});
|
||||
setStatus("OpenAI defaults restored.");
|
||||
});
|
||||
|
||||
loadSettings();
|
||||
|
||||
Reference in New Issue
Block a user