mirror of
https://github.com/Retropex/custom-ocean.xyz-dashboard.git
synced 2025-05-12 11:10:44 +02:00
Add responsive theme toggle and dynamic styling
Introduces a responsive theme toggle button with styles for desktop and mobile views in `theme-toggle.css`. Updates `BitcoinProgressBar.js` to support dynamic theme changes and adds a new `updateTheme` method. Enhances `main.js` for theme management based on user preferences in `localStorage`. Modifies `base.html` and other HTML files to include the theme toggle button and necessary scripts. Introduces `theme.js` for managing theme constants and applying the DeepSea theme.
This commit is contained in:
parent
2142a7d2af
commit
0d0a707019
146
static/css/theme-toggle.css
Normal file
146
static/css/theme-toggle.css
Normal file
@ -0,0 +1,146 @@
|
||||
/* Responsive Theme Toggle Button Styles */
|
||||
/* Common styles for the theme toggle button regardless of device */
|
||||
#themeToggle,
|
||||
.theme-toggle-btn {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
background: transparent;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
font-family: 'VT323', monospace;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
text-transform: uppercase;
|
||||
outline: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Default positioning and styling for desktop */
|
||||
@media screen and (min-width: 768px) {
|
||||
#themeToggle,
|
||||
.theme-toggle-btn {
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
border-radius: 3px;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
/* Add theme icon for desktop view */
|
||||
#themeToggle:before,
|
||||
.theme-toggle-btn:before {
|
||||
content: "☀/☾";
|
||||
margin-right: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Hover effects for desktop */
|
||||
#themeToggle:hover,
|
||||
.theme-toggle-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile-specific styling - MODIFIED to keep left positioning */
|
||||
@media screen and (max-width: 767px) {
|
||||
#themeToggle,
|
||||
.theme-toggle-btn {
|
||||
top: 60px;
|
||||
left: 10px; /* Keep on left side */
|
||||
padding: 8px;
|
||||
font-size: 12px;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
/* Use just icon for mobile to save space */
|
||||
#themeToggle:before,
|
||||
.theme-toggle-btn:before {
|
||||
content: "☀/☾";
|
||||
margin-right: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* Hide text on mobile */
|
||||
#themeToggle span,
|
||||
.theme-toggle-btn span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Adjust position when in portrait mode on very small screens */
|
||||
@media screen and (max-height: 500px) {
|
||||
#themeToggle,
|
||||
.theme-toggle-btn {
|
||||
top: 5px;
|
||||
left: 5px; /* Keep on left side */
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The rest of the CSS remains unchanged */
|
||||
/* Active state for the button */
|
||||
#themeToggle:active,
|
||||
.theme-toggle-btn:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 0 2px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Bitcoin theme specific styling (orange) */
|
||||
body:not(.deepsea-theme) #themeToggle,
|
||||
body:not(.deepsea-theme) .theme-toggle-btn {
|
||||
color: #f2a900;
|
||||
border-color: #f2a900;
|
||||
}
|
||||
|
||||
body:not(.deepsea-theme) #themeToggle:hover,
|
||||
body:not(.deepsea-theme) .theme-toggle-btn:hover {
|
||||
background-color: rgba(242, 169, 0, 0.1);
|
||||
box-shadow: 0 4px 8px rgba(242, 169, 0, 0.3);
|
||||
}
|
||||
|
||||
/* DeepSea theme specific styling (blue) */
|
||||
body.deepsea-theme #themeToggle,
|
||||
body.deepsea-theme .theme-toggle-btn {
|
||||
color: #0088cc;
|
||||
border-color: #0088cc;
|
||||
}
|
||||
|
||||
body.deepsea-theme #themeToggle:hover,
|
||||
body.deepsea-theme .theme-toggle-btn:hover {
|
||||
background-color: rgba(0, 136, 204, 0.1);
|
||||
box-shadow: 0 4px 8px rgba(0, 136, 204, 0.3);
|
||||
}
|
||||
|
||||
/* Transition effect for smoother theme switching */
|
||||
#themeToggle,
|
||||
.theme-toggle-btn,
|
||||
#themeToggle:before,
|
||||
.theme-toggle-btn:before {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* Accessibility improvements */
|
||||
#themeToggle:focus,
|
||||
.theme-toggle-btn:focus {
|
||||
box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.3);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
body:not(.deepsea-theme) #themeToggle:focus,
|
||||
body:not(.deepsea-theme) .theme-toggle-btn:focus {
|
||||
box-shadow: 0 0 0 3px rgba(242, 169, 0, 0.3);
|
||||
}
|
||||
|
||||
body.deepsea-theme #themeToggle:focus,
|
||||
body.deepsea-theme .theme-toggle-btn:focus {
|
||||
box-shadow: 0 0 0 3px rgba(0, 136, 204, 0.3);
|
||||
}
|
@ -2,11 +2,14 @@
|
||||
* BitcoinMinuteRefresh.js - Simplified Bitcoin-themed floating uptime monitor
|
||||
*
|
||||
* This module creates a Bitcoin-themed terminal that shows server uptime.
|
||||
* Now includes DeepSea theme support.
|
||||
*/
|
||||
|
||||
const BitcoinMinuteRefresh = (function () {
|
||||
// Constants
|
||||
const STORAGE_KEY = 'bitcoin_last_refresh_time'; // For cross-page sync
|
||||
const BITCOIN_COLOR = '#f7931a';
|
||||
const DEEPSEA_COLOR = '#0088cc';
|
||||
|
||||
// Private variables
|
||||
let terminalElement = null;
|
||||
@ -16,6 +19,117 @@ const BitcoinMinuteRefresh = (function () {
|
||||
let uptimeInterval = null;
|
||||
let isInitialized = false;
|
||||
let refreshCallback = null;
|
||||
let currentThemeColor = BITCOIN_COLOR; // Default Bitcoin color
|
||||
|
||||
/**
|
||||
* Apply the current theme color
|
||||
*/
|
||||
function applyThemeColor() {
|
||||
// Check if theme toggle is set to DeepSea
|
||||
const isDeepSeaTheme = localStorage.getItem('useDeepSeaTheme') === 'true';
|
||||
currentThemeColor = isDeepSeaTheme ? DEEPSEA_COLOR : BITCOIN_COLOR;
|
||||
|
||||
// Don't try to update DOM elements if they don't exist yet
|
||||
if (!terminalElement) return;
|
||||
|
||||
// Update terminal colors
|
||||
if (isDeepSeaTheme) {
|
||||
terminalElement.style.borderColor = DEEPSEA_COLOR;
|
||||
terminalElement.style.color = DEEPSEA_COLOR;
|
||||
terminalElement.style.boxShadow = `0 0 5px rgba(0, 136, 204, 0.3)`;
|
||||
|
||||
// Update header border
|
||||
const headerElement = terminalElement.querySelector('.terminal-header');
|
||||
if (headerElement) {
|
||||
headerElement.style.borderColor = DEEPSEA_COLOR;
|
||||
}
|
||||
|
||||
// Update terminal title
|
||||
const titleElement = terminalElement.querySelector('.terminal-title');
|
||||
if (titleElement) {
|
||||
titleElement.style.color = DEEPSEA_COLOR;
|
||||
titleElement.style.textShadow = '0 0 5px rgba(0, 136, 204, 0.8)';
|
||||
}
|
||||
|
||||
// Update uptime timer border
|
||||
const uptimeTimer = terminalElement.querySelector('.uptime-timer');
|
||||
if (uptimeTimer) {
|
||||
uptimeTimer.style.borderColor = `rgba(0, 136, 204, 0.5)`;
|
||||
}
|
||||
|
||||
// Update uptime separators
|
||||
const separators = terminalElement.querySelectorAll('.uptime-separator');
|
||||
separators.forEach(sep => {
|
||||
sep.style.textShadow = '0 0 8px rgba(0, 136, 204, 0.8)';
|
||||
});
|
||||
|
||||
// Update uptime title
|
||||
const uptimeTitle = terminalElement.querySelector('.uptime-title');
|
||||
if (uptimeTitle) {
|
||||
uptimeTitle.style.textShadow = '0 0 5px rgba(0, 136, 204, 0.8)';
|
||||
}
|
||||
|
||||
// Update minimized view
|
||||
const miniLabel = terminalElement.querySelector('.mini-uptime-label');
|
||||
if (miniLabel) {
|
||||
miniLabel.style.color = DEEPSEA_COLOR;
|
||||
}
|
||||
} else {
|
||||
// Reset to Bitcoin theme
|
||||
terminalElement.style.borderColor = BITCOIN_COLOR;
|
||||
terminalElement.style.color = BITCOIN_COLOR;
|
||||
terminalElement.style.boxShadow = `0 0 5px rgba(247, 147, 26, 0.3)`;
|
||||
|
||||
// Update header border
|
||||
const headerElement = terminalElement.querySelector('.terminal-header');
|
||||
if (headerElement) {
|
||||
headerElement.style.borderColor = BITCOIN_COLOR;
|
||||
}
|
||||
|
||||
// Update terminal title
|
||||
const titleElement = terminalElement.querySelector('.terminal-title');
|
||||
if (titleElement) {
|
||||
titleElement.style.color = BITCOIN_COLOR;
|
||||
titleElement.style.textShadow = '0 0 5px rgba(247, 147, 26, 0.8)';
|
||||
}
|
||||
|
||||
// Update uptime timer border
|
||||
const uptimeTimer = terminalElement.querySelector('.uptime-timer');
|
||||
if (uptimeTimer) {
|
||||
uptimeTimer.style.borderColor = `rgba(247, 147, 26, 0.5)`;
|
||||
}
|
||||
|
||||
// Update uptime separators
|
||||
const separators = terminalElement.querySelectorAll('.uptime-separator');
|
||||
separators.forEach(sep => {
|
||||
sep.style.textShadow = '0 0 8px rgba(247, 147, 26, 0.8)';
|
||||
});
|
||||
|
||||
// Update uptime title
|
||||
const uptimeTitle = terminalElement.querySelector('.uptime-title');
|
||||
if (uptimeTitle) {
|
||||
uptimeTitle.style.textShadow = '0 0 5px rgba(247, 147, 26, 0.8)';
|
||||
}
|
||||
|
||||
// Update minimized view
|
||||
const miniLabel = terminalElement.querySelector('.mini-uptime-label');
|
||||
if (miniLabel) {
|
||||
miniLabel.style.color = BITCOIN_COLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for theme changes
|
||||
*/
|
||||
function setupThemeChangeListener() {
|
||||
// Listen for theme change events from localStorage
|
||||
window.addEventListener('storage', function (e) {
|
||||
if (e.key === 'useDeepSeaTheme') {
|
||||
applyThemeColor();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add dragging functionality to the terminal
|
||||
@ -200,6 +314,7 @@ const BitcoinMinuteRefresh = (function () {
|
||||
* Add CSS styles for the terminal
|
||||
*/
|
||||
function addStyles() {
|
||||
// Use the currentThemeColor variable instead of hardcoded colors
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.id = 'bitcoin-terminal-styles';
|
||||
styleElement.textContent = `
|
||||
@ -210,14 +325,14 @@ const BitcoinMinuteRefresh = (function () {
|
||||
right: 20px;
|
||||
width: 230px;
|
||||
background-color: #000000;
|
||||
border: 1px solid #f7931a;
|
||||
color: #f7931a;
|
||||
border: 1px solid ${currentThemeColor};
|
||||
color: ${currentThemeColor};
|
||||
font-family: 'VT323', monospace;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
padding: 8px;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 0 5px rgba(247, 147, 26, 0.3);
|
||||
box-shadow: 0 0 5px rgba(${currentThemeColor === DEEPSEA_COLOR ? '0, 136, 204' : '247, 147, 26'}, 0.3);
|
||||
}
|
||||
|
||||
/* Terminal Header */
|
||||
@ -616,6 +731,9 @@ const BitcoinMinuteRefresh = (function () {
|
||||
// Store the refresh callback
|
||||
refreshCallback = refreshFunc;
|
||||
|
||||
// Get current theme status
|
||||
applyThemeColor();
|
||||
|
||||
// Create the terminal element if it doesn't exist
|
||||
if (!document.getElementById('bitcoin-terminal')) {
|
||||
createTerminalElement();
|
||||
@ -623,8 +741,14 @@ const BitcoinMinuteRefresh = (function () {
|
||||
// Get references to existing elements
|
||||
terminalElement = document.getElementById('bitcoin-terminal');
|
||||
uptimeElement = document.getElementById('uptime-timer');
|
||||
|
||||
// Apply theme to existing element
|
||||
applyThemeColor();
|
||||
}
|
||||
|
||||
// Set up listener for theme changes
|
||||
setupThemeChangeListener();
|
||||
|
||||
// Try to get stored server time information
|
||||
try {
|
||||
serverTimeOffset = parseFloat(localStorage.getItem('serverTimeOffset') || '0');
|
||||
@ -766,11 +890,12 @@ const BitcoinMinuteRefresh = (function () {
|
||||
updateServerTime: updateServerTime,
|
||||
toggleTerminal: toggleTerminal,
|
||||
hideTerminal: hideTerminal,
|
||||
showTerminal: showTerminal
|
||||
showTerminal: showTerminal,
|
||||
updateTheme: applyThemeColor // <-- Add this new method
|
||||
};
|
||||
})();
|
||||
|
||||
// Auto-initialize when document is ready if a refresh function is available in the global scope
|
||||
// Auto-initialize when document is ready
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Check if manualRefresh function exists in global scope
|
||||
if (typeof window.manualRefresh === 'function') {
|
||||
@ -778,4 +903,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
} else {
|
||||
console.log("BitcoinMinuteRefresh: No refresh function found, will need to be initialized manually");
|
||||
}
|
||||
|
||||
// Update theme based on current setting
|
||||
setTimeout(() => BitcoinMinuteRefresh.updateTheme(), 100);
|
||||
});
|
||||
|
@ -1,4 +1,7 @@
|
||||
"use strict";
|
||||
// Add this flag at the top of your file, outside the function
|
||||
let isApplyingTheme = false;
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* ArrowIndicator - A clean implementation for managing metric value change indicators
|
||||
@ -176,6 +179,11 @@ class ArrowIndicator {
|
||||
});
|
||||
}
|
||||
|
||||
// Current theme affects arrow colors
|
||||
const theme = getCurrentTheme();
|
||||
const upArrowColor = THEME.SHARED.GREEN;
|
||||
const downArrowColor = THEME.SHARED.RED;
|
||||
|
||||
// Get normalized values and compare with previous metrics
|
||||
for (const key of metricKeys) {
|
||||
if (newMetrics[key] === undefined) continue;
|
||||
@ -714,15 +722,16 @@ function handleVisibilityChange() {
|
||||
|
||||
// Helper function to show connection issues to the user
|
||||
function showConnectionIssue(message) {
|
||||
const theme = getCurrentTheme();
|
||||
let $connectionStatus = $("#connectionStatus");
|
||||
if (!$connectionStatus.length) {
|
||||
$("body").append('<div id="connectionStatus" style="position: fixed; top: 10px; right: 10px; background: rgba(255,0,0,0.7); color: white; padding: 10px; border-radius: 5px; z-index: 9999;"></div>');
|
||||
$("body").append(`<div id="connectionStatus" style="position: fixed; top: 10px; right: 10px; background: rgba(255,0,0,0.7); color: white; padding: 10px; border-radius: 5px; z-index: 9999;"></div>`);
|
||||
$connectionStatus = $("#connectionStatus");
|
||||
}
|
||||
$connectionStatus.html(`<i class="fas fa-exclamation-triangle"></i> ${message}`).show();
|
||||
|
||||
// Show manual refresh button when there are connection issues
|
||||
$("#refreshButton").show();
|
||||
// Show manual refresh button with theme color
|
||||
$("#refreshButton").css('background-color', theme.PRIMARY).show();
|
||||
}
|
||||
|
||||
// Helper function to hide connection issue message
|
||||
@ -766,7 +775,7 @@ function manualRefresh() {
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize Chart.js with Unit Normalization
|
||||
// Modify the initializeChart function to use blue colors for the chart
|
||||
function initializeChart() {
|
||||
try {
|
||||
const ctx = document.getElementById('trendGraph').getContext('2d');
|
||||
@ -780,10 +789,12 @@ function initializeChart() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the current theme colors
|
||||
const theme = getCurrentTheme();
|
||||
|
||||
// Check if Chart.js plugin is available
|
||||
const hasAnnotationPlugin = window['chartjs-plugin-annotation'] !== undefined;
|
||||
|
||||
// Inside the initializeChart function, modify the dataset configuration:
|
||||
return new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
@ -796,29 +807,29 @@ function initializeChart() {
|
||||
const chart = context.chart;
|
||||
const { ctx, chartArea } = chart;
|
||||
if (!chartArea) {
|
||||
return '#f7931a';
|
||||
return theme.PRIMARY;
|
||||
}
|
||||
// Create gradient for line
|
||||
const gradient = ctx.createLinearGradient(0, 0, 0, chartArea.bottom);
|
||||
gradient.addColorStop(0, '#ffa64d'); // Lighter orange
|
||||
gradient.addColorStop(1, '#f7931a'); // Bitcoin orange
|
||||
gradient.addColorStop(0, theme.CHART.GRADIENT_START);
|
||||
gradient.addColorStop(1, theme.CHART.GRADIENT_END);
|
||||
return gradient;
|
||||
},
|
||||
backgroundColor: function (context) {
|
||||
const chart = context.chart;
|
||||
const { ctx, chartArea } = chart;
|
||||
if (!chartArea) {
|
||||
return 'rgba(247,147,26,0.1)';
|
||||
return `rgba(${theme.PRIMARY_RGB}, 0.1)`;
|
||||
}
|
||||
// Create gradient for fill
|
||||
const gradient = ctx.createLinearGradient(0, 0, 0, chartArea.bottom);
|
||||
gradient.addColorStop(0, 'rgba(255, 166, 77, 0.3)'); // Lighter orange with transparency
|
||||
gradient.addColorStop(0.5, 'rgba(247, 147, 26, 0.2)'); // Bitcoin orange with medium transparency
|
||||
gradient.addColorStop(1, 'rgba(247, 147, 26, 0.05)'); // Bitcoin orange with high transparency
|
||||
gradient.addColorStop(0, `rgba(${theme.PRIMARY_RGB}, 0.3)`);
|
||||
gradient.addColorStop(0.5, `rgba(${theme.PRIMARY_RGB}, 0.2)`);
|
||||
gradient.addColorStop(1, `rgba(${theme.PRIMARY_RGB}, 0.05)`);
|
||||
return gradient;
|
||||
},
|
||||
fill: true,
|
||||
tension: 0.3, // Slightly increase tension for smoother curves
|
||||
tension: 0.3,
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
@ -848,10 +859,10 @@ function initializeChart() {
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'HASHRATE (TH/S)', // Already uppercase
|
||||
color: '#f7931a', // Bitcoin orange
|
||||
text: 'HASHRATE (TH/S)',
|
||||
color: theme.PRIMARY,
|
||||
font: {
|
||||
family: "'VT323', monospace", // Terminal font
|
||||
family: "'VT323', monospace",
|
||||
size: 16,
|
||||
weight: 'bold'
|
||||
}
|
||||
@ -905,7 +916,7 @@ function initializeChart() {
|
||||
plugins: {
|
||||
tooltip: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||
titleColor: '#f7931a',
|
||||
titleColor: theme.PRIMARY,
|
||||
bodyColor: '#FFFFFF',
|
||||
titleFont: {
|
||||
family: "'VT323', monospace",
|
||||
@ -937,10 +948,10 @@ function initializeChart() {
|
||||
type: 'line',
|
||||
yMin: 0,
|
||||
yMax: 0,
|
||||
borderColor: '#ffd700', // Gold color
|
||||
borderColor: theme.CHART.ANNOTATION,
|
||||
borderWidth: 3,
|
||||
borderDash: [8, 4],
|
||||
shadowColor: 'rgba(255, 215, 0, 0.5)',
|
||||
shadowColor: `rgba(${theme.PRIMARY_RGB}, 0.5)`,
|
||||
shadowBlur: 8,
|
||||
shadowOffsetX: 0,
|
||||
shadowOffsetY: 0,
|
||||
@ -948,7 +959,7 @@ function initializeChart() {
|
||||
enabled: true,
|
||||
content: '24HR AVG: 0 TH/S',
|
||||
backgroundColor: 'rgba(0,0,0,0.8)',
|
||||
color: '#ffd700',
|
||||
color: theme.CHART.ANNOTATION,
|
||||
font: {
|
||||
family: "'VT323', monospace",
|
||||
size: 16,
|
||||
@ -1237,20 +1248,21 @@ function updateChartWithNormalizedData(chart, data) {
|
||||
chart.data.datasets[0].data = [normalizedValue];
|
||||
}
|
||||
|
||||
// If using 3hr average due to low hashrate device detection, add visual indicator
|
||||
// In updateChartWithNormalizedData function
|
||||
if (useHashrate3hr) {
|
||||
// Add indicator text to the chart
|
||||
if (!chart.lowHashrateIndicator) {
|
||||
// Create the indicator element if it doesn't exist
|
||||
const graphContainer = document.getElementById('graphContainer');
|
||||
if (graphContainer) {
|
||||
const theme = getCurrentTheme();
|
||||
const indicator = document.createElement('div');
|
||||
indicator.id = 'lowHashrateIndicator';
|
||||
indicator.style.position = 'absolute';
|
||||
indicator.style.bottom = '10px';
|
||||
indicator.style.right = '10px';
|
||||
indicator.style.background = 'rgba(0,0,0,0.7)';
|
||||
indicator.style.color = '#f7931a';
|
||||
indicator.style.color = theme.PRIMARY;
|
||||
indicator.style.padding = '5px 10px';
|
||||
indicator.style.borderRadius = '3px';
|
||||
indicator.style.fontSize = '12px';
|
||||
@ -1261,6 +1273,8 @@ function updateChartWithNormalizedData(chart, data) {
|
||||
chart.lowHashrateIndicator = indicator;
|
||||
}
|
||||
} else {
|
||||
// Update color based on current theme
|
||||
chart.lowHashrateIndicator.style.color = getCurrentTheme().PRIMARY;
|
||||
// Show the indicator if it already exists
|
||||
chart.lowHashrateIndicator.style.display = 'block';
|
||||
}
|
||||
@ -1902,8 +1916,512 @@ function resetDashboardChart() {
|
||||
}
|
||||
}
|
||||
|
||||
// Document ready initialization
|
||||
// Replace your entire function with this version
|
||||
function applyDeepSeaTheme() {
|
||||
// Check if we're already applying the theme to prevent recursion
|
||||
if (isApplyingTheme) {
|
||||
console.log("Theme application already in progress, avoiding recursion");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the guard flag
|
||||
isApplyingTheme = true;
|
||||
|
||||
try {
|
||||
console.log("Applying DeepSea theme...");
|
||||
|
||||
// Create or update CSS variables for the DeepSea theme
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.id = 'deepSeaThemeStyles'; // Give it an ID so we can check if it exists
|
||||
|
||||
// Enhanced CSS with your requested changes
|
||||
styleElement.textContent = `
|
||||
/* Base theme variables */
|
||||
:root {
|
||||
--primary-color: #0088cc !important;
|
||||
--bitcoin-orange: #0088cc !important;
|
||||
--bitcoin-orange-rgb: 0, 136, 204 !important;
|
||||
--bg-gradient: linear-gradient(135deg, #0a0a0a, #131b20) !important;
|
||||
--accent-color: #00b3ff !important;
|
||||
--header-bg: linear-gradient(to right, #0088cc, #005580) !important;
|
||||
--card-header-bg: linear-gradient(to right, #0088cc, #006699) !important;
|
||||
--progress-bar-color: #0088cc !important;
|
||||
--link-color: #0088cc !important;
|
||||
--link-hover-color: #00b3ff !important;
|
||||
|
||||
/* Standardized text shadow values */
|
||||
--blue-text-shadow: 0 0 10px rgba(0, 136, 204, 0.8), 0 0 5px rgba(0, 136, 204, 0.5);
|
||||
--yellow-text-shadow: 0 0 10px rgba(255, 215, 0, 0.8), 0 0 5px rgba(255, 215, 0, 0.5);
|
||||
--green-text-shadow: 0 0 10px rgba(50, 205, 50, 0.8), 0 0 5px rgba(50, 205, 50, 0.5);
|
||||
--red-text-shadow: 0 0 10px rgba(255, 85, 85, 0.8), 0 0 5px rgba(255, 85, 85, 0.5);
|
||||
--white-text-shadow: 0 0 10px rgba(255, 255, 255, 0.8), 0 0 5px rgba(255, 255, 255, 0.5);
|
||||
--cyan-text-shadow: 0 0 10px rgba(0, 255, 255, 0.8), 0 0 5px rgba(0, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* Blue elements - main theme elements */
|
||||
.card-header, .card > .card-header,
|
||||
.container-fluid .card > .card-header {
|
||||
background: linear-gradient(to right, #0088cc, #006699) !important;
|
||||
border-bottom: 1px solid #0088cc !important;
|
||||
text-shadow: var(--blue-text-shadow) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 1px solid #0088cc !important;
|
||||
box-shadow: 0 0 5px rgba(0, 136, 204, 0.3) !important;
|
||||
}
|
||||
|
||||
/* Navigation and interface elements */
|
||||
.nav-link {
|
||||
border: 1px solid #0088cc !important;
|
||||
color: #0088cc !important;
|
||||
}
|
||||
|
||||
.nav-link:hover, .nav-link.active {
|
||||
background-color: #0088cc !important;
|
||||
color: #fff !important;
|
||||
box-shadow: 0 0 10px rgba(0, 136, 204, 0.5) !important;
|
||||
}
|
||||
|
||||
#terminal-cursor {
|
||||
background-color: #0088cc !important;
|
||||
box-shadow: 0 0 5px rgba(0, 136, 204, 0.8) !important;
|
||||
}
|
||||
|
||||
#lastUpdated {
|
||||
color: #0088cc !important;
|
||||
}
|
||||
|
||||
/* Chart and progress elements */
|
||||
.bitcoin-progress-inner {
|
||||
background: linear-gradient(90deg, #0088cc, #00b3ff) !important;
|
||||
}
|
||||
|
||||
.bitcoin-progress-container {
|
||||
border: 1px solid #0088cc !important;
|
||||
box-shadow: 0 0 8px rgba(0, 136, 204, 0.5) !important;
|
||||
}
|
||||
|
||||
h1, .text-center h1 {
|
||||
color: #0088cc !important;
|
||||
text-shadow: var(--blue-text-shadow) !important;
|
||||
}
|
||||
|
||||
.nav-badge {
|
||||
background-color: #0088cc !important;
|
||||
}
|
||||
|
||||
/* ===== COLOR SPECIFIC STYLING ===== */
|
||||
|
||||
/* YELLOW - SATOSHI EARNINGS & BTC PRICE */
|
||||
/* All Satoshi earnings in yellow with consistent text shadow */
|
||||
#daily_mined_sats,
|
||||
#monthly_mined_sats,
|
||||
#estimated_earnings_per_day_sats,
|
||||
#estimated_earnings_next_block_sats,
|
||||
#estimated_rewards_in_window_sats,
|
||||
#btc_price, /* BTC Price in yellow */
|
||||
.card:contains('SATOSHI EARNINGS') span.metric-value {
|
||||
color: #ffd700 !important; /* Bitcoin gold/yellow */
|
||||
text-shadow: var(--yellow-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* More specific selectors for Satoshi values */
|
||||
span.metric-value[id$="_sats"] {
|
||||
color: #ffd700 !important;
|
||||
text-shadow: var(--yellow-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Retaining original yellow for specific elements */
|
||||
.est_time_to_payout:not(.green):not(.red) {
|
||||
color: #ffd700 !important;
|
||||
text-shadow: var(--yellow-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* GREEN - POSITIVE USD VALUES */
|
||||
/* USD earnings that are positive should be green */
|
||||
.metric-value.green,
|
||||
span.green,
|
||||
#daily_revenue:not([style*="color: #ff"]),
|
||||
#monthly_profit_usd:not([style*="color: #ff"]),
|
||||
#daily_profit_usd:not([style*="color: #ff"]) {
|
||||
color: #32CD32 !important; /* Lime green */
|
||||
text-shadow: var(--green-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Status indicators remain green */
|
||||
.status-green {
|
||||
color: #32CD32 !important;
|
||||
text-shadow: var(--green-text-shadow) !important;
|
||||
}
|
||||
|
||||
.online-dot {
|
||||
background: #32CD32 !important;
|
||||
box-shadow: 0 0 10px #32CD32, 0 0 20px #32CD32 !important;
|
||||
}
|
||||
|
||||
/* RED - NEGATIVE USD VALUES & WARNINGS */
|
||||
/* Red for negative values and warnings */
|
||||
.metric-value.red,
|
||||
span.red,
|
||||
.status-red,
|
||||
#daily_power_cost {
|
||||
color: #ff5555 !important;
|
||||
text-shadow: var(--red-text-shadow) !important;
|
||||
}
|
||||
|
||||
.offline-dot {
|
||||
background: #ff5555 !important;
|
||||
box-shadow: 0 0 10px #ff5555, 0 0 20px #ff5555 !important;
|
||||
}
|
||||
|
||||
/* WHITE - Network stats and worker data */
|
||||
#block_number,
|
||||
#difficulty,
|
||||
#network_hashrate,
|
||||
#pool_fees_percentage,
|
||||
#workers_hashing,
|
||||
#last_share,
|
||||
#blocks_found,
|
||||
#last_block_height {
|
||||
color: #ffffff !important;
|
||||
text-shadow: var(--white-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* CYAN - Time ago in last block */
|
||||
#last_block_time {
|
||||
color: #00ffff !important; /* Cyan */
|
||||
text-shadow: var(--cyan-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* BLUE - Pool statistics */
|
||||
#pool_total_hashrate {
|
||||
color: #0088cc !important;
|
||||
text-shadow: var(--blue-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Hashrate values are white */
|
||||
#hashrate_24hr,
|
||||
#hashrate_3hr,
|
||||
#hashrate_10min,
|
||||
#hashrate_60sec {
|
||||
color: white !important;
|
||||
text-shadow: var(--white-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Pool luck/efficiency colors - PRESERVE EXISTING */
|
||||
#pool_luck.very-lucky {
|
||||
color: #32CD32 !important; /* Very lucky - bright green */
|
||||
text-shadow: var(--green-text-shadow) !important;
|
||||
}
|
||||
|
||||
#pool_luck.lucky {
|
||||
color: #90EE90 !important; /* Lucky - light green */
|
||||
text-shadow: 0 0 10px rgba(144, 238, 144, 0.8), 0 0 5px rgba(144, 238, 144, 0.5) !important;
|
||||
}
|
||||
|
||||
#pool_luck.normal-luck {
|
||||
color: #F0E68C !important; /* Normal - khaki */
|
||||
text-shadow: 0 0 10px rgba(240, 230, 140, 0.8), 0 0 5px rgba(240, 230, 140, 0.5) !important;
|
||||
}
|
||||
|
||||
#pool_luck.unlucky {
|
||||
color: #ff5555 !important; /* Unlucky - red */
|
||||
text-shadow: var(--red-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Congrats message */
|
||||
#congratsMessage {
|
||||
background: #0088cc !important;
|
||||
box-shadow: 0 0 15px rgba(0, 136, 204, 0.7) !important;
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@keyframes waitingPulse {
|
||||
0%, 100% { box-shadow: 0 0 10px #0088cc, 0 0 15px #0088cc !important; opacity: 0.8; }
|
||||
50% { box-shadow: 0 0 20px #0088cc, 0 0 35px #0088cc !important; opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes glow {
|
||||
0%, 100% { box-shadow: 0 0 10px #0088cc, 0 0 15px #0088cc !important; }
|
||||
50% { box-shadow: 0 0 15px #0088cc, 0 0 25px #0088cc !important; }
|
||||
}
|
||||
`;
|
||||
|
||||
// Check if our style element already exists
|
||||
const existingStyle = document.getElementById('deepSeaThemeStyles');
|
||||
if (existingStyle) {
|
||||
existingStyle.parentNode.removeChild(existingStyle);
|
||||
}
|
||||
|
||||
// Add our new style element to the head
|
||||
document.head.appendChild(styleElement);
|
||||
|
||||
// Update page title
|
||||
document.title = document.title.replace("BTC-OS", "DeepSea");
|
||||
document.title = document.title.replace("Bitcoin", "DeepSea");
|
||||
|
||||
// Update header text
|
||||
const headerElement = document.querySelector('h1');
|
||||
if (headerElement) {
|
||||
headerElement.innerHTML = headerElement.innerHTML.replace("BTC-OS", "DeepSea");
|
||||
headerElement.innerHTML = headerElement.innerHTML.replace("BITCOIN", "DEEPSEA");
|
||||
}
|
||||
|
||||
console.log("DeepSea theme applied with color adjustments");
|
||||
} finally {
|
||||
// Always reset the guard flag when done, even if there's an error
|
||||
isApplyingTheme = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the function accessible globally so main.js can check for it
|
||||
window.applyDeepSeaTheme = applyDeepSeaTheme;
|
||||
|
||||
$(document).ready(function () {
|
||||
// Apply theme based on stored preference - moved to beginning for better initialization
|
||||
try {
|
||||
const useDeepSea = localStorage.getItem('useDeepSeaTheme') === 'true';
|
||||
if (useDeepSea) {
|
||||
applyDeepSeaTheme();
|
||||
}
|
||||
// Setup theme change listener
|
||||
setupThemeChangeListener();
|
||||
} catch (e) {
|
||||
console.error("Error handling theme:", e);
|
||||
}
|
||||
|
||||
// Modify the initializeChart function to use blue colors for the chart
|
||||
function initializeChart() {
|
||||
try {
|
||||
const ctx = document.getElementById('trendGraph').getContext('2d');
|
||||
if (!ctx) {
|
||||
console.error("Could not find trend graph canvas");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!window.Chart) {
|
||||
console.error("Chart.js not loaded");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the current theme colors
|
||||
const theme = getCurrentTheme();
|
||||
|
||||
// Check if Chart.js plugin is available
|
||||
const hasAnnotationPlugin = window['chartjs-plugin-annotation'] !== undefined;
|
||||
|
||||
return new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [],
|
||||
datasets: [{
|
||||
label: 'HASHRATE TREND (TH/s)',
|
||||
data: [],
|
||||
borderWidth: 2,
|
||||
borderColor: function (context) {
|
||||
const chart = context.chart;
|
||||
const { ctx, chartArea } = chart;
|
||||
if (!chartArea) {
|
||||
return theme.PRIMARY;
|
||||
}
|
||||
// Create gradient for line
|
||||
const gradient = ctx.createLinearGradient(0, 0, 0, chartArea.bottom);
|
||||
gradient.addColorStop(0, theme.CHART.GRADIENT_START);
|
||||
gradient.addColorStop(1, theme.CHART.GRADIENT_END);
|
||||
return gradient;
|
||||
},
|
||||
backgroundColor: function (context) {
|
||||
const chart = context.chart;
|
||||
const { ctx, chartArea } = chart;
|
||||
if (!chartArea) {
|
||||
return `rgba(${theme.PRIMARY_RGB}, 0.1)`;
|
||||
}
|
||||
// Create gradient for fill
|
||||
const gradient = ctx.createLinearGradient(0, 0, 0, chartArea.bottom);
|
||||
gradient.addColorStop(0, `rgba(${theme.PRIMARY_RGB}, 0.3)`);
|
||||
gradient.addColorStop(0.5, `rgba(${theme.PRIMARY_RGB}, 0.2)`);
|
||||
gradient.addColorStop(1, `rgba(${theme.PRIMARY_RGB}, 0.05)`);
|
||||
return gradient;
|
||||
},
|
||||
fill: true,
|
||||
tension: 0.3,
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
animation: {
|
||||
duration: 0 // Disable animations for better performance
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
display: true,
|
||||
ticks: {
|
||||
maxTicksLimit: 8, // Limit number of x-axis labels
|
||||
maxRotation: 0, // Don't rotate labels
|
||||
autoSkip: true, // Automatically skip some labels
|
||||
color: '#FFFFFF',
|
||||
font: {
|
||||
family: "'VT323', monospace", // Terminal font
|
||||
size: 14
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
color: '#333333',
|
||||
lineWidth: 0.5
|
||||
}
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'HASHRATE (TH/S)',
|
||||
color: theme.PRIMARY,
|
||||
font: {
|
||||
family: "'VT323', monospace",
|
||||
size: 16,
|
||||
weight: 'bold'
|
||||
}
|
||||
},
|
||||
ticks: {
|
||||
color: '#FFFFFF',
|
||||
maxTicksLimit: 6, // Limit total number of ticks
|
||||
precision: 1, // Control decimal precision
|
||||
autoSkip: true, // Skip labels to prevent overcrowding
|
||||
autoSkipPadding: 10, // Padding between skipped labels
|
||||
font: {
|
||||
family: "'VT323', monospace", // Terminal font
|
||||
size: 14
|
||||
},
|
||||
callback: function (value) {
|
||||
// For zero, just return 0
|
||||
if (value === 0) return '0';
|
||||
|
||||
// For very large values (1M+)
|
||||
if (value >= 1000000) {
|
||||
return (value / 1000000).toFixed(1) + 'M';
|
||||
}
|
||||
// For large values (1K+)
|
||||
else if (value >= 1000) {
|
||||
return (value / 1000).toFixed(1) + 'K';
|
||||
}
|
||||
// For values between 10 and 1000
|
||||
else if (value >= 10) {
|
||||
return Math.round(value);
|
||||
}
|
||||
// For small values, limit decimal places
|
||||
else if (value >= 1) {
|
||||
return value.toFixed(1);
|
||||
}
|
||||
// For tiny values, use appropriate precision
|
||||
else {
|
||||
return value.toPrecision(2);
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
color: '#333333',
|
||||
lineWidth: 0.5,
|
||||
drawBorder: false,
|
||||
zeroLineColor: '#555555',
|
||||
zeroLineWidth: 1,
|
||||
drawTicks: false
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
tooltip: {
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||
titleColor: theme.PRIMARY,
|
||||
bodyColor: '#FFFFFF',
|
||||
titleFont: {
|
||||
family: "'VT323', monospace",
|
||||
size: 16,
|
||||
weight: 'bold'
|
||||
},
|
||||
bodyFont: {
|
||||
family: "'VT323', monospace",
|
||||
size: 14
|
||||
},
|
||||
padding: 10,
|
||||
cornerRadius: 0,
|
||||
displayColors: false,
|
||||
callbacks: {
|
||||
title: function (tooltipItems) {
|
||||
return tooltipItems[0].label.toUpperCase();
|
||||
},
|
||||
label: function (context) {
|
||||
// Format tooltip values with appropriate unit
|
||||
const value = context.raw;
|
||||
return 'HASHRATE: ' + formatHashrateForDisplay(value).toUpperCase();
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: { display: false },
|
||||
annotation: hasAnnotationPlugin ? {
|
||||
annotations: {
|
||||
averageLine: {
|
||||
type: 'line',
|
||||
yMin: 0,
|
||||
yMax: 0,
|
||||
borderColor: theme.CHART.ANNOTATION,
|
||||
borderWidth: 3,
|
||||
borderDash: [8, 4],
|
||||
shadowColor: `rgba(${theme.PRIMARY_RGB}, 0.5)`,
|
||||
shadowBlur: 8,
|
||||
shadowOffsetX: 0,
|
||||
shadowOffsetY: 0,
|
||||
label: {
|
||||
enabled: true,
|
||||
content: '24HR AVG: 0 TH/S',
|
||||
backgroundColor: 'rgba(0,0,0,0.8)',
|
||||
color: theme.CHART.ANNOTATION,
|
||||
font: {
|
||||
family: "'VT323', monospace",
|
||||
size: 16,
|
||||
weight: 'bold'
|
||||
},
|
||||
padding: { top: 4, bottom: 4, left: 8, right: 8 },
|
||||
borderRadius: 0,
|
||||
position: 'start'
|
||||
}
|
||||
}
|
||||
}
|
||||
} : {}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error initializing chart:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Add this function to the document ready section
|
||||
function setupThemeChangeListener() {
|
||||
// Listen for storage events to detect theme changes from other tabs/windows
|
||||
window.addEventListener('storage', function (event) {
|
||||
if (event.key === 'useDeepSeaTheme') {
|
||||
// Update chart with new theme colors
|
||||
if (trendChart) {
|
||||
// Trigger chart update with new colors
|
||||
trendChart.destroy();
|
||||
trendChart = initializeChart();
|
||||
updateChartWithNormalizedData(trendChart, latestMetrics);
|
||||
}
|
||||
|
||||
// Update other UI elements that depend on theme colors
|
||||
updateRefreshButtonColor();
|
||||
|
||||
// Trigger a custom event that other components can listen to
|
||||
$(document).trigger('themeChanged');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setupThemeChangeListener();
|
||||
|
||||
// Remove the existing refreshUptime container to avoid duplicates
|
||||
$('#refreshUptime').hide();
|
||||
|
||||
@ -2046,6 +2564,14 @@ $(document).ready(function () {
|
||||
}
|
||||
}
|
||||
|
||||
// Update BitcoinProgressBar theme when theme changes
|
||||
$(document).on('themeChanged', function () {
|
||||
if (typeof BitcoinMinuteRefresh !== 'undefined' &&
|
||||
typeof BitcoinMinuteRefresh.updateTheme === 'function') {
|
||||
BitcoinMinuteRefresh.updateTheme();
|
||||
}
|
||||
});
|
||||
|
||||
// Set up event source for SSE
|
||||
setupEventSource();
|
||||
|
||||
@ -2053,8 +2579,8 @@ $(document).ready(function () {
|
||||
updateServerTime();
|
||||
setInterval(updateServerTime, 30000);
|
||||
|
||||
// Add a manual refresh button for fallback
|
||||
$("body").append('<button id="refreshButton" style="position: fixed; bottom: 20px; left: 20px; z-index: 1000; background: #f7931a; color: black; border: none; padding: 8px 16px; display: none; border-radius: 4px; cursor: pointer;">Refresh Data</button>');
|
||||
// Update the manual refresh button color
|
||||
$("body").append('<button id="refreshButton" style="position: fixed; bottom: 20px; left: 20px; z-index: 1000; background: #0088cc; color: white; border: none; padding: 8px 16px; display: none; border-radius: 4px; cursor: pointer;">Refresh Data</button>');
|
||||
|
||||
$("#refreshButton").on("click", function () {
|
||||
$(this).text("Refreshing...");
|
||||
|
404
static/js/theme.js
Normal file
404
static/js/theme.js
Normal file
@ -0,0 +1,404 @@
|
||||
// Bitcoin Orange theme (default)
|
||||
const BITCOIN_THEME = {
|
||||
PRIMARY: '#f2a900',
|
||||
PRIMARY_RGB: '242, 169, 0',
|
||||
SHARED: {
|
||||
GREEN: '#32CD32',
|
||||
RED: '#ff5555',
|
||||
YELLOW: '#ffd700'
|
||||
},
|
||||
CHART: {
|
||||
GRADIENT_START: '#f2a900',
|
||||
GRADIENT_END: 'rgba(242, 169, 0, 0.2)',
|
||||
ANNOTATION: '#ffd700'
|
||||
}
|
||||
};
|
||||
|
||||
// DeepSea theme (blue alternative)
|
||||
const DEEPSEA_THEME = {
|
||||
PRIMARY: '#0088cc',
|
||||
PRIMARY_RGB: '0, 136, 204',
|
||||
SHARED: {
|
||||
GREEN: '#32CD32',
|
||||
RED: '#ff5555',
|
||||
YELLOW: '#ffd700'
|
||||
},
|
||||
CHART: {
|
||||
GRADIENT_START: '#0088cc',
|
||||
GRADIENT_END: 'rgba(0, 136, 204, 0.2)',
|
||||
ANNOTATION: '#00b3ff'
|
||||
}
|
||||
};
|
||||
|
||||
// Global theme constants
|
||||
const THEME = {
|
||||
BITCOIN: BITCOIN_THEME,
|
||||
DEEPSEA: DEEPSEA_THEME,
|
||||
SHARED: BITCOIN_THEME.SHARED
|
||||
};
|
||||
|
||||
// Function to get the current theme based on localStorage setting
|
||||
function getCurrentTheme() {
|
||||
const useDeepSea = localStorage.getItem('useDeepSeaTheme') === 'true';
|
||||
return useDeepSea ? DEEPSEA_THEME : BITCOIN_THEME;
|
||||
}
|
||||
|
||||
// Make globals available
|
||||
window.THEME = THEME;
|
||||
window.getCurrentTheme = getCurrentTheme;
|
||||
|
||||
// Use window-scoped variable to prevent conflicts
|
||||
window.themeProcessing = false;
|
||||
|
||||
// Fixed applyDeepSeaTheme function with recursion protection
|
||||
function applyDeepSeaTheme() {
|
||||
// Check if we're already applying the theme to prevent recursion
|
||||
if (window.themeProcessing) {
|
||||
console.log("Theme application already in progress, avoiding recursion");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the guard flag
|
||||
window.themeProcessing = true;
|
||||
|
||||
try {
|
||||
console.log("Applying DeepSea theme...");
|
||||
|
||||
// Create or update CSS variables for the DeepSea theme
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.id = 'deepSeaThemeStyles'; // Give it an ID so we can check if it exists
|
||||
|
||||
// Enhanced CSS with your requested changes
|
||||
styleElement.textContent = `
|
||||
/* Base theme variables */
|
||||
:root {
|
||||
--primary-color: #0088cc !important;
|
||||
--bitcoin-orange: #0088cc !important;
|
||||
--bitcoin-orange-rgb: 0, 136, 204 !important;
|
||||
--bg-gradient: linear-gradient(135deg, #0a0a0a, #131b20) !important;
|
||||
--accent-color: #00b3ff !important;
|
||||
--header-bg: linear-gradient(to right, #0088cc, #005580) !important;
|
||||
--card-header-bg: linear-gradient(to right, #0088cc, #006699) !important;
|
||||
--progress-bar-color: #0088cc !important;
|
||||
--link-color: #0088cc !important;
|
||||
--link-hover-color: #00b3ff !important;
|
||||
|
||||
/* Standardized text shadow values */
|
||||
--blue-text-shadow: 0 0 10px rgba(0, 136, 204, 0.8), 0 0 5px rgba(0, 136, 204, 0.5);
|
||||
--yellow-text-shadow: 0 0 10px rgba(255, 215, 0, 0.8), 0 0 5px rgba(255, 215, 0, 0.5);
|
||||
--green-text-shadow: 0 0 10px rgba(50, 205, 50, 0.8), 0 0 5px rgba(50, 205, 50, 0.5);
|
||||
--red-text-shadow: 0 0 10px rgba(255, 85, 85, 0.8), 0 0 5px rgba(255, 85, 85, 0.5);
|
||||
--white-text-shadow: 0 0 10px rgba(255, 255, 255, 0.8), 0 0 5px rgba(255, 255, 255, 0.5);
|
||||
--cyan-text-shadow: 0 0 10px rgba(0, 255, 255, 0.8), 0 0 5px rgba(0, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* Blue elements - main theme elements */
|
||||
.card-header, .card > .card-header,
|
||||
.container-fluid .card > .card-header {
|
||||
background: linear-gradient(to right, #0088cc, #006699) !important;
|
||||
border-bottom: 1px solid #0088cc !important;
|
||||
text-shadow: var(--blue-text-shadow) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.card {
|
||||
border: 1px solid #0088cc !important;
|
||||
box-shadow: 0 0 5px rgba(0, 136, 204, 0.3) !important;
|
||||
}
|
||||
|
||||
/* Navigation and interface elements */
|
||||
.nav-link {
|
||||
border: 1px solid #0088cc !important;
|
||||
color: #0088cc !important;
|
||||
}
|
||||
|
||||
.nav-link:hover, .nav-link.active {
|
||||
background-color: #0088cc !important;
|
||||
color: #fff !important;
|
||||
box-shadow: 0 0 10px rgba(0, 136, 204, 0.5) !important;
|
||||
}
|
||||
|
||||
#terminal-cursor {
|
||||
background-color: #0088cc !important;
|
||||
box-shadow: 0 0 5px rgba(0, 136, 204, 0.8) !important;
|
||||
}
|
||||
|
||||
#lastUpdated {
|
||||
color: #0088cc !important;
|
||||
}
|
||||
|
||||
/* Chart and progress elements */
|
||||
.bitcoin-progress-inner {
|
||||
background: linear-gradient(90deg, #0088cc, #00b3ff) !important;
|
||||
}
|
||||
|
||||
.bitcoin-progress-container {
|
||||
border: 1px solid #0088cc !important;
|
||||
box-shadow: 0 0 8px rgba(0, 136, 204, 0.5) !important;
|
||||
}
|
||||
|
||||
h1, .text-center h1 {
|
||||
color: #0088cc !important;
|
||||
text-shadow: var(--blue-text-shadow) !important;
|
||||
}
|
||||
|
||||
.nav-badge {
|
||||
background-color: #0088cc !important;
|
||||
}
|
||||
|
||||
/* Theme toggle button styling */
|
||||
#themeToggle,
|
||||
button.theme-toggle,
|
||||
.toggle-theme-btn {
|
||||
background: transparent !important;
|
||||
border: 1px solid #0088cc !important;
|
||||
color: #0088cc !important;
|
||||
transition: all 0.3s ease !important;
|
||||
}
|
||||
|
||||
#themeToggle:hover,
|
||||
button.theme-toggle:hover,
|
||||
.toggle-theme-btn:hover {
|
||||
background-color: rgba(0, 136, 204, 0.1) !important;
|
||||
box-shadow: 0 0 10px rgba(0, 136, 204, 0.3) !important;
|
||||
}
|
||||
|
||||
/* ===== COLOR SPECIFIC STYLING ===== */
|
||||
|
||||
/* YELLOW - SATOSHI EARNINGS & BTC PRICE */
|
||||
/* All Satoshi earnings in yellow with consistent text shadow */
|
||||
#daily_mined_sats,
|
||||
#monthly_mined_sats,
|
||||
#estimated_earnings_per_day_sats,
|
||||
#estimated_earnings_next_block_sats,
|
||||
#estimated_rewards_in_window_sats,
|
||||
#btc_price, /* BTC Price in yellow */
|
||||
.card:contains('SATOSHI EARNINGS') span.metric-value {
|
||||
color: #ffd700 !important; /* Bitcoin gold/yellow */
|
||||
text-shadow: var(--yellow-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* More specific selectors for Satoshi values */
|
||||
span.metric-value[id$="_sats"] {
|
||||
color: #ffd700 !important;
|
||||
text-shadow: var(--yellow-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Retaining original yellow for specific elements */
|
||||
.est_time_to_payout:not(.green):not(.red) {
|
||||
color: #ffd700 !important;
|
||||
text-shadow: var(--yellow-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* GREEN - POSITIVE USD VALUES */
|
||||
/* USD earnings that are positive should be green */
|
||||
.metric-value.green,
|
||||
span.green,
|
||||
#daily_revenue:not([style*="color: #ff"]),
|
||||
#monthly_profit_usd:not([style*="color: #ff"]),
|
||||
#daily_profit_usd:not([style*="color: #ff"]) {
|
||||
color: #32CD32 !important; /* Lime green */
|
||||
text-shadow: var(--green-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Status indicators remain green */
|
||||
.status-green {
|
||||
color: #32CD32 !important;
|
||||
text-shadow: var(--green-text-shadow) !important;
|
||||
}
|
||||
|
||||
.online-dot {
|
||||
background: #32CD32 !important;
|
||||
box-shadow: 0 0 10px #32CD32, 0 0 20px #32CD32 !important;
|
||||
}
|
||||
|
||||
/* RED - NEGATIVE USD VALUES & WARNINGS */
|
||||
/* Red for negative values and warnings */
|
||||
.metric-value.red,
|
||||
span.red,
|
||||
.status-red,
|
||||
#daily_power_cost {
|
||||
color: #ff5555 !important;
|
||||
text-shadow: var(--red-text-shadow) !important;
|
||||
}
|
||||
|
||||
.offline-dot {
|
||||
background: #ff5555 !important;
|
||||
box-shadow: 0 0 10px #ff5555, 0 0 20px #ff5555 !important;
|
||||
}
|
||||
|
||||
/* WHITE - Network stats and worker data */
|
||||
#block_number,
|
||||
#difficulty,
|
||||
#network_hashrate,
|
||||
#pool_fees_percentage,
|
||||
#workers_hashing,
|
||||
#last_share,
|
||||
#blocks_found,
|
||||
#last_block_height {
|
||||
color: #ffffff !important;
|
||||
text-shadow: var(--white-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* CYAN - Time ago in last block */
|
||||
#last_block_time {
|
||||
color: #00ffff !important; /* Cyan */
|
||||
text-shadow: var(--cyan-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* BLUE - Pool statistics */
|
||||
#pool_total_hashrate {
|
||||
color: #0088cc !important;
|
||||
text-shadow: var(--blue-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Hashrate values are white */
|
||||
#hashrate_24hr,
|
||||
#hashrate_3hr,
|
||||
#hashrate_10min,
|
||||
#hashrate_60sec {
|
||||
color: white !important;
|
||||
text-shadow: var(--white-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Pool luck/efficiency colors - PRESERVE EXISTING */
|
||||
#pool_luck.very-lucky {
|
||||
color: #32CD32 !important; /* Very lucky - bright green */
|
||||
text-shadow: var(--green-text-shadow) !important;
|
||||
}
|
||||
|
||||
#pool_luck.lucky {
|
||||
color: #90EE90 !important; /* Lucky - light green */
|
||||
text-shadow: 0 0 10px rgba(144, 238, 144, 0.8), 0 0 5px rgba(144, 238, 144, 0.5) !important;
|
||||
}
|
||||
|
||||
#pool_luck.normal-luck {
|
||||
color: #F0E68C !important; /* Normal - khaki */
|
||||
text-shadow: 0 0 10px rgba(240, 230, 140, 0.8), 0 0 5px rgba(240, 230, 140, 0.5) !important;
|
||||
}
|
||||
|
||||
#pool_luck.unlucky {
|
||||
color: #ff5555 !important; /* Unlucky - red */
|
||||
text-shadow: var(--red-text-shadow) !important;
|
||||
}
|
||||
|
||||
/* Congrats message */
|
||||
#congratsMessage {
|
||||
background: #0088cc !important;
|
||||
box-shadow: 0 0 15px rgba(0, 136, 204, 0.7) !important;
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@keyframes waitingPulse {
|
||||
0%, 100% { box-shadow: 0 0 10px #0088cc, 0 0 15px #0088cc !important; opacity: 0.8; }
|
||||
50% { box-shadow: 0 0 20px #0088cc, 0 0 35px #0088cc !important; opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes glow {
|
||||
0%, 100% { box-shadow: 0 0 10px #0088cc, 0 0 15px #0088cc !important; }
|
||||
50% { box-shadow: 0 0 15px #0088cc, 0 0 25px #0088cc !important; }
|
||||
}
|
||||
`;
|
||||
|
||||
// Check if our style element already exists
|
||||
const existingStyle = document.getElementById('deepSeaThemeStyles');
|
||||
if (existingStyle) {
|
||||
existingStyle.parentNode.removeChild(existingStyle);
|
||||
}
|
||||
|
||||
// Add our new style element to the head
|
||||
document.head.appendChild(styleElement);
|
||||
|
||||
// Update page title
|
||||
document.title = document.title.replace("BTC-OS", "DeepSea");
|
||||
document.title = document.title.replace("Bitcoin", "DeepSea");
|
||||
|
||||
// Update header text
|
||||
const headerElement = document.querySelector('h1');
|
||||
if (headerElement) {
|
||||
headerElement.innerHTML = headerElement.innerHTML.replace("BTC-OS", "DeepSea");
|
||||
headerElement.innerHTML = headerElement.innerHTML.replace("BITCOIN", "DEEPSEA");
|
||||
}
|
||||
|
||||
// Update theme toggle button
|
||||
const themeToggle = document.getElementById('themeToggle');
|
||||
if (themeToggle) {
|
||||
themeToggle.style.borderColor = '#0088cc';
|
||||
themeToggle.style.color = '#0088cc';
|
||||
}
|
||||
|
||||
console.log("DeepSea theme applied with color adjustments");
|
||||
} finally {
|
||||
// Always reset the guard flag when done, even if there's an error
|
||||
window.themeProcessing = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Make the function accessible globally
|
||||
window.applyDeepSeaTheme = applyDeepSeaTheme;
|
||||
|
||||
// Toggle theme with hard page refresh
|
||||
function toggleTheme() {
|
||||
const useDeepSea = localStorage.getItem('useDeepSeaTheme') !== 'true';
|
||||
|
||||
// Save the new theme preference
|
||||
saveThemePreference(useDeepSea);
|
||||
|
||||
// Show a brief loading message to indicate theme change is happening
|
||||
const loadingMessage = document.createElement('div');
|
||||
loadingMessage.style.position = 'fixed';
|
||||
loadingMessage.style.top = '0';
|
||||
loadingMessage.style.left = '0';
|
||||
loadingMessage.style.width = '100%';
|
||||
loadingMessage.style.height = '100%';
|
||||
loadingMessage.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
|
||||
loadingMessage.style.display = 'flex';
|
||||
loadingMessage.style.justifyContent = 'center';
|
||||
loadingMessage.style.alignItems = 'center';
|
||||
loadingMessage.style.zIndex = '9999';
|
||||
loadingMessage.style.color = useDeepSea ? '#0088cc' : '#f2a900';
|
||||
loadingMessage.style.fontFamily = "'VT323', monospace";
|
||||
loadingMessage.style.fontSize = '24px';
|
||||
loadingMessage.innerHTML = '<div style="background-color: rgba(0, 0, 0, 0.8); padding: 20px; border-radius: 5px;">APPLYING ' + (useDeepSea ? 'DEEPSEA' : 'BITCOIN') + ' THEME...</div>';
|
||||
document.body.appendChild(loadingMessage);
|
||||
|
||||
// Short delay before refreshing to allow the message to be seen
|
||||
setTimeout(() => {
|
||||
// Hard reload the page
|
||||
window.location.reload();
|
||||
}, 300);
|
||||
}
|
||||
|
||||
// Set theme preference to localStorage
|
||||
function saveThemePreference(useDeepSea) {
|
||||
try {
|
||||
localStorage.setItem('useDeepSeaTheme', useDeepSea);
|
||||
} catch (e) {
|
||||
console.error("Error saving theme preference:", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for theme preference in localStorage
|
||||
function loadThemePreference() {
|
||||
try {
|
||||
const themePreference = localStorage.getItem('useDeepSeaTheme');
|
||||
if (themePreference === 'true') {
|
||||
applyDeepSeaTheme();
|
||||
} else {
|
||||
// Make sure the toggle button is styled correctly for Bitcoin theme
|
||||
const themeToggle = document.getElementById('themeToggle');
|
||||
if (themeToggle) {
|
||||
themeToggle.style.borderColor = '#f2a900';
|
||||
themeToggle.style.color = '#f2a900';
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error loading theme preference:", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply theme on page load
|
||||
document.addEventListener('DOMContentLoaded', loadThemePreference);
|
||||
|
||||
// For pages that load content dynamically, also check when the window loads
|
||||
window.addEventListener('load', loadThemePreference);
|
@ -17,8 +17,25 @@
|
||||
<!-- Common CSS -->
|
||||
<link rel="stylesheet" href="/static/css/common.css">
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||
|
||||
<!-- Theme JS (added to ensure consistent application of theme) -->
|
||||
<script src="/static/js/theme.js"></script>
|
||||
|
||||
<!-- Page-specific CSS -->
|
||||
{% block css %}{% endblock %}
|
||||
|
||||
<style>
|
||||
.footer {
|
||||
margin-top: 30px;
|
||||
padding: 10px 0;
|
||||
color: grey;
|
||||
font-size: 0.9rem;
|
||||
text-shadow: 0 0 5px rgba(100, 100, 100, 0.3);
|
||||
border-top: 1px solid rgba(128, 128, 128, 0.2);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
@ -34,6 +51,11 @@
|
||||
<!-- Top right link -->
|
||||
<a href="https://x.com/DJObleezy" id="topRightLink" target="_blank" rel="noopener noreferrer">MADE BY @DJO₿LEEZY</a>
|
||||
|
||||
<!-- Theme toggle button (new) -->
|
||||
<button id="themeToggle" class="theme-toggle-btn">
|
||||
<span>Toggle Theme</span>
|
||||
</button>
|
||||
|
||||
{% block last_updated %}
|
||||
<p class="text-center" id="lastUpdated" style="color: #f7931a; text-transform: uppercase;"><strong>LAST UPDATED:</strong> {{ current_time }}<span id="terminal-cursor"></span></p>
|
||||
{% endblock %}
|
||||
@ -57,6 +79,11 @@
|
||||
{% block congrats_message %}
|
||||
<div id="congratsMessage" style="display:none; position: fixed; top: 20px; left: 50%; transform: translateX(-50%); z-index: 1000; background: #f7931a; color: #000; padding: 10px; border-radius: 5px; box-shadow: 0 0 15px rgba(247, 147, 26, 0.7);"></div>
|
||||
{% endblock %}
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer text-center">
|
||||
<p>Not affiliated with Ocean.xyz</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- External JavaScript libraries -->
|
||||
@ -64,6 +91,32 @@
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@1.1.0"></script>
|
||||
|
||||
<!-- Theme toggle initialization -->
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Initialize theme toggle button based on current theme
|
||||
const themeToggle = document.getElementById('themeToggle');
|
||||
if (themeToggle) {
|
||||
// Check current theme
|
||||
const isDeepSea = localStorage.getItem('useDeepSeaTheme') === 'true';
|
||||
|
||||
// Update button style based on theme
|
||||
if (isDeepSea) {
|
||||
themeToggle.style.borderColor = '#0088cc';
|
||||
themeToggle.style.color = '#0088cc';
|
||||
} else {
|
||||
themeToggle.style.borderColor = '#f2a900';
|
||||
themeToggle.style.color = '#f2a900';
|
||||
}
|
||||
|
||||
// Add click event listener
|
||||
themeToggle.addEventListener('click', function () {
|
||||
toggleTheme(); // This will now trigger a page refresh
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Page-specific JavaScript -->
|
||||
{% block javascript %}{% endblock %}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
{% block css %}
|
||||
<link rel="stylesheet" href="/static/css/blocks.css">
|
||||
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}BLOCKCHAIN MONITOR v 0.1{% endblock %}
|
||||
|
@ -6,25 +6,122 @@
|
||||
<title>Ocean.xyz Pool Miner - Initializing...</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/static/css/boot.css">
|
||||
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||
<!-- Add Theme JS -->
|
||||
<script src="/static/js/theme.js"></script>
|
||||
<style>
|
||||
/* Added styles for configuration form */
|
||||
/* Config form styling - fixed width and hidden by default */
|
||||
#config-form {
|
||||
display: none;
|
||||
margin-top: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
width: 500px;
|
||||
max-width: 90%;
|
||||
margin: 30px auto;
|
||||
padding: 20px;
|
||||
background-color: #0d0d0d;
|
||||
border: 1px solid #f7931a;
|
||||
padding: 15px;
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
box-shadow: 0 0 10px rgba(247, 147, 26, 0.5);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.config-title {
|
||||
/* Boot text color - updated with theme toggling */
|
||||
body:not(.deepsea-theme) #terminal,
|
||||
body:not(.deepsea-theme) #output,
|
||||
body:not(.deepsea-theme) #prompt-container,
|
||||
body:not(.deepsea-theme) #prompt-text,
|
||||
body:not(.deepsea-theme) #user-input,
|
||||
body:not(.deepsea-theme) #loading-message {
|
||||
color: #f7931a;
|
||||
font-size: 22px;
|
||||
text-shadow: 0 0 5px rgba(247, 147, 26, 0.4);
|
||||
}
|
||||
|
||||
/* DeepSea theme text color */
|
||||
body.deepsea-theme #terminal,
|
||||
body.deepsea-theme #output,
|
||||
body.deepsea-theme #prompt-container,
|
||||
body.deepsea-theme #prompt-text,
|
||||
body.deepsea-theme #user-input,
|
||||
body.deepsea-theme #loading-message {
|
||||
color: #0088cc;
|
||||
text-shadow: 0 0 5px rgba(0, 136, 204, 0.4);
|
||||
}
|
||||
|
||||
/* DeepSea cursor color */
|
||||
body.deepsea-theme .cursor,
|
||||
body.deepsea-theme .prompt-cursor {
|
||||
background-color: #0088cc;
|
||||
box-shadow: 0 0 5px rgba(0, 136, 204, 0.8);
|
||||
}
|
||||
|
||||
/* Boot-specific DeepSea theme adjustments */
|
||||
body.deepsea-theme #bitcoin-logo {
|
||||
color: #0088cc;
|
||||
border-color: #0088cc;
|
||||
text-shadow: 0 0 10px rgba(0, 136, 204, 0.5);
|
||||
box-shadow: 0 0 15px rgba(0, 136, 204, 0.5);
|
||||
}
|
||||
|
||||
body.deepsea-theme #config-form {
|
||||
border: 1px solid #0088cc;
|
||||
box-shadow: 0 0 10px rgba(0, 136, 204, 0.5);
|
||||
}
|
||||
|
||||
body.deepsea-theme .config-title {
|
||||
color: #0088cc;
|
||||
text-shadow: 0 0 8px rgba(0, 136, 204, 0.8);
|
||||
}
|
||||
|
||||
body.deepsea-theme .form-group label {
|
||||
color: #0088cc;
|
||||
}
|
||||
|
||||
body.deepsea-theme .form-group input,
|
||||
body.deepsea-theme .form-group select {
|
||||
border: 1px solid #0088cc;
|
||||
}
|
||||
|
||||
body.deepsea-theme .form-group input:focus,
|
||||
body.deepsea-theme .form-group select:focus {
|
||||
box-shadow: 0 0 5px #0088cc;
|
||||
}
|
||||
|
||||
body.deepsea-theme .btn {
|
||||
background-color: #0088cc;
|
||||
}
|
||||
|
||||
body.deepsea-theme .btn:hover {
|
||||
background-color: #00b3ff;
|
||||
}
|
||||
|
||||
body.deepsea-theme .btn-secondary {
|
||||
background-color: #333;
|
||||
color: #0088cc;
|
||||
}
|
||||
|
||||
body.deepsea-theme .tooltip .tooltip-text {
|
||||
border: 1px solid #0088cc;
|
||||
}
|
||||
|
||||
body.deepsea-theme .form-group select {
|
||||
background-image: linear-gradient(45deg, transparent 50%, #0088cc 50%), linear-gradient(135deg, #0088cc 50%, transparent 50%);
|
||||
}
|
||||
|
||||
/* DeepSea skip button */
|
||||
body.deepsea-theme #skip-button {
|
||||
background-color: #0088cc;
|
||||
box-shadow: 0 0 8px rgba(0, 136, 204, 0.5);
|
||||
}
|
||||
|
||||
body.deepsea-theme #skip-button:hover {
|
||||
background-color: #00b3ff;
|
||||
box-shadow: 0 0 12px rgba(0, 136, 204, 0.7);
|
||||
}
|
||||
|
||||
/* Original Bitcoin styling preserved by default */
|
||||
.config-title {
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
margin-bottom: 20px;
|
||||
color: #f7931a;
|
||||
text-shadow: 0 0 8px rgba(247, 147, 26, 0.8);
|
||||
}
|
||||
|
||||
@ -38,17 +135,19 @@
|
||||
color: #f7931a;
|
||||
}
|
||||
|
||||
.form-group input {
|
||||
.form-group input,
|
||||
.form-group select {
|
||||
width: 100%;
|
||||
background-color: #111;
|
||||
border: 1px solid #f7931a;
|
||||
padding: 8px;
|
||||
color: white;
|
||||
background-color: #0d0d0d;
|
||||
border: 1px solid #f7931a;
|
||||
color: #fff;
|
||||
font-family: 'VT323', monospace;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.form-group input:focus {
|
||||
.form-group input:focus,
|
||||
.form-group select:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 5px #f7931a;
|
||||
}
|
||||
@ -60,19 +159,17 @@
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 8px 16px;
|
||||
background-color: #f7931a;
|
||||
color: #000;
|
||||
border: none;
|
||||
color: black;
|
||||
padding: 8px 15px;
|
||||
cursor: pointer;
|
||||
font-family: 'VT323', monospace;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
min-width: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: #ffa642;
|
||||
background-color: #ffa32e;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@ -80,79 +177,10 @@
|
||||
color: #f7931a;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
/* Make skip button more mobile-friendly */
|
||||
#skip-button {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
z-index: 1000;
|
||||
padding: 12px 20px;
|
||||
font-size: 18px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
#skip-button {
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
padding: 15px 25px;
|
||||
font-size: 20px; /* Larger font size for better tap targets */
|
||||
border-radius: 10px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tooltip styles */
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.tooltip .tooltip-text {
|
||||
visibility: hidden;
|
||||
width: 200px;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border: 1px solid #f7931a;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
bottom: 125%;
|
||||
left: 50%;
|
||||
margin-left: -100px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tooltip:hover .tooltip-text {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Form success/error message */
|
||||
#form-message {
|
||||
margin-top: 10px;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
margin-top: 15px;
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -168,60 +196,63 @@
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
/* Add these styles to match the timezone dropdown with your other inputs */
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background-color: #333;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
text-align: center;
|
||||
line-height: 14px;
|
||||
font-size: 10px;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.tooltip .tooltip-text {
|
||||
visibility: hidden;
|
||||
width: 200px;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
bottom: 125%;
|
||||
left: 50%;
|
||||
margin-left: -100px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
font-size: 14px;
|
||||
border: 1px solid #f7931a;
|
||||
}
|
||||
|
||||
.tooltip:hover .tooltip-text {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Style the select dropdown with custom arrow */
|
||||
.form-group select {
|
||||
width: 100%;
|
||||
background-color: #111;
|
||||
border: 1px solid #f7931a;
|
||||
padding: 8px;
|
||||
color: white;
|
||||
font-family: 'VT323', monospace;
|
||||
font-size: 18px;
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Add a custom dropdown arrow */
|
||||
.form-group select {
|
||||
background-image: linear-gradient(45deg, transparent 50%, #f7931a 50%), linear-gradient(135deg, #f7931a 50%, transparent 50%);
|
||||
background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%;
|
||||
background-position: calc(100% - 15px) calc(1em + 0px), calc(100% - 10px) calc(1em + 0px);
|
||||
background-size: 5px 5px, 5px 5px;
|
||||
background-repeat: no-repeat;
|
||||
padding-right: 25px; /* Space for the arrow */
|
||||
}
|
||||
|
||||
.form-group select:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 5px #f7931a;
|
||||
}
|
||||
|
||||
/* Style the option groups */
|
||||
.form-group select optgroup {
|
||||
background-color: #111;
|
||||
color: #f7931a;
|
||||
font-family: 'VT323', monospace;
|
||||
}
|
||||
|
||||
/* Style the options */
|
||||
.form-group select option {
|
||||
background-color: #222;
|
||||
color: white;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* Improve mobile appearance */
|
||||
@media (max-width: 768px) {
|
||||
.form-group select {
|
||||
padding: 12px;
|
||||
padding-right: 30px; /* More space for the dropdown arrow */
|
||||
font-size: 20px;
|
||||
}
|
||||
padding-right: 30px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Theme toggle button (new) -->
|
||||
<button id="themeToggle" class="theme-toggle-btn">
|
||||
<span>Toggle Theme</span>
|
||||
</button>
|
||||
<button id="skip-button">SKIP</button>
|
||||
<div id="debug-info"></div>
|
||||
<div id="loading-message">Loading mining data...</div>
|
||||
@ -232,7 +263,7 @@
|
||||
██╔══██╗ ██║ ██║ ██║ ██║╚════██║
|
||||
██████╔╝ ██║ ╚██████╗ ╚██████╔╝███████║
|
||||
╚═════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
|
||||
v.21
|
||||
v.21
|
||||
</div>
|
||||
<div id="terminal">
|
||||
<div id="terminal-content">
|
||||
@ -322,6 +353,45 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Theme toggle initialization
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Initialize theme toggle button based on current theme
|
||||
const themeToggle = document.getElementById('themeToggle');
|
||||
if (themeToggle) {
|
||||
// Check current theme
|
||||
const isDeepSea = localStorage.getItem('useDeepSeaTheme') === 'true';
|
||||
|
||||
// Update button style based on theme
|
||||
if (isDeepSea) {
|
||||
document.body.classList.add('deepsea-theme');
|
||||
themeToggle.style.borderColor = '#0088cc';
|
||||
themeToggle.style.color = '#0088cc';
|
||||
} else {
|
||||
document.body.classList.remove('deepsea-theme');
|
||||
themeToggle.style.borderColor = '#f2a900';
|
||||
themeToggle.style.color = '#f2a900';
|
||||
}
|
||||
|
||||
// Add click event listener
|
||||
themeToggle.addEventListener('click', function () {
|
||||
toggleTheme(); // This will now trigger a page refresh
|
||||
});
|
||||
}
|
||||
|
||||
// Update terminal colors based on theme (boot.html specific)
|
||||
function updateTerminalColors() {
|
||||
const isDeepSeaTheme = localStorage.getItem('useDeepSeaTheme') === 'true';
|
||||
if (isDeepSeaTheme) {
|
||||
document.body.classList.add('deepsea-theme');
|
||||
} else {
|
||||
document.body.classList.remove('deepsea-theme');
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize terminal colors
|
||||
updateTerminalColors();
|
||||
});
|
||||
|
||||
// Add a function to populate all available timezones
|
||||
function populateTimezones() {
|
||||
const otherTimezones = document.getElementById('other-timezones');
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
{% block css %}
|
||||
<link rel="stylesheet" href="/static/css/dashboard.css">
|
||||
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||
{% endblock %}
|
||||
|
||||
{% block dashboard_active %}active{% endblock %}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
{% block css %}
|
||||
<link rel="stylesheet" href="/static/css/notifications.css">
|
||||
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}NOTIFICATION CENTER v 0.1{% endblock %}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
{% block css %}
|
||||
<link rel="stylesheet" href="/static/css/workers.css">
|
||||
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}WORKERS OVERVIEW{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user