mirror of
https://github.com/fmhy/FMHY-SafeGuard.git
synced 2026-03-11 08:55:40 +00:00
Add files via upload
This commit is contained in:
parent
3c6d51444c
commit
adceeaa87a
2 changed files with 834 additions and 0 deletions
553
platform/chromium/pub/settings-page.html
Normal file
553
platform/chromium/pub/settings-page.html
Normal file
|
|
@ -0,0 +1,553 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>FMHY SafeGuard - Settings</title>
|
||||
<link rel="icon" type="image/x-icon" href="../res/ext_icon_144.png" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<style>
|
||||
:root {
|
||||
--background: rgb(26, 26, 26);
|
||||
--card-bg: rgba(255, 255, 255, 0.05);
|
||||
--text-primary: #e8e8e8;
|
||||
--text-secondary: #848a94;
|
||||
--accent-purple: #c4b5fd;
|
||||
--accent-blue: #7bc5e4;
|
||||
--toggle-bg: #374151;
|
||||
--section-border: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
--background: #f5f5f5;
|
||||
--card-bg: rgba(255, 255, 255, 0.9);
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #4b5563;
|
||||
--toggle-bg: #d1d5db;
|
||||
--section-border: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--background);
|
||||
font-family: "Inter", sans-serif;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.5;
|
||||
transition: background-color 0.3s, color 0.3s;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 1.5rem;
|
||||
background: linear-gradient(
|
||||
120deg,
|
||||
var(--accent-purple) 30%,
|
||||
var(--accent-blue)
|
||||
);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.settings-card {
|
||||
background: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid var(--section-border);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.settings-section {
|
||||
padding: 1rem 0;
|
||||
border-bottom: 1px solid var(--section-border);
|
||||
}
|
||||
|
||||
.settings-section:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.last-updated {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-secondary);
|
||||
padding: 0.5rem 0.75rem;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.last-updated span {
|
||||
color: var(--accent-blue);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.section-description {
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.stats-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-radius: 12px;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
transition: transform 0.2s ease, background-color 0.3s ease;
|
||||
border: 1px solid var(--section-border);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.stat-card::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
var(--accent-purple),
|
||||
var(--accent-blue)
|
||||
);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.stat-card:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
background: linear-gradient(
|
||||
120deg,
|
||||
var(--accent-purple),
|
||||
var(--accent-blue)
|
||||
);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.update-status {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-secondary);
|
||||
text-align: right;
|
||||
padding: 0.5rem 0.75rem;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 0.5rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.update-icon {
|
||||
animation: spin 2s linear infinite;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark theme specific adjustments */
|
||||
[data-theme="dark"] .stat-card {
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
[data-theme="dark"] .stat-card:hover {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
/* Light theme specific adjustments */
|
||||
[data-theme="light"] .stat-card {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
[data-theme="light"] .stat-card:hover {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.section-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.last-updated {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stats-container {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.stats-container {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.toggle-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.toggle-switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.toggle-slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: var(--toggle-bg);
|
||||
transition: 0.4s;
|
||||
border-radius: 34px;
|
||||
}
|
||||
|
||||
.toggle-slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
left: 4px;
|
||||
bottom: 4px;
|
||||
background-color: white;
|
||||
transition: 0.4s;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
input:checked + .toggle-slider {
|
||||
background: linear-gradient(
|
||||
120deg,
|
||||
var(--accent-purple),
|
||||
var(--accent-blue)
|
||||
);
|
||||
}
|
||||
|
||||
input:checked + .toggle-slider:before {
|
||||
transform: translateX(22px);
|
||||
}
|
||||
|
||||
.select-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
select {
|
||||
appearance: none;
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--section-border);
|
||||
border-radius: 8px;
|
||||
padding: 0.5rem 2rem 0.5rem 1rem;
|
||||
font-family: inherit;
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.select-wrapper::after {
|
||||
content: "▼";
|
||||
font-size: 0.8rem;
|
||||
position: absolute;
|
||||
right: 1rem;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
pointer-events: none;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.settings-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, opacity 0.2s;
|
||||
background: linear-gradient(
|
||||
120deg,
|
||||
var(--accent-purple),
|
||||
var(--accent-blue)
|
||||
);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 2rem;
|
||||
text-align: center;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.footer a {
|
||||
color: var(--accent-blue);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.notification {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
padding: 1rem;
|
||||
background: linear-gradient(
|
||||
120deg,
|
||||
var(--accent-purple),
|
||||
var(--accent-blue)
|
||||
);
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
transform: translateY(150%);
|
||||
transition: transform 0.3s ease-out;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.notification.show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.settings-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stats-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1 class="title">FMHY SafeGuard Settings</h1>
|
||||
|
||||
<div class="settings-card">
|
||||
<!-- Filterlist Stats -->
|
||||
<div class="settings-section">
|
||||
<div class="section-header">
|
||||
<div class="section-title">Filterlist Statistics</div>
|
||||
<div class="last-updated">
|
||||
Last Updated: <span id="lastUpdated">Today at 2:56:48 PM</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-container">
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Unsafe Sites</div>
|
||||
<div class="stat-value" id="unsafeFilterCount">266</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Potentially Unsafe Sites</div>
|
||||
<div class="stat-value" id="potentiallyUnsafeFilterCount">46</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">Safe Sites</div>
|
||||
<div class="stat-value" id="safeSiteCount">21901</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="update-status" id="updateStatus">
|
||||
Next update scheduled for: Checking...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Appearance -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-grid">
|
||||
<div>
|
||||
<h2 class="section-title">Theme</h2>
|
||||
<p class="section-description">
|
||||
Choose your preferred appearance mode
|
||||
</p>
|
||||
</div>
|
||||
<div class="select-wrapper">
|
||||
<select id="themeSelect">
|
||||
<option value="system">System Default</option>
|
||||
<option value="dark">Dark Mode</option>
|
||||
<option value="light">Light Mode</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Security Settings -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-grid">
|
||||
<div>
|
||||
<h2 class="section-title">Warning Page</h2>
|
||||
<p class="section-description">
|
||||
Show warning page for unsafe sites
|
||||
</p>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="warningToggle" checked />
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Auto-Update Settings -->
|
||||
<div class="settings-section">
|
||||
<div class="settings-grid">
|
||||
<div>
|
||||
<h2 class="section-title">Auto-Update Filterlist</h2>
|
||||
<p class="section-description">
|
||||
Automatically update security filters
|
||||
</p>
|
||||
</div>
|
||||
<div class="select-wrapper">
|
||||
<select id="updateFrequency">
|
||||
<option value="daily">Daily</option>
|
||||
<option value="weekly">Weekly</option>
|
||||
<option value="monthly">Monthly</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Save Button -->
|
||||
<div style="text-align: center">
|
||||
<button class="btn" id="saveSettings">Save Settings</button>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>FMHY SafeGuard v1.1.3</p>
|
||||
<p>
|
||||
Powered by
|
||||
<a href="https://github.com/fmhy/FMHYFilterlist" target="_blank"
|
||||
>FMHY Filterlist</a
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notification Toast -->
|
||||
<div class="notification" id="notification">
|
||||
Settings saved successfully!
|
||||
</div>
|
||||
|
||||
<script src="settings-page.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
281
platform/chromium/pub/settings-page.js
Normal file
281
platform/chromium/pub/settings-page.js
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// Get all DOM elements
|
||||
const themeSelect = document.getElementById("themeSelect");
|
||||
const warningToggle = document.getElementById("warningToggle");
|
||||
const updateFrequency = document.getElementById("updateFrequency");
|
||||
const saveButton = document.getElementById("saveSettings");
|
||||
const notification = document.getElementById("notification");
|
||||
const lastUpdated = document.getElementById("lastUpdated");
|
||||
const updateStatus = document.getElementById("updateStatus");
|
||||
|
||||
// Theme application function
|
||||
function applyTheme(theme) {
|
||||
if (theme === "system") {
|
||||
const prefersDark = window.matchMedia(
|
||||
"(prefers-color-scheme: dark)"
|
||||
).matches;
|
||||
document.body.setAttribute("data-theme", prefersDark ? "dark" : "light");
|
||||
} else {
|
||||
document.body.setAttribute("data-theme", theme);
|
||||
}
|
||||
}
|
||||
|
||||
// Format date function
|
||||
function formatDate(date) {
|
||||
if (!date) return "Never";
|
||||
const d = new Date(date);
|
||||
const now = new Date();
|
||||
const diffTime = Math.abs(now - d);
|
||||
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
||||
|
||||
if (diffDays === 0) {
|
||||
return (
|
||||
"Today at " +
|
||||
d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
|
||||
);
|
||||
} else if (diffDays === 1) {
|
||||
return (
|
||||
"Yesterday at " +
|
||||
d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
d.toLocaleDateString() +
|
||||
" " +
|
||||
d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate next update time
|
||||
function calculateNextUpdate(lastUpdate, frequency) {
|
||||
if (!lastUpdate) return "Not scheduled";
|
||||
const lastUpdateDate = new Date(lastUpdate);
|
||||
let nextUpdate = new Date(lastUpdateDate);
|
||||
|
||||
switch (frequency) {
|
||||
case "daily":
|
||||
nextUpdate.setDate(nextUpdate.getDate() + 1);
|
||||
nextUpdate.setHours(0, 0, 0, 0);
|
||||
break;
|
||||
case "weekly":
|
||||
nextUpdate.setDate(nextUpdate.getDate() + 7);
|
||||
nextUpdate.setHours(0, 0, 0, 0);
|
||||
break;
|
||||
case "monthly":
|
||||
nextUpdate.setMonth(nextUpdate.getMonth() + 1);
|
||||
nextUpdate.setHours(0, 0, 0, 0);
|
||||
break;
|
||||
default:
|
||||
return "Not scheduled";
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
if (nextUpdate < now) {
|
||||
return "Update pending...";
|
||||
}
|
||||
|
||||
const timeUntil = nextUpdate - now;
|
||||
const hoursUntil = Math.floor(timeUntil / (1000 * 60 * 60));
|
||||
const minutesUntil = Math.floor(
|
||||
(timeUntil % (1000 * 60 * 60)) / (1000 * 60)
|
||||
);
|
||||
|
||||
if (hoursUntil < 24) {
|
||||
if (hoursUntil === 0) {
|
||||
return `in ${minutesUntil} minutes`;
|
||||
} else {
|
||||
return `in ${hoursUntil}h ${minutesUntil}m`;
|
||||
}
|
||||
} else {
|
||||
const days = Math.floor(hoursUntil / 24);
|
||||
if (days === 1) {
|
||||
return "tomorrow";
|
||||
} else {
|
||||
return `in ${days} days`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the UI with next update time
|
||||
function updateNextUpdateStatus() {
|
||||
chrome.storage.local.get({ lastUpdated: null }, (stats) => {
|
||||
chrome.storage.sync.get({ updateFrequency: "daily" }, (settings) => {
|
||||
const nextUpdateText = calculateNextUpdate(
|
||||
stats.lastUpdated,
|
||||
settings.updateFrequency
|
||||
);
|
||||
|
||||
if (updateStatus) {
|
||||
updateStatus.innerHTML = `
|
||||
<svg class="update-icon" viewBox="0 0 24 24" width="16" height="16">
|
||||
<path fill="currentColor" d="M12 4V2C6.477 2 2 6.477 2 12C2 17.523 6.477 22 12 22C17.523 22 22 17.523 22 12H20C20 16.418 16.418 20 12 20C7.582 20 4 16.418 4 12C4 7.582 7.582 4 12 4Z"/>
|
||||
</svg>
|
||||
Next update ${nextUpdateText}
|
||||
`;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Load filterlist stats
|
||||
function loadFilterlistStats() {
|
||||
chrome.storage.local.get(
|
||||
{
|
||||
unsafeFilterCount: 0,
|
||||
potentiallyUnsafeFilterCount: 0,
|
||||
safeSiteCount: 0,
|
||||
lastUpdated: null,
|
||||
},
|
||||
(stats) => {
|
||||
console.log("Fetched stats:", stats);
|
||||
|
||||
document.getElementById("unsafeFilterCount").textContent =
|
||||
stats.unsafeFilterCount;
|
||||
document.getElementById("potentiallyUnsafeFilterCount").textContent =
|
||||
stats.potentiallyUnsafeFilterCount;
|
||||
document.getElementById("safeSiteCount").textContent =
|
||||
stats.safeSiteCount;
|
||||
document.getElementById("lastUpdated").textContent = formatDate(
|
||||
stats.lastUpdated
|
||||
);
|
||||
|
||||
// Update the next update status
|
||||
updateNextUpdateStatus();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Load settings function
|
||||
function loadSettings() {
|
||||
chrome.storage.sync.get(
|
||||
{
|
||||
theme: "system",
|
||||
warningPage: true,
|
||||
updateFrequency: "daily",
|
||||
},
|
||||
(savedSettings) => {
|
||||
if (themeSelect) themeSelect.value = savedSettings.theme;
|
||||
if (warningToggle) warningToggle.checked = savedSettings.warningPage;
|
||||
if (updateFrequency)
|
||||
updateFrequency.value = savedSettings.updateFrequency;
|
||||
|
||||
// Apply theme
|
||||
applyTheme(savedSettings.theme);
|
||||
|
||||
// Load filterlist stats after settings are loaded
|
||||
loadFilterlistStats();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Show notification function
|
||||
function showNotification(message, isError = false) {
|
||||
if (notification) {
|
||||
notification.textContent = message;
|
||||
if (isError) {
|
||||
notification.style.background =
|
||||
"linear-gradient(120deg, #ff6b6b, #ff8787)";
|
||||
} else {
|
||||
notification.style.background =
|
||||
"linear-gradient(120deg, var(--accent-purple), var(--accent-blue))";
|
||||
}
|
||||
notification.classList.add("show");
|
||||
setTimeout(() => {
|
||||
notification.classList.remove("show");
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
// Save settings function
|
||||
function saveSettings() {
|
||||
console.log("Save button clicked, attempting to save settings...");
|
||||
|
||||
if (!themeSelect || !warningToggle || !updateFrequency) {
|
||||
console.error(
|
||||
"Missing form elements. Ensure all elements are properly defined."
|
||||
);
|
||||
showNotification("Error saving settings: Missing form elements", true);
|
||||
return;
|
||||
}
|
||||
|
||||
const settings = {
|
||||
theme: themeSelect.value,
|
||||
warningPage: warningToggle.checked,
|
||||
updateFrequency: updateFrequency.value,
|
||||
};
|
||||
|
||||
console.log("Settings to save:", settings);
|
||||
|
||||
chrome.storage.sync.set(settings, () => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error(
|
||||
"Error saving settings:",
|
||||
chrome.runtime.lastError.message
|
||||
);
|
||||
showNotification("Error saving settings", true);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Settings saved successfully.");
|
||||
|
||||
// Show success notification
|
||||
showNotification("Settings saved successfully!");
|
||||
|
||||
// Apply theme immediately
|
||||
applyTheme(settings.theme);
|
||||
console.log("Theme applied:", settings.theme);
|
||||
|
||||
// Update next update status
|
||||
updateNextUpdateStatus();
|
||||
|
||||
// Notify background script about settings change
|
||||
chrome.runtime.sendMessage(
|
||||
{ type: "settingsUpdated", settings: settings },
|
||||
() => {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error(
|
||||
"Error notifying background script:",
|
||||
chrome.runtime.lastError.message
|
||||
);
|
||||
} else {
|
||||
console.log("Background script notified about settings change.");
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Event Listeners
|
||||
if (saveButton) {
|
||||
saveButton.addEventListener("click", saveSettings);
|
||||
}
|
||||
|
||||
if (themeSelect) {
|
||||
themeSelect.addEventListener("change", (e) => {
|
||||
applyTheme(e.target.value);
|
||||
});
|
||||
}
|
||||
|
||||
// System theme change listener
|
||||
window
|
||||
.matchMedia("(prefers-color-scheme: dark)")
|
||||
.addEventListener("change", (e) => {
|
||||
if (themeSelect && themeSelect.value === "system") {
|
||||
applyTheme("system");
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for filterlist updates from background script
|
||||
chrome.runtime.onMessage.addListener((message) => {
|
||||
if (message.type === "filterlistUpdated") {
|
||||
loadFilterlistStats();
|
||||
}
|
||||
});
|
||||
|
||||
// Update the status every minute
|
||||
setInterval(updateNextUpdateStatus, 60000);
|
||||
|
||||
// Load settings when page loads
|
||||
loadSettings();
|
||||
});
|
||||
Loading…
Reference in a new issue