|
|
@@ -0,0 +1,630 @@
|
|
|
+---
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+<button id="settings-button" class="settings-button" aria-label="Settings">
|
|
|
+ <svg
|
|
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
+ width="24"
|
|
|
+ height="24"
|
|
|
+ viewBox="0 0 24 24"
|
|
|
+ fill="none"
|
|
|
+ stroke="currentColor"
|
|
|
+ stroke-width="2"
|
|
|
+ stroke-linecap="round"
|
|
|
+ stroke-linejoin="round"
|
|
|
+ >
|
|
|
+ <circle cx="12" cy="12" r="3"></circle>
|
|
|
+ <path d="M12 1v6m0 6v6m0-6h6m-6 0H6"></path>
|
|
|
+ <path
|
|
|
+ d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"
|
|
|
+ ></path>
|
|
|
+ </svg>
|
|
|
+</button>
|
|
|
+
|
|
|
+<div id="settings-dialog" class="settings-dialog">
|
|
|
+ <div class="settings-content">
|
|
|
+ <div class="settings-header">
|
|
|
+ <h2>Feed Settings</h2>
|
|
|
+ <button id="close-settings" class="close-button" aria-label="Close"
|
|
|
+ >✕</button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="settings-body">
|
|
|
+ <div id="categories-container"></div>
|
|
|
+
|
|
|
+ <button id="add-category" class="add-button">+ Add Category</button>
|
|
|
+
|
|
|
+ <div class="settings-actions">
|
|
|
+ <button id="export-settings" class="action-button"
|
|
|
+ >Export Settings</button
|
|
|
+ >
|
|
|
+ <button id="import-settings" class="action-button"
|
|
|
+ >Import Settings</button
|
|
|
+ >
|
|
|
+ <button id="reset-settings" class="action-button reset"
|
|
|
+ >Reset to Defaults</button
|
|
|
+ >
|
|
|
+ <input
|
|
|
+ type="file"
|
|
|
+ id="import-file-input"
|
|
|
+ accept=".json"
|
|
|
+ style="display: none;"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="settings-footer">
|
|
|
+ <button id="save-settings" class="save-button">Save Changes</button>
|
|
|
+ <button id="cancel-settings" class="cancel-button">Cancel</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+
|
|
|
+<script>
|
|
|
+ const settingsButton = document.getElementById("settings-button");
|
|
|
+ const settingsDialog = document.getElementById("settings-dialog");
|
|
|
+ const closeSettings = document.getElementById("close-settings");
|
|
|
+ const cancelSettings = document.getElementById("cancel-settings");
|
|
|
+ const saveSettings = document.getElementById("save-settings");
|
|
|
+ const addCategoryButton = document.getElementById("add-category");
|
|
|
+ const categoriesContainer = document.getElementById("categories-container");
|
|
|
+ const exportButton = document.getElementById("export-settings");
|
|
|
+ const importButton = document.getElementById("import-settings");
|
|
|
+ const resetButton = document.getElementById("reset-settings");
|
|
|
+ const importFileInput = document.getElementById(
|
|
|
+ "import-file-input",
|
|
|
+ ) as HTMLInputElement;
|
|
|
+
|
|
|
+ let currentSettings: any = {};
|
|
|
+
|
|
|
+ const defaultSettings = {
|
|
|
+ Tech: {
|
|
|
+ feeds: ["https://techcrunch.com/feed/"],
|
|
|
+ path: "tech",
|
|
|
+ },
|
|
|
+ "USA News": {
|
|
|
+ feeds: [
|
|
|
+ "https://feeds.nbcnews.com/nbcnews/public/news",
|
|
|
+ "https://abcnews.go.com/abcnews/topstories",
|
|
|
+ "https://www.cbsnews.com/latest/rss/main",
|
|
|
+ ],
|
|
|
+ path: "usa-news",
|
|
|
+ },
|
|
|
+ "World News": {
|
|
|
+ feeds: [
|
|
|
+ "https://feeds.nbcnews.com/nbcnews/public/news",
|
|
|
+ "https://www.cnbc.com/id/100727362/device/rss/rss.html",
|
|
|
+ ],
|
|
|
+ path: "world-news",
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ function getCookie(name: string): string | null {
|
|
|
+ const value = `; ${document.cookie}`;
|
|
|
+ const parts = value.split(`; ${name}=`);
|
|
|
+ if (parts.length === 2) {
|
|
|
+ const cookieValue = parts.pop()?.split(";").shift();
|
|
|
+ return cookieValue ? decodeURIComponent(cookieValue) : null;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ function setCookie(name: string, value: string, days: number = 365) {
|
|
|
+ const date = new Date();
|
|
|
+ date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
|
+ const expires = `expires=${date.toUTCString()}`;
|
|
|
+ document.cookie = `${name}=${encodeURIComponent(value)};${expires};path=/`;
|
|
|
+ }
|
|
|
+
|
|
|
+ function loadSettings() {
|
|
|
+ const stored = getCookie("rssFeeds");
|
|
|
+ if (stored) {
|
|
|
+ try {
|
|
|
+ currentSettings = JSON.parse(stored);
|
|
|
+ } catch (e) {
|
|
|
+ console.error("Failed to parse stored settings", e);
|
|
|
+ currentSettings = JSON.parse(JSON.stringify(defaultSettings));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ currentSettings = JSON.parse(JSON.stringify(defaultSettings));
|
|
|
+ }
|
|
|
+ renderCategories();
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderCategories() {
|
|
|
+ if (!categoriesContainer) return;
|
|
|
+
|
|
|
+ categoriesContainer.innerHTML = "";
|
|
|
+
|
|
|
+ Object.keys(currentSettings).forEach((categoryName) => {
|
|
|
+ if (categoryName === "All") return;
|
|
|
+
|
|
|
+ const category = currentSettings[categoryName];
|
|
|
+ const categoryDiv = document.createElement("div");
|
|
|
+ categoryDiv.className = "category-item";
|
|
|
+ categoryDiv.innerHTML = `
|
|
|
+ <div class="category-header">
|
|
|
+ <input type="text" class="category-name" value="${categoryName}" data-original="${categoryName}" placeholder="Category Name">
|
|
|
+ <input type="text" class="category-path" value="${category.path}" placeholder="URL path (e.g., tech)">
|
|
|
+ <button class="delete-category" data-category="${categoryName}">Delete</button>
|
|
|
+ </div>
|
|
|
+ <div class="feeds-list">
|
|
|
+ ${category.feeds
|
|
|
+ .map(
|
|
|
+ (feed: string, idx: number) => `
|
|
|
+ <div class="feed-item">
|
|
|
+ <input type="url" class="feed-url" value="${feed}" placeholder="RSS Feed URL">
|
|
|
+ <button class="delete-feed" data-category="${categoryName}" data-index="${idx}">−</button>
|
|
|
+ </div>
|
|
|
+ `,
|
|
|
+ )
|
|
|
+ .join("")}
|
|
|
+ </div>
|
|
|
+ <button class="add-feed" data-category="${categoryName}">+ Add Feed</button>
|
|
|
+ `;
|
|
|
+ categoriesContainer.appendChild(categoryDiv);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Attach event listeners
|
|
|
+ attachEventListeners();
|
|
|
+ }
|
|
|
+
|
|
|
+ function attachEventListeners() {
|
|
|
+ // Delete category buttons
|
|
|
+ document.querySelectorAll(".delete-category").forEach((btn) => {
|
|
|
+ btn.addEventListener("click", (e) => {
|
|
|
+ const categoryName = (e.target as HTMLButtonElement).dataset
|
|
|
+ .category!;
|
|
|
+ delete currentSettings[categoryName];
|
|
|
+ renderCategories();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // Delete feed buttons
|
|
|
+ document.querySelectorAll(".delete-feed").forEach((btn) => {
|
|
|
+ btn.addEventListener("click", (e) => {
|
|
|
+ const target = e.target as HTMLButtonElement;
|
|
|
+ const categoryName = target.dataset.category!;
|
|
|
+ const index = parseInt(target.dataset.index!);
|
|
|
+ currentSettings[categoryName].feeds.splice(index, 1);
|
|
|
+ renderCategories();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // Add feed buttons
|
|
|
+ document.querySelectorAll(".add-feed").forEach((btn) => {
|
|
|
+ btn.addEventListener("click", (e) => {
|
|
|
+ const categoryName = (e.target as HTMLButtonElement).dataset
|
|
|
+ .category!;
|
|
|
+ currentSettings[categoryName].feeds.push("");
|
|
|
+ renderCategories();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Open settings dialog
|
|
|
+ settingsButton?.addEventListener("click", () => {
|
|
|
+ loadSettings();
|
|
|
+ settingsDialog!.style.display = "flex";
|
|
|
+ });
|
|
|
+
|
|
|
+ // Close settings dialog
|
|
|
+ function closeDialog() {
|
|
|
+ settingsDialog!.style.display = "none";
|
|
|
+ }
|
|
|
+
|
|
|
+ closeSettings?.addEventListener("click", closeDialog);
|
|
|
+ cancelSettings?.addEventListener("click", closeDialog);
|
|
|
+
|
|
|
+ // Close when clicking outside
|
|
|
+ settingsDialog?.addEventListener("click", (e) => {
|
|
|
+ if (e.target === settingsDialog) {
|
|
|
+ closeDialog();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // Add new category
|
|
|
+ addCategoryButton?.addEventListener("click", () => {
|
|
|
+ const categoryName = `New Category ${Object.keys(currentSettings).length}`;
|
|
|
+ currentSettings[categoryName] = {
|
|
|
+ path: `category-${Date.now()}`,
|
|
|
+ feeds: [],
|
|
|
+ };
|
|
|
+ renderCategories();
|
|
|
+ });
|
|
|
+
|
|
|
+ // Save settings
|
|
|
+ saveSettings?.addEventListener("click", () => {
|
|
|
+ // Collect updated data from inputs
|
|
|
+ const updatedSettings: any = {};
|
|
|
+
|
|
|
+ document.querySelectorAll(".category-item").forEach((categoryDiv) => {
|
|
|
+ const nameInput = categoryDiv.querySelector(
|
|
|
+ ".category-name",
|
|
|
+ ) as HTMLInputElement;
|
|
|
+ const pathInput = categoryDiv.querySelector(
|
|
|
+ ".category-path",
|
|
|
+ ) as HTMLInputElement;
|
|
|
+ const categoryName = nameInput.value.trim();
|
|
|
+ const categoryPath = pathInput.value.trim();
|
|
|
+
|
|
|
+ if (!categoryName || !categoryPath) return;
|
|
|
+
|
|
|
+ const feeds: string[] = [];
|
|
|
+ categoryDiv.querySelectorAll(".feed-url").forEach((feedInput) => {
|
|
|
+ const url = (feedInput as HTMLInputElement).value.trim();
|
|
|
+ if (url) feeds.push(url);
|
|
|
+ });
|
|
|
+
|
|
|
+ updatedSettings[categoryName] = {
|
|
|
+ path: categoryPath,
|
|
|
+ feeds: feeds,
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ // Build the "All" category by combining all other category feeds
|
|
|
+ updatedSettings.All = {
|
|
|
+ path: "/",
|
|
|
+ feeds: [],
|
|
|
+ };
|
|
|
+
|
|
|
+ Object.keys(updatedSettings).forEach((category) => {
|
|
|
+ if (category === "All") return;
|
|
|
+ updatedSettings.All.feeds = updatedSettings.All.feeds.concat(
|
|
|
+ updatedSettings[category].feeds,
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ // Save to cookie
|
|
|
+ setCookie("rssFeeds", JSON.stringify(updatedSettings));
|
|
|
+
|
|
|
+ closeDialog();
|
|
|
+
|
|
|
+ // Reload the page to apply new settings
|
|
|
+ window.location.reload();
|
|
|
+ });
|
|
|
+
|
|
|
+ // Export settings
|
|
|
+ exportButton?.addEventListener("click", () => {
|
|
|
+ const dataStr = JSON.stringify(currentSettings, null, 2);
|
|
|
+ const dataBlob = new Blob([dataStr], { type: "application/json" });
|
|
|
+ const url = URL.createObjectURL(dataBlob);
|
|
|
+ const link = document.createElement("a");
|
|
|
+ link.href = url;
|
|
|
+ link.download = "rss-feeds.json";
|
|
|
+ document.body.appendChild(link);
|
|
|
+ link.click();
|
|
|
+ document.body.removeChild(link);
|
|
|
+ URL.revokeObjectURL(url);
|
|
|
+ });
|
|
|
+
|
|
|
+ // Import settings
|
|
|
+ importButton?.addEventListener("click", () => {
|
|
|
+ importFileInput?.click();
|
|
|
+ });
|
|
|
+
|
|
|
+ importFileInput?.addEventListener("change", (e) => {
|
|
|
+ const file = (e.target as HTMLInputElement).files?.[0];
|
|
|
+ if (!file) return;
|
|
|
+
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = (event) => {
|
|
|
+ try {
|
|
|
+ const imported = JSON.parse(event.target?.result as string);
|
|
|
+ currentSettings = imported;
|
|
|
+ setCookie("rssFeeds", JSON.stringify(imported));
|
|
|
+ renderCategories();
|
|
|
+ alert("Settings imported successfully!");
|
|
|
+ } catch (error) {
|
|
|
+ alert(
|
|
|
+ "Failed to import settings. Please check the file format.",
|
|
|
+ );
|
|
|
+ console.error("Import error:", error);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ reader.readAsText(file);
|
|
|
+
|
|
|
+ // Reset input so the same file can be imported again
|
|
|
+ importFileInput.value = "";
|
|
|
+ });
|
|
|
+
|
|
|
+ // Reset to defaults
|
|
|
+ resetButton?.addEventListener("click", () => {
|
|
|
+ if (
|
|
|
+ confirm(
|
|
|
+ "Are you sure you want to reset to default settings? This will discard all custom feeds.",
|
|
|
+ )
|
|
|
+ ) {
|
|
|
+ currentSettings = JSON.parse(JSON.stringify(defaultSettings));
|
|
|
+ setCookie("rssFeeds", JSON.stringify(currentSettings));
|
|
|
+ renderCategories();
|
|
|
+ }
|
|
|
+ });
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+ .settings-button {
|
|
|
+ position: fixed;
|
|
|
+ top: 20px;
|
|
|
+ left: 20px;
|
|
|
+ background: transparent;
|
|
|
+ border: 2px solid #ccc;
|
|
|
+ border-radius: 5px;
|
|
|
+ color: white;
|
|
|
+ width: 48px;
|
|
|
+ height: 48px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ z-index: 1000;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-button:hover {
|
|
|
+ border-color: #999;
|
|
|
+ background: #1a1a1a;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-dialog {
|
|
|
+ display: none;
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background: rgba(0, 0, 0, 0.8);
|
|
|
+ z-index: 10000;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-content {
|
|
|
+ background: black;
|
|
|
+ border: 2px solid #ccc;
|
|
|
+ border-radius: 5px;
|
|
|
+ width: 100%;
|
|
|
+ max-width: 800px;
|
|
|
+ max-height: 90vh;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 20px;
|
|
|
+ border-bottom: 2px solid #333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-header h2 {
|
|
|
+ margin: 0;
|
|
|
+ color: white;
|
|
|
+ font-size: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .close-button {
|
|
|
+ background: transparent;
|
|
|
+ border: none;
|
|
|
+ color: white;
|
|
|
+ font-size: 28px;
|
|
|
+ cursor: pointer;
|
|
|
+ padding: 0;
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ transition: opacity 0.3s ease;
|
|
|
+ }
|
|
|
+
|
|
|
+ .close-button:hover {
|
|
|
+ opacity: 0.7;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-body {
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+ padding: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ #categories-container {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 20px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-item {
|
|
|
+ border: 2px solid #444;
|
|
|
+ border-radius: 5px;
|
|
|
+ padding: 15px;
|
|
|
+ background: #0a0a0a;
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-header {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-name,
|
|
|
+ .category-path {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 150px;
|
|
|
+ background: #1a1a1a;
|
|
|
+ border: 1px solid #555;
|
|
|
+ border-radius: 3px;
|
|
|
+ padding: 8px 12px;
|
|
|
+ color: white;
|
|
|
+ font-family: Monospace;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .category-name:focus,
|
|
|
+ .category-path:focus,
|
|
|
+ .feed-url:focus {
|
|
|
+ outline: none;
|
|
|
+ border-color: #999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete-category {
|
|
|
+ background: #cc0000;
|
|
|
+ border: none;
|
|
|
+ border-radius: 3px;
|
|
|
+ color: white;
|
|
|
+ padding: 8px 16px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-family: Monospace;
|
|
|
+ transition: background 0.3s ease;
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete-category:hover {
|
|
|
+ background: #aa0000;
|
|
|
+ }
|
|
|
+
|
|
|
+ .feeds-list {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 8px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .feed-item {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .feed-url {
|
|
|
+ flex: 1;
|
|
|
+ background: #1a1a1a;
|
|
|
+ border: 1px solid #555;
|
|
|
+ border-radius: 3px;
|
|
|
+ padding: 8px 12px;
|
|
|
+ color: white;
|
|
|
+ font-family: Monospace;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete-feed {
|
|
|
+ background: #cc0000;
|
|
|
+ border: none;
|
|
|
+ border-radius: 3px;
|
|
|
+ color: white;
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-size: 20px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ transition: background 0.3s ease;
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete-feed:hover {
|
|
|
+ background: #aa0000;
|
|
|
+ }
|
|
|
+
|
|
|
+ .add-feed,
|
|
|
+ .add-button {
|
|
|
+ background: transparent;
|
|
|
+ border: 2px solid #555;
|
|
|
+ border-radius: 3px;
|
|
|
+ color: #999;
|
|
|
+ padding: 8px 16px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-family: Monospace;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .add-feed:hover,
|
|
|
+ .add-button:hover {
|
|
|
+ border-color: #999;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-actions {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ margin-top: 20px;
|
|
|
+ padding-top: 20px;
|
|
|
+ border-top: 2px solid #333;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .action-button {
|
|
|
+ background: transparent;
|
|
|
+ border: 2px solid #555;
|
|
|
+ border-radius: 3px;
|
|
|
+ color: #999;
|
|
|
+ padding: 8px 16px;
|
|
|
+ cursor: pointer;
|
|
|
+ font-family: Monospace;
|
|
|
+ font-size: 14px;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ flex: 1;
|
|
|
+ min-width: 150px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .action-button:hover {
|
|
|
+ border-color: #999;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+
|
|
|
+ .action-button.reset {
|
|
|
+ border-color: #cc6600;
|
|
|
+ color: #cc6600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .action-button.reset:hover {
|
|
|
+ border-color: #ff8800;
|
|
|
+ color: #ff8800;
|
|
|
+ }
|
|
|
+
|
|
|
+ .settings-footer {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+ padding: 20px;
|
|
|
+ border-top: 2px solid #333;
|
|
|
+ justify-content: flex-end;
|
|
|
+ }
|
|
|
+
|
|
|
+ .save-button,
|
|
|
+ .cancel-button {
|
|
|
+ padding: 10px 24px;
|
|
|
+ border-radius: 3px;
|
|
|
+ font-family: Monospace;
|
|
|
+ font-size: 14px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ }
|
|
|
+
|
|
|
+ .save-button {
|
|
|
+ background: white;
|
|
|
+ border: 2px solid white;
|
|
|
+ color: black;
|
|
|
+ }
|
|
|
+
|
|
|
+ .save-button:hover {
|
|
|
+ background: #ccc;
|
|
|
+ border-color: #ccc;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cancel-button {
|
|
|
+ background: transparent;
|
|
|
+ border: 2px solid #ccc;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cancel-button:hover {
|
|
|
+ border-color: #999;
|
|
|
+ }
|
|
|
+</style>
|