mirror of
https://github.com/Retropex/custom-ocean.xyz-dashboard.git
synced 2025-05-12 19:20:45 +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
|
* BitcoinMinuteRefresh.js - Simplified Bitcoin-themed floating uptime monitor
|
||||||
*
|
*
|
||||||
* This module creates a Bitcoin-themed terminal that shows server uptime.
|
* This module creates a Bitcoin-themed terminal that shows server uptime.
|
||||||
|
* Now includes DeepSea theme support.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const BitcoinMinuteRefresh = (function () {
|
const BitcoinMinuteRefresh = (function () {
|
||||||
// Constants
|
// Constants
|
||||||
const STORAGE_KEY = 'bitcoin_last_refresh_time'; // For cross-page sync
|
const STORAGE_KEY = 'bitcoin_last_refresh_time'; // For cross-page sync
|
||||||
|
const BITCOIN_COLOR = '#f7931a';
|
||||||
|
const DEEPSEA_COLOR = '#0088cc';
|
||||||
|
|
||||||
// Private variables
|
// Private variables
|
||||||
let terminalElement = null;
|
let terminalElement = null;
|
||||||
@ -16,6 +19,117 @@ const BitcoinMinuteRefresh = (function () {
|
|||||||
let uptimeInterval = null;
|
let uptimeInterval = null;
|
||||||
let isInitialized = false;
|
let isInitialized = false;
|
||||||
let refreshCallback = null;
|
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
|
* Add dragging functionality to the terminal
|
||||||
@ -200,6 +314,7 @@ const BitcoinMinuteRefresh = (function () {
|
|||||||
* Add CSS styles for the terminal
|
* Add CSS styles for the terminal
|
||||||
*/
|
*/
|
||||||
function addStyles() {
|
function addStyles() {
|
||||||
|
// Use the currentThemeColor variable instead of hardcoded colors
|
||||||
const styleElement = document.createElement('style');
|
const styleElement = document.createElement('style');
|
||||||
styleElement.id = 'bitcoin-terminal-styles';
|
styleElement.id = 'bitcoin-terminal-styles';
|
||||||
styleElement.textContent = `
|
styleElement.textContent = `
|
||||||
@ -210,14 +325,14 @@ const BitcoinMinuteRefresh = (function () {
|
|||||||
right: 20px;
|
right: 20px;
|
||||||
width: 230px;
|
width: 230px;
|
||||||
background-color: #000000;
|
background-color: #000000;
|
||||||
border: 1px solid #f7931a;
|
border: 1px solid ${currentThemeColor};
|
||||||
color: #f7931a;
|
color: ${currentThemeColor};
|
||||||
font-family: 'VT323', monospace;
|
font-family: 'VT323', monospace;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
transition: all 0.3s ease;
|
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 */
|
/* Terminal Header */
|
||||||
@ -616,6 +731,9 @@ const BitcoinMinuteRefresh = (function () {
|
|||||||
// Store the refresh callback
|
// Store the refresh callback
|
||||||
refreshCallback = refreshFunc;
|
refreshCallback = refreshFunc;
|
||||||
|
|
||||||
|
// Get current theme status
|
||||||
|
applyThemeColor();
|
||||||
|
|
||||||
// Create the terminal element if it doesn't exist
|
// Create the terminal element if it doesn't exist
|
||||||
if (!document.getElementById('bitcoin-terminal')) {
|
if (!document.getElementById('bitcoin-terminal')) {
|
||||||
createTerminalElement();
|
createTerminalElement();
|
||||||
@ -623,8 +741,14 @@ const BitcoinMinuteRefresh = (function () {
|
|||||||
// Get references to existing elements
|
// Get references to existing elements
|
||||||
terminalElement = document.getElementById('bitcoin-terminal');
|
terminalElement = document.getElementById('bitcoin-terminal');
|
||||||
uptimeElement = document.getElementById('uptime-timer');
|
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 to get stored server time information
|
||||||
try {
|
try {
|
||||||
serverTimeOffset = parseFloat(localStorage.getItem('serverTimeOffset') || '0');
|
serverTimeOffset = parseFloat(localStorage.getItem('serverTimeOffset') || '0');
|
||||||
@ -766,11 +890,12 @@ const BitcoinMinuteRefresh = (function () {
|
|||||||
updateServerTime: updateServerTime,
|
updateServerTime: updateServerTime,
|
||||||
toggleTerminal: toggleTerminal,
|
toggleTerminal: toggleTerminal,
|
||||||
hideTerminal: hideTerminal,
|
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 () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
// Check if manualRefresh function exists in global scope
|
// Check if manualRefresh function exists in global scope
|
||||||
if (typeof window.manualRefresh === 'function') {
|
if (typeof window.manualRefresh === 'function') {
|
||||||
@ -778,4 +903,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
} else {
|
} else {
|
||||||
console.log("BitcoinMinuteRefresh: No refresh function found, will need to be initialized manually");
|
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
|
* 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
|
// Get normalized values and compare with previous metrics
|
||||||
for (const key of metricKeys) {
|
for (const key of metricKeys) {
|
||||||
if (newMetrics[key] === undefined) continue;
|
if (newMetrics[key] === undefined) continue;
|
||||||
@ -714,15 +722,16 @@ function handleVisibilityChange() {
|
|||||||
|
|
||||||
// Helper function to show connection issues to the user
|
// Helper function to show connection issues to the user
|
||||||
function showConnectionIssue(message) {
|
function showConnectionIssue(message) {
|
||||||
|
const theme = getCurrentTheme();
|
||||||
let $connectionStatus = $("#connectionStatus");
|
let $connectionStatus = $("#connectionStatus");
|
||||||
if (!$connectionStatus.length) {
|
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 = $("#connectionStatus");
|
||||||
}
|
}
|
||||||
$connectionStatus.html(`<i class="fas fa-exclamation-triangle"></i> ${message}`).show();
|
$connectionStatus.html(`<i class="fas fa-exclamation-triangle"></i> ${message}`).show();
|
||||||
|
|
||||||
// Show manual refresh button when there are connection issues
|
// Show manual refresh button with theme color
|
||||||
$("#refreshButton").show();
|
$("#refreshButton").css('background-color', theme.PRIMARY).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to hide connection issue message
|
// 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() {
|
function initializeChart() {
|
||||||
try {
|
try {
|
||||||
const ctx = document.getElementById('trendGraph').getContext('2d');
|
const ctx = document.getElementById('trendGraph').getContext('2d');
|
||||||
@ -780,10 +789,12 @@ function initializeChart() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the current theme colors
|
||||||
|
const theme = getCurrentTheme();
|
||||||
|
|
||||||
// Check if Chart.js plugin is available
|
// Check if Chart.js plugin is available
|
||||||
const hasAnnotationPlugin = window['chartjs-plugin-annotation'] !== undefined;
|
const hasAnnotationPlugin = window['chartjs-plugin-annotation'] !== undefined;
|
||||||
|
|
||||||
// Inside the initializeChart function, modify the dataset configuration:
|
|
||||||
return new Chart(ctx, {
|
return new Chart(ctx, {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
@ -796,29 +807,29 @@ function initializeChart() {
|
|||||||
const chart = context.chart;
|
const chart = context.chart;
|
||||||
const { ctx, chartArea } = chart;
|
const { ctx, chartArea } = chart;
|
||||||
if (!chartArea) {
|
if (!chartArea) {
|
||||||
return '#f7931a';
|
return theme.PRIMARY;
|
||||||
}
|
}
|
||||||
// Create gradient for line
|
// Create gradient for line
|
||||||
const gradient = ctx.createLinearGradient(0, 0, 0, chartArea.bottom);
|
const gradient = ctx.createLinearGradient(0, 0, 0, chartArea.bottom);
|
||||||
gradient.addColorStop(0, '#ffa64d'); // Lighter orange
|
gradient.addColorStop(0, theme.CHART.GRADIENT_START);
|
||||||
gradient.addColorStop(1, '#f7931a'); // Bitcoin orange
|
gradient.addColorStop(1, theme.CHART.GRADIENT_END);
|
||||||
return gradient;
|
return gradient;
|
||||||
},
|
},
|
||||||
backgroundColor: function (context) {
|
backgroundColor: function (context) {
|
||||||
const chart = context.chart;
|
const chart = context.chart;
|
||||||
const { ctx, chartArea } = chart;
|
const { ctx, chartArea } = chart;
|
||||||
if (!chartArea) {
|
if (!chartArea) {
|
||||||
return 'rgba(247,147,26,0.1)';
|
return `rgba(${theme.PRIMARY_RGB}, 0.1)`;
|
||||||
}
|
}
|
||||||
// Create gradient for fill
|
// Create gradient for fill
|
||||||
const gradient = ctx.createLinearGradient(0, 0, 0, chartArea.bottom);
|
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, `rgba(${theme.PRIMARY_RGB}, 0.3)`);
|
||||||
gradient.addColorStop(0.5, 'rgba(247, 147, 26, 0.2)'); // Bitcoin orange with medium transparency
|
gradient.addColorStop(0.5, `rgba(${theme.PRIMARY_RGB}, 0.2)`);
|
||||||
gradient.addColorStop(1, 'rgba(247, 147, 26, 0.05)'); // Bitcoin orange with high transparency
|
gradient.addColorStop(1, `rgba(${theme.PRIMARY_RGB}, 0.05)`);
|
||||||
return gradient;
|
return gradient;
|
||||||
},
|
},
|
||||||
fill: true,
|
fill: true,
|
||||||
tension: 0.3, // Slightly increase tension for smoother curves
|
tension: 0.3,
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
@ -848,10 +859,10 @@ function initializeChart() {
|
|||||||
y: {
|
y: {
|
||||||
title: {
|
title: {
|
||||||
display: true,
|
display: true,
|
||||||
text: 'HASHRATE (TH/S)', // Already uppercase
|
text: 'HASHRATE (TH/S)',
|
||||||
color: '#f7931a', // Bitcoin orange
|
color: theme.PRIMARY,
|
||||||
font: {
|
font: {
|
||||||
family: "'VT323', monospace", // Terminal font
|
family: "'VT323', monospace",
|
||||||
size: 16,
|
size: 16,
|
||||||
weight: 'bold'
|
weight: 'bold'
|
||||||
}
|
}
|
||||||
@ -905,7 +916,7 @@ function initializeChart() {
|
|||||||
plugins: {
|
plugins: {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
titleColor: '#f7931a',
|
titleColor: theme.PRIMARY,
|
||||||
bodyColor: '#FFFFFF',
|
bodyColor: '#FFFFFF',
|
||||||
titleFont: {
|
titleFont: {
|
||||||
family: "'VT323', monospace",
|
family: "'VT323', monospace",
|
||||||
@ -937,10 +948,10 @@ function initializeChart() {
|
|||||||
type: 'line',
|
type: 'line',
|
||||||
yMin: 0,
|
yMin: 0,
|
||||||
yMax: 0,
|
yMax: 0,
|
||||||
borderColor: '#ffd700', // Gold color
|
borderColor: theme.CHART.ANNOTATION,
|
||||||
borderWidth: 3,
|
borderWidth: 3,
|
||||||
borderDash: [8, 4],
|
borderDash: [8, 4],
|
||||||
shadowColor: 'rgba(255, 215, 0, 0.5)',
|
shadowColor: `rgba(${theme.PRIMARY_RGB}, 0.5)`,
|
||||||
shadowBlur: 8,
|
shadowBlur: 8,
|
||||||
shadowOffsetX: 0,
|
shadowOffsetX: 0,
|
||||||
shadowOffsetY: 0,
|
shadowOffsetY: 0,
|
||||||
@ -948,7 +959,7 @@ function initializeChart() {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
content: '24HR AVG: 0 TH/S',
|
content: '24HR AVG: 0 TH/S',
|
||||||
backgroundColor: 'rgba(0,0,0,0.8)',
|
backgroundColor: 'rgba(0,0,0,0.8)',
|
||||||
color: '#ffd700',
|
color: theme.CHART.ANNOTATION,
|
||||||
font: {
|
font: {
|
||||||
family: "'VT323', monospace",
|
family: "'VT323', monospace",
|
||||||
size: 16,
|
size: 16,
|
||||||
@ -1237,20 +1248,21 @@ function updateChartWithNormalizedData(chart, data) {
|
|||||||
chart.data.datasets[0].data = [normalizedValue];
|
chart.data.datasets[0].data = [normalizedValue];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If using 3hr average due to low hashrate device detection, add visual indicator
|
// In updateChartWithNormalizedData function
|
||||||
if (useHashrate3hr) {
|
if (useHashrate3hr) {
|
||||||
// Add indicator text to the chart
|
// Add indicator text to the chart
|
||||||
if (!chart.lowHashrateIndicator) {
|
if (!chart.lowHashrateIndicator) {
|
||||||
// Create the indicator element if it doesn't exist
|
// Create the indicator element if it doesn't exist
|
||||||
const graphContainer = document.getElementById('graphContainer');
|
const graphContainer = document.getElementById('graphContainer');
|
||||||
if (graphContainer) {
|
if (graphContainer) {
|
||||||
|
const theme = getCurrentTheme();
|
||||||
const indicator = document.createElement('div');
|
const indicator = document.createElement('div');
|
||||||
indicator.id = 'lowHashrateIndicator';
|
indicator.id = 'lowHashrateIndicator';
|
||||||
indicator.style.position = 'absolute';
|
indicator.style.position = 'absolute';
|
||||||
indicator.style.bottom = '10px';
|
indicator.style.bottom = '10px';
|
||||||
indicator.style.right = '10px';
|
indicator.style.right = '10px';
|
||||||
indicator.style.background = 'rgba(0,0,0,0.7)';
|
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.padding = '5px 10px';
|
||||||
indicator.style.borderRadius = '3px';
|
indicator.style.borderRadius = '3px';
|
||||||
indicator.style.fontSize = '12px';
|
indicator.style.fontSize = '12px';
|
||||||
@ -1261,6 +1273,8 @@ function updateChartWithNormalizedData(chart, data) {
|
|||||||
chart.lowHashrateIndicator = indicator;
|
chart.lowHashrateIndicator = indicator;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Update color based on current theme
|
||||||
|
chart.lowHashrateIndicator.style.color = getCurrentTheme().PRIMARY;
|
||||||
// Show the indicator if it already exists
|
// Show the indicator if it already exists
|
||||||
chart.lowHashrateIndicator.style.display = 'block';
|
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 () {
|
$(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
|
// Remove the existing refreshUptime container to avoid duplicates
|
||||||
$('#refreshUptime').hide();
|
$('#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
|
// Set up event source for SSE
|
||||||
setupEventSource();
|
setupEventSource();
|
||||||
|
|
||||||
@ -2053,8 +2579,8 @@ $(document).ready(function () {
|
|||||||
updateServerTime();
|
updateServerTime();
|
||||||
setInterval(updateServerTime, 30000);
|
setInterval(updateServerTime, 30000);
|
||||||
|
|
||||||
// Add a manual refresh button for fallback
|
// Update the manual refresh button color
|
||||||
$("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>');
|
$("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 () {
|
$("#refreshButton").on("click", function () {
|
||||||
$(this).text("Refreshing...");
|
$(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 -->
|
<!-- Common CSS -->
|
||||||
<link rel="stylesheet" href="/static/css/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 -->
|
<!-- Page-specific CSS -->
|
||||||
{% block css %}{% endblock %}
|
{% 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>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
@ -34,6 +51,11 @@
|
|||||||
<!-- Top right link -->
|
<!-- Top right link -->
|
||||||
<a href="https://x.com/DJObleezy" id="topRightLink" target="_blank" rel="noopener noreferrer">MADE BY @DJO₿LEEZY</a>
|
<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 %}
|
{% 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>
|
<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 %}
|
{% endblock %}
|
||||||
@ -57,6 +79,11 @@
|
|||||||
{% block congrats_message %}
|
{% 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>
|
<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 %}
|
{% endblock %}
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="footer text-center">
|
||||||
|
<p>Not affiliated with Ocean.xyz</p>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- External JavaScript libraries -->
|
<!-- External JavaScript libraries -->
|
||||||
@ -64,6 +91,32 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-annotation@1.1.0"></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 -->
|
<!-- Page-specific JavaScript -->
|
||||||
{% block javascript %}{% endblock %}
|
{% block javascript %}{% endblock %}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<link rel="stylesheet" href="/static/css/blocks.css">
|
<link rel="stylesheet" href="/static/css/blocks.css">
|
||||||
|
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block header %}BLOCKCHAIN MONITOR v 0.1{% endblock %}
|
{% block header %}BLOCKCHAIN MONITOR v 0.1{% endblock %}
|
||||||
|
@ -6,25 +6,122 @@
|
|||||||
<title>Ocean.xyz Pool Miner - Initializing...</title>
|
<title>Ocean.xyz Pool Miner - Initializing...</title>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
|
<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/boot.css">
|
||||||
|
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||||
|
<!-- Add Theme JS -->
|
||||||
|
<script src="/static/js/theme.js"></script>
|
||||||
<style>
|
<style>
|
||||||
/* Added styles for configuration form */
|
/* Config form styling - fixed width and hidden by default */
|
||||||
#config-form {
|
#config-form {
|
||||||
display: none;
|
display: none;
|
||||||
margin-top: 20px;
|
width: 500px;
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
max-width: 90%;
|
||||||
|
margin: 30px auto;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #0d0d0d;
|
||||||
border: 1px solid #f7931a;
|
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);
|
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;
|
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;
|
text-align: center;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 20px;
|
||||||
|
color: #f7931a;
|
||||||
text-shadow: 0 0 8px rgba(247, 147, 26, 0.8);
|
text-shadow: 0 0 8px rgba(247, 147, 26, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,17 +135,19 @@
|
|||||||
color: #f7931a;
|
color: #f7931a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group input {
|
.form-group input,
|
||||||
|
.form-group select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #111;
|
|
||||||
border: 1px solid #f7931a;
|
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
color: white;
|
background-color: #0d0d0d;
|
||||||
|
border: 1px solid #f7931a;
|
||||||
|
color: #fff;
|
||||||
font-family: 'VT323', monospace;
|
font-family: 'VT323', monospace;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group input:focus {
|
.form-group input:focus,
|
||||||
|
.form-group select:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: 0 0 5px #f7931a;
|
box-shadow: 0 0 5px #f7931a;
|
||||||
}
|
}
|
||||||
@ -60,19 +159,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
|
padding: 8px 16px;
|
||||||
background-color: #f7931a;
|
background-color: #f7931a;
|
||||||
|
color: #000;
|
||||||
border: none;
|
border: none;
|
||||||
color: black;
|
cursor: pointer;
|
||||||
padding: 8px 15px;
|
|
||||||
font-family: 'VT323', monospace;
|
font-family: 'VT323', monospace;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
cursor: pointer;
|
|
||||||
min-width: 120px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn:hover {
|
.btn:hover {
|
||||||
background-color: #ffa642;
|
background-color: #ffa32e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-secondary {
|
.btn-secondary {
|
||||||
@ -80,79 +177,10 @@
|
|||||||
color: #f7931a;
|
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 {
|
#form-message {
|
||||||
margin-top: 10px;
|
margin-top: 15px;
|
||||||
padding: 8px;
|
padding: 10px;
|
||||||
text-align: center;
|
border-radius: 3px;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,60 +196,63 @@
|
|||||||
color: #ff0000;
|
color: #ff0000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add these styles to match the timezone dropdown with your other inputs */
|
.tooltip {
|
||||||
.form-group select {
|
position: relative;
|
||||||
width: 100%;
|
display: inline-block;
|
||||||
background-color: #111;
|
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;
|
border: 1px solid #f7931a;
|
||||||
padding: 8px;
|
}
|
||||||
color: white;
|
|
||||||
font-family: 'VT323', monospace;
|
.tooltip:hover .tooltip-text {
|
||||||
font-size: 18px;
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style the select dropdown with custom arrow */
|
||||||
|
.form-group select {
|
||||||
|
appearance: none;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-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-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-size: 5px 5px, 5px 5px;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
padding-right: 25px; /* Space for the arrow */
|
padding-right: 30px;
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!-- Theme toggle button (new) -->
|
||||||
|
<button id="themeToggle" class="theme-toggle-btn">
|
||||||
|
<span>Toggle Theme</span>
|
||||||
|
</button>
|
||||||
<button id="skip-button">SKIP</button>
|
<button id="skip-button">SKIP</button>
|
||||||
<div id="debug-info"></div>
|
<div id="debug-info"></div>
|
||||||
<div id="loading-message">Loading mining data...</div>
|
<div id="loading-message">Loading mining data...</div>
|
||||||
@ -322,6 +353,45 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<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
|
// Add a function to populate all available timezones
|
||||||
function populateTimezones() {
|
function populateTimezones() {
|
||||||
const otherTimezones = document.getElementById('other-timezones');
|
const otherTimezones = document.getElementById('other-timezones');
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<link rel="stylesheet" href="/static/css/dashboard.css">
|
<link rel="stylesheet" href="/static/css/dashboard.css">
|
||||||
|
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block dashboard_active %}active{% endblock %}
|
{% block dashboard_active %}active{% endblock %}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<link rel="stylesheet" href="/static/css/notifications.css">
|
<link rel="stylesheet" href="/static/css/notifications.css">
|
||||||
|
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block header %}NOTIFICATION CENTER v 0.1{% endblock %}
|
{% block header %}NOTIFICATION CENTER v 0.1{% endblock %}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<link rel="stylesheet" href="/static/css/workers.css">
|
<link rel="stylesheet" href="/static/css/workers.css">
|
||||||
|
<link rel="stylesheet" href="/static/css/theme-toggle.css">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block header %}WORKERS OVERVIEW{% endblock %}
|
{% block header %}WORKERS OVERVIEW{% endblock %}
|
||||||
|
Loading…
Reference in New Issue
Block a user