implemented a central haptic feedback system with configurable levels (off, reduced, full), added a Haptics facade providing semantic feedback methods, integrated haptic cues across navigation, settings toggles, and async action results, and updated version to 1.1.0+54
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user