Commit 00e13552 authored by Mahmoud Aglan's avatar Mahmoud Aglan

feat(game): vibration switch in settings

Haptics (feel.haptic) are off when the player turns vibration off; the
setting persists with the rest of the player's preferences.
Co-Authored-By: 's avatarClaude Opus 5.5 <noreply@anthropic.com>
parent 8822f88d
......@@ -8,6 +8,7 @@
//
// One global layer, so every screen gets the same feel without wiring it.
import * as audio from './audio.js';
import * as store from './store.js';
const PRESSABLE = 'button, .deck-card, .chip, [role="button"], [role="radio"], [role="switch"], [role="tab"], .tab-item, a.btn';
const MOVE_CANCEL = 10; // px of travel that turns a press into a scroll
......@@ -21,6 +22,7 @@ let sceneMountedAt = 0;
/** Haptics: native shell when present, the Vibration API otherwise. */
export function haptic(kind = 'light') {
if (store.get('hapticsEnabled') === false) return;
const bridge = window.flutter_bridge;
if (bridge?.postMessage) {
try { bridge.postMessage(JSON.stringify({ cmd: 'haptic', type: kind })); } catch (e) {}
......
This diff is collapsed.
......@@ -11,6 +11,7 @@ const defaultState = {
features: {},
activeWorld: 'play',
audioEnabled: true,
hapticsEnabled: true,
language: 'ar'
};
......@@ -33,6 +34,7 @@ function persist() {
player: state.player,
activeWorld: state.activeWorld,
audioEnabled: state.audioEnabled,
hapticsEnabled: state.hapticsEnabled,
language: state.language,
home: state.home
};
......
......@@ -14,6 +14,7 @@ import { screenHead, wireBack } from '../../../core/ui.js';
export function mountSettings(el) {
const lang = store.get('language') || 'ar';
const audioOn = !!store.get('audioEnabled');
const hapticsOn = store.get('hapticsEnabled') !== false;
el.innerHTML = `
<div class="screen st">
......@@ -28,6 +29,13 @@ export function mountSettings(el) {
<span class="st-knob"></span>
</button>
</div>
<div class="row st-row">
<span class="st-tile">${gicon('hand', 34)}</span>
<span class="row-main"><span class="row-title" id="st-haptic-label">${t('settings.vibration')}</span></span>
<button class="st-switch" id="toggle-haptics" role="switch" aria-checked="${hapticsOn}" aria-labelledby="st-haptic-label">
<span class="st-knob"></span>
</button>
</div>
<button class="row st-row st-btn" id="toggle-lang">
<span class="st-tile">${gicon('chat', 34)}</span>
<span class="row-main"><span class="row-title">${t('settings.language')}</span></span>
......@@ -121,6 +129,13 @@ export function mountSettings(el) {
el.querySelector('#toggle-audio')?.focus();
});
el.querySelector('#toggle-haptics').addEventListener('click', () => {
store.set('hapticsEnabled', store.get('hapticsEnabled') === false);
if (navigator.vibrate && store.get('hapticsEnabled')) navigator.vibrate(20);
mountSettings(el);
el.querySelector('#toggle-haptics')?.focus();
});
el.querySelector('#toggle-lang').addEventListener('click', () => {
const current = store.get('language') || 'ar';
const next = current === 'ar' ? 'en' : 'ar';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment