feat: add options page for API key and thresholds

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
IgorVolochay
2026-10-25 10:51:42 +03:00
co-authored by Claude Sonnet 5.5
parent 3a28991522
commit 513a64f84a
4 changed files with 85 additions and 1 deletions
+2 -1
View File
@@ -6,5 +6,6 @@
"permissions": ["storage"],
"host_permissions": ["https://www.googleapis.com/youtube/v3/*"],
"background": { "service_worker": "src/background.js", "type": "module" },
"action": { "default_title": "Outlier Saver" }
"action": { "default_title": "Outlier Saver" },
"options_ui": { "page": "src/options/options.html", "open_in_tab": true }
}
+16
View File
@@ -0,0 +1,16 @@
:root {
color-scheme: light dark;
--line: color-mix(in srgb, currentColor 20%, transparent);
--muted: color-mix(in srgb, currentColor 60%, transparent);
}
body { margin: 0; font: 15px/1.5 system-ui, sans-serif; }
main { max-width: 520px; margin: 0 auto; padding: 24px 16px; }
h1 { font-size: 20px; margin: 0 0 16px; }
form { display: grid; gap: 16px; }
label { display: grid; gap: 4px; font-weight: 600; }
input { padding: 8px 10px; font: inherit; border: 1px solid var(--line); border-radius: 6px; background: transparent; color: inherit; }
.actions { display: flex; align-items: center; gap: 12px; }
button { padding: 8px 16px; font: inherit; border: 0; border-radius: 6px; background: #1a73e8; color: #fff; cursor: pointer; }
#saved { color: var(--muted); }
details { margin-top: 24px; color: var(--muted); }
summary { cursor: pointer; }
+43
View File
@@ -0,0 +1,43 @@
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Outlier Saver — настройки</title>
<link rel="stylesheet" href="options.css">
</head>
<body>
<main>
<h1>Outlier Saver</h1>
<form id="form">
<label>
API-ключ YouTube Data API v3
<input id="apiKey" type="password" autocomplete="off" spellcheck="false">
</label>
<label>
Порог score (просмотры ÷ подписчики)
<input id="threshold" type="number" min="0.1" step="0.1" required>
</label>
<label>
Минимум просмотров
<input id="minViews" type="number" min="0" step="1000" required>
</label>
<div class="actions">
<button type="submit">Сохранить</button>
<span id="saved" role="status"></span>
</div>
</form>
<details>
<summary>Как получить API-ключ</summary>
<ol>
<li>Откройте <a href="https://console.cloud.google.com/" target="_blank" rel="noreferrer">Google Cloud Console</a> и создайте проект.</li>
<li>В разделе «API и сервисы → Библиотека» включите <b>YouTube Data API v3</b>.</li>
<li>В «Учётные данные» создайте <b>API-ключ</b>.</li>
<li>В ограничениях ключа выберите «Ограничить API → YouTube Data API v3». Ограничение по HTTP-источникам (referrer) <b>не включайте</b>: запросы идут из расширения.</li>
<li>Вставьте ключ в поле выше и нажмите «Сохранить».</li>
</ol>
</details>
</main>
<script type="module" src="options.js"></script>
</body>
</html>
+24
View File
@@ -0,0 +1,24 @@
import { getSettings, saveSettings } from '../lib/storage.js';
const form = document.getElementById('form');
const apiKey = document.getElementById('apiKey');
const threshold = document.getElementById('threshold');
const minViews = document.getElementById('minViews');
const savedLabel = document.getElementById('saved');
function fill(settings) {
apiKey.value = settings.apiKey;
threshold.value = settings.threshold;
minViews.value = settings.minViews;
}
fill(await getSettings());
form.addEventListener('submit', async (event) => {
event.preventDefault();
fill(await saveSettings({ apiKey: apiKey.value, threshold: threshold.value, minViews: minViews.value }));
savedLabel.textContent = 'Сохранено';
setTimeout(() => {
savedLabel.textContent = '';
}, 2000);
});