Skip to content

Settings System

Centralized settings managed by TabletContext and persisted to MySQL.

Settings Architecture

lib/settings.js          — Defaults, load/save, apply to DOM, theme definitions
├── lib/dbStorage.js     — NUI → Server → MySQL bridge
├── TabletContext.jsx    — React state, reducer, derived themeColors
├── TabletShell.jsx      — Inline settings panel (7 sections)
└── All apps via useTablet() — Read settings

Settings Panel

Accessed via the gear icon in the taskbar. Opens inline in the tablet shell (not a separate window).

7 Accordion Sections

  1. Appearance — Theme selector (Dark, Light, Cyberpunk), wallpaper presets
  2. Colors — Accent, secondary, text, background color pickers + preset swatches
  3. Typography — Font family dropdown, font size slider
  4. Layout — UI scale slider, border radius slider, UI style (default/compact/spacious)
  5. Progress Bars — Linear style (9 options), circular style (3 options)
  6. Notifications — Toast style (default/minimal/bold/bordered), sound toggle, notification mute
  7. Effects — Glow effects toggle, animations toggle

Color Picker

Custom lightweight color picker (no native <input type="color">):

  • Saturation/Brightness area — 200x150px, click/drag to select
  • Hue slider — Horizontal rainbow bar
  • Hex input — Direct hex code entry
  • Preset swatches — 8 preset colors (Aifazi Green, Cyber Red, Neon Blue, etc.)

Theme System

Built-in Themes

ThemeAccentBackground
Dark#00ff88#060a0f
Light#00aa55#f0f0f0
Cyberpunk#ff00ff#0a0014

themeColors Derivation

themeColors is derived from the base theme + user custom colors:

js
function buildThemeColors(base, settings) {
    return {
        ...base,
        accent: settings.accentColor || base.accent,
        secondary: settings.secondaryColor || base.accentHover,
        text: settings.textColor || base.text,
        desktopBg: settings.backgroundColor || base.desktopBg,
        // ... other derived colors
    };
}

CSS Custom Properties

applySettings() sets these on document.documentElement:

css
--wtf-primary: #00ff88;
--wtf-primary-hover: #00ff88dd;
--wtf-primary-text: #ffffff;  /* auto-contrast */
--wtf-success: #00ff88;
--wtf-info: #00d4ff;
--wtf-text: #c8d8e8;
--wtf-bg: #060a0f;
--wtf-border: rgba(0,255,136,0.08);
--wtf-font: 'Inter', sans-serif;
--wtf-radius-panel: 12px;
--tablet-accent: #00ff88;
--tablet-bg: #060a0f;

Data Attributes

html
<html data-progress-style="plain"
      data-notification-style="default"
      data-ui-style="default"
      data-glow="on"
      data-animations="on">

Auto-Contrast

Button text color is automatically calculated based on accent vs background luminance:

js
function getContrastColor(accentHex, bgHex) {
    const diff = Math.abs(accentLum - bgLum);
    if (diff < 0.15) {
        return accentLum > 0.5 ? '#000000' : '#ffffff';
    }
    return null; // Use default
}

Injected as a dynamic <style> element targeting .wtf-btn-primary etc.

Default Settings

js
const DEFAULT_SETTINGS = {
    theme: 'dark',
    wallpaper: null,
    clockFormat: '24h',
    iconSize: 'medium',
    taskbarPosition: 'bottom',
    accentColor: '#00ff88',
    secondaryColor: '#00d4ff',
    textColor: '#c8d8e8',
    backgroundColor: '#060a0f',
    fontFamily: "'Inter','SF Pro Display','Segoe UI',system-ui,sans-serif",
    fontSize: 13,
    uiScale: 100,
    borderRadius: 12,
    uiStyle: 'default',
    progressStyle: 'plain',
    circularStyle: 'ring',
    notificationStyle: 'default',
    showGlowEffects: true,
    showAnimations: true,
    notificationMuted: false,
    soundEnabled: true,
};

Persistence

  • localStorage (wtf_tablet_settings): Instant load, acts as cache
  • MySQL (wtf_tablet_settings table): Durable storage, loaded async on mount
  • Dual write: Every saveSettings() writes to both
  • DB override: On mount, if DB has data, it replaces localStorage values

AIFAZI — FiveM Resources