Files
Client/lib/utils/haptics.dart
T

73 lines
2.1 KiB
Dart

import 'dart:async';
import 'package:flutter/services.dart';
import '../state/app/modules/settings/bloc/settings_cubit.dart';
import '../storage/haptic_settings.dart';
import '../storage/settings.dart';
/// App-weite Haptik-Fassade. Liest die aktive Stufe aus einem in-memory Cache,
/// der einmal an den SettingsCubit gebunden wird — damit sind die Aufrufe
/// kontextfrei (egal ob aus Widget oder Util).
///
/// Semantische Methoden statt roher Impacts, damit Call-Sites die Intention
/// transportieren, nicht die Stärke.
class Haptics {
static HapticLevel _level = HapticLevel.full;
static StreamSubscription<Settings>? _sub;
/// Einmal aus App-Root aufrufen, sobald der [SettingsCubit] verfügbar ist.
static void bind(SettingsCubit cubit) {
_level = cubit.state.hapticSettings.level;
_sub?.cancel();
_sub = cubit.stream.listen((s) => _level = s.hapticSettings.level);
}
// --- reduced + full ---
/// Long-Press, der ein Bottom-Sheet / Action-Menü öffnet.
static void longPress() {
if (_level == HapticLevel.off) return;
HapticFeedback.mediumImpact();
}
/// Bestätigen eines ConfirmDialogs (nicht das Abbrechen).
static void confirm() {
if (_level == HapticLevel.off) return;
HapticFeedback.mediumImpact();
}
/// Fehler einer Async-Aktion / Dialog-Fehler.
static void error() {
if (_level == HapticLevel.off) return;
HapticFeedback.mediumImpact();
}
/// Seltener Dopamin-Moment — z.B. erfolgreicher Login.
static void heavyAccent() {
if (_level == HapticLevel.off) return;
HapticFeedback.heavyImpact();
}
// --- nur full ---
/// Erfolg einer Async-Aktion (Senden, Reagieren, Speichern, …).
static void success() {
if (_level != HapticLevel.full) return;
HapticFeedback.lightImpact();
}
/// Pull-to-Refresh ausgelöst.
static void refresh() {
if (_level != HapticLevel.full) return;
HapticFeedback.selectionClick();
}
/// Tab-Wechsel, Toggle-Switch, Clipboard-Copy — alles, was eine
/// subtile Quittung verdient.
static void selection() {
if (_level != HapticLevel.full) return;
HapticFeedback.selectionClick();
}
}