Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions [esx_addons]/esx_weather/fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ fx_version "cerulean"
game "gta5"
author "Kenshin13"
description "Weather sync for your ESX server"
version "1.0.0"
version "1.1.0"
legacyversion "1.13.4"
lua54 "yes"
use_fxv2_oal "yes"
Expand All @@ -27,7 +27,6 @@ files {
"ui/css/*.css",
"ui/js/core/state.js",
"ui/js/core/constants.js",
"ui/js/utils/sanitizer.js",
"ui/js/utils/helpers.js",
"ui/js/services/nui-bridge.js",
"ui/js/controllers/ui-controller.js",
Expand Down
47 changes: 47 additions & 0 deletions [esx_addons]/esx_weather/ui/css/layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,53 @@
margin: 0;
}

.header-controls {
display: flex;
align-items: center;
gap: var(--spacing-sm);
}

.perf-toggle-btn {
background: transparent;
border: 0.125rem solid var(--mid-color);
color: var(--light-color);
height: 2.5rem;
padding: 0 var(--spacing-sm);
border-radius: var(--radius-md);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
transition: all var(--transition-fast);
font-size: 0.875rem;
font-weight: 500;
white-space: nowrap;
}

.perf-toggle-btn svg {
flex-shrink: 0;
}

.perf-toggle-btn:hover {
border-color: var(--brand-color);
color: var(--brand-color);
background: rgba(var(--brand-color-rgb), 0.1);
transform: scale(1.05);
}

.perf-toggle-btn:active {
transform: scale(0.95);
}

/* Performance mode active state */
.perf-toggle-btn.active {
border-color: var(--brand-color);
color: var(--brand-color);
background: rgba(var(--brand-color-rgb), 0.2);
box-shadow: 0 0 0.5rem rgba(var(--brand-color-rgb), 0.3);
}

.close-btn {
background: transparent;
border: 0.125rem solid var(--mid-color);
Expand Down
68 changes: 68 additions & 0 deletions [esx_addons]/esx_weather/ui/css/performance.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* Performance Mode Styles
* Disables heavy animations and effects for improved FPS on weak hardware
*/

/* Disable all weather icon animations */
.performance-mode .weather-icon.animate-sun,
.performance-mode .weather-icon.animate-rain,
.performance-mode .weather-icon.animate-cloud,
.performance-mode .weather-icon.animate-lightning,
.performance-mode .current-zone-icon.animate-sun,
.performance-mode .current-zone-icon.animate-rain,
.performance-mode .current-zone-icon.animate-cloud,
.performance-mode .current-zone-icon.animate-lightning {
animation: none !important;
}

/* Remove backdrop filter blur (known CEF issue, replace with solid color) */
.performance-mode .backdrop {
backdrop-filter: none !important;
}

/* Remove drop-shadow filters from icons */
.performance-mode .current-zone-icon,
.performance-mode .weather-icon {
filter: none !important;
}

/* Remove text shadows for reduced GPU load */
.performance-mode .current-zone-name {
text-shadow: none !important;
}

.performance-mode .zone-card-title {
text-shadow: none !important;
}

/* Simplify modal entrance animation (fade only, no scale/translate) */
.performance-mode .modal {
animation: fadeIn var(--transition-normal) ease-out !important;
}

/* Remove hover transform effects (keep color changes) */
.performance-mode .zone-card:hover {
transform: none !important;
}

.performance-mode .perf-toggle-btn:hover,
.performance-mode .close-btn:hover {
transform: none !important;
}

.performance-mode .perf-toggle-btn:active,
.performance-mode .close-btn:active {
transform: none !important;
}

/* Simplify zone card hover background gradient */
.performance-mode .zone-card::before {
display: none !important;
}

/* Reduce transition duration in performance mode */
.performance-mode .zone-card,
.performance-mode .perf-toggle-btn,
.performance-mode .close-btn {
transition-duration: var(--transition-fast) !important;
}
22 changes: 15 additions & 7 deletions [esx_addons]/esx_weather/ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="css/performance.css">
<script src="https://unpkg.com/lucide@latest"></script>
</head>
<body>
Expand All @@ -20,12 +21,20 @@
<h1>Weather Control Panel</h1>
<p class="modal-subtitle">Control the forecast. Shape the atmosphere. Rule the skies.</p>
</div>
<button class="close-btn" id="closeBtn" aria-label="Close panel">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
<div class="header-controls">
<button class="perf-toggle-btn" id="perfToggleBtn" aria-label="Toggle performance mode">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path>
</svg>
<span>Performance</span>
</button>
<button class="close-btn" id="closeBtn" aria-label="Close panel">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
</div>
</div>

<div class="modal-body">
Expand All @@ -45,7 +54,6 @@ <h1>Weather Control Panel</h1>
<script src="js/core/constants.js"></script>

<!-- Utilities -->
<script src="js/utils/sanitizer.js"></script>
<script src="js/utils/helpers.js"></script>

<!-- Services -->
Expand Down
86 changes: 60 additions & 26 deletions [esx_addons]/esx_weather/ui/js/controllers/ui-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ const UIController = (() => {
app: document.getElementById('app'),
closeBtn: document.getElementById('closeBtn'),
currentZoneName: document.getElementById('currentZoneName'),
zonesGrid: document.getElementById('zonesGrid')
zonesGrid: document.getElementById('zonesGrid'),
perfToggleBtn: document.getElementById('perfToggleBtn')
};
};

Expand Down Expand Up @@ -63,20 +64,7 @@ const UIController = (() => {
const container = document.querySelector('.current-zone-info');
if (!container) return;

// Validate inputs
if (!Sanitizer.isValidZoneName(zoneName)) {
console.warn('[UIController] Invalid zone name:', zoneName);
return;
}

if (!Sanitizer.isValidWeatherType(weatherType, State.weatherTypes)) {
console.warn('[UIController] Invalid weather type:', weatherType);
return;
}

const iconConfig = getWeatherIcon(weatherType);
const safeZoneName = Sanitizer.sanitizeHTML(zoneName);
const safeWeatherType = Sanitizer.sanitizeHTML(weatherType);

container.className = `current-zone-info ${iconConfig.gradientClass}`;

Expand Down Expand Up @@ -119,12 +107,6 @@ const UIController = (() => {
* @returns {HTMLElement}
*/
const createZoneCard = (zoneName, weatherType, isCurrent) => {
// Validate inputs
if (!Sanitizer.isValidZoneName(zoneName) || !Sanitizer.isValidWeatherType(weatherType, State.weatherTypes)) {
console.warn('[UIController] Invalid zone card data:', { zoneName, weatherType });
return document.createElement('div');
}

const card = document.createElement('div');
const iconConfig = getWeatherIcon(weatherType);

Expand Down Expand Up @@ -264,12 +246,6 @@ const UIController = (() => {
const card = elements.zonesGrid?.querySelector(`[data-zone="${zoneName}"]`);
if (!card) return;

// Validate inputs
if (!Sanitizer.isValidWeatherType(weatherType, State.weatherTypes)) {
console.warn('[UIController] Invalid weather type for update:', weatherType);
return;
}

const iconConfig = getWeatherIcon(weatherType);
const isCurrent = card.classList.contains('current');

Expand Down Expand Up @@ -317,6 +293,61 @@ const UIController = (() => {
}
};

/**
* Toggle performance mode on/off
* Applies CSS class to root element and updates button state
* @returns {void}
*/
const togglePerformanceMode = () => {
setPerformanceMode(!State.performanceMode);
applyPerformanceMode();
};

/**
* Apply performance mode settings to UI
* Adds/removes performance-mode class based on state
* @returns {void}
*/
const applyPerformanceMode = () => {
const app = elements.app || document.getElementById('app');
if (!app) return;

if (State.performanceMode) {
app.classList.add('performance-mode');
updatePerformanceModeButtonState();
} else {
app.classList.remove('performance-mode');
updatePerformanceModeButtonState();
}
};

/**
* Update performance mode button visual state
* Shows active state when performance mode is enabled
* @returns {void}
*/
const updatePerformanceModeButtonState = () => {
const btn = elements.perfToggleBtn || document.getElementById('perfToggleBtn');
if (!btn) return;

if (State.performanceMode) {
btn.classList.add('active');
btn.setAttribute('title', 'Performance Mode: ON (Click to disable)');
} else {
btn.classList.remove('active');
btn.setAttribute('title', 'Performance Mode: OFF (Click to enable)');
}
};

/**
* Initialize performance mode based on saved setting
* Called during app initialization
* @returns {void}
*/
const initPerformanceMode = () => {
applyPerformanceMode();
};

return {
initElements,
show,
Expand All @@ -325,6 +356,9 @@ const UIController = (() => {
renderZones,
updateZoneWeather,
getWeatherIcon,
togglePerformanceMode,
applyPerformanceMode,
initPerformanceMode,
elements
};
})();
Expand Down
21 changes: 20 additions & 1 deletion [esx_addons]/esx_weather/ui/js/core/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,28 @@
const State = {
isVisible: false,
data: null,
weatherTypes: {}
weatherTypes: {},
performanceMode: getPerformanceModeSetting()
};

/**
* Get performance mode setting from localStorage
* @returns {boolean} Performance mode enabled status
*/
function getPerformanceModeSetting() {
const stored = localStorage.getItem('weather_performanceMode');
return stored !== null ? JSON.parse(stored) : false;
}

/**
* Set performance mode and persist to localStorage
* @param {boolean} enabled - Whether performance mode is enabled
*/
function setPerformanceMode(enabled) {
State.performanceMode = enabled;
localStorage.setItem('weather_performanceMode', JSON.stringify(enabled));
}

// Export for module usage
if (typeof module !== 'undefined' && module.exports) {
module.exports = State;
Expand Down
Loading