ADD ALOT OF POLISHING AND UPDATES...

This commit is contained in:
Wowieee4
2026-05-26 05:52:12 +07:00
parent 2e3ecdf1d1
commit b8ad8df993
53 changed files with 3194 additions and 3860 deletions
@@ -12,6 +12,7 @@ import 'package:go_router/go_router.dart';
import '../../app/app_cubit.dart';
import '../../app/injection_container.dart';
import '../../core/constants/app_constants.dart';
import '../../core/errors/friendly_error.dart';
import '../../core/network/api_client.dart';
import '../../core/services/haptic_service.dart';
import '../../core/services/tts_service.dart';
@@ -78,40 +79,46 @@ class _UserSettingsScreenState extends State<UserSettingsScreen> {
}
Future<void> _loadSettings() async {
try {
final res =
await _api.get('/user/settings').timeout(const Duration(seconds: 6));
final data = res.data['data'];
if (data is Map) {
_ttsLanguage = data['ttsLanguage']?.toString() ?? 'id-ID';
_ttsPitch = (data['ttsPitch'] as num?)?.toDouble() ?? 1.0;
_ttsSpeed = (data['ttsSpeed'] as num?)?.toDouble() ?? 0.9;
_warnNoGuardian = data['warnNoGuardian'] as bool? ?? true;
_hapticEnabled = data['hapticEnabled'] as bool? ?? true;
}
} catch (_) {
// offline: tetap pakai default / nilai lokal
}
await runFriendlyAction(
() async {
final res = await _api
.get('/user/settings')
.timeout(const Duration(seconds: 6));
final data = res.data['data'];
if (data is Map) {
_ttsLanguage = data['ttsLanguage']?.toString() ?? 'id-ID';
_ttsPitch = (data['ttsPitch'] as num?)?.toDouble() ?? 1.0;
_ttsSpeed = (data['ttsSpeed'] as num?)?.toDouble() ?? 0.9;
_warnNoGuardian = data['warnNoGuardian'] as bool? ?? true;
_hapticEnabled = data['hapticEnabled'] as bool? ?? true;
}
},
onError: (_) {},
fallback: 'Settings belum bisa dimuat.',
);
}
Future<void> _loadPairing() async {
try {
final res = await _api
.get('/shared/pairing/status')
.timeout(const Duration(seconds: 5));
final data = res.data['data'];
if (data is Map) {
_paired = data['status'] == 'ACTIVE';
final partner = data['pairedWithName'] ?? data['pairedWithEmail'] ?? '';
_pairingStatus = _paired
? 'Terhubung dengan $partner'
: data['status'] == 'PENDING'
? 'Menunggu konfirmasi Guardian'
: 'Belum paired';
}
} catch (_) {
_pairingStatus = 'Tidak bisa cek status';
}
await runFriendlyAction(
() async {
final res = await _api
.get('/shared/pairing/status')
.timeout(const Duration(seconds: 5));
final data = res.data['data'];
if (data is Map) {
_paired = data['status'] == 'ACTIVE';
final partner =
data['pairedWithName'] ?? data['pairedWithEmail'] ?? '';
_pairingStatus = _paired
? 'Terhubung dengan $partner'
: data['status'] == 'PENDING'
? 'Menunggu konfirmasi Guardian'
: 'Belum paired';
}
},
onError: (_) => _pairingStatus = 'Tidak bisa cek status',
fallback: 'Tidak bisa cek status',
);
}
Future<void> _save() async {
@@ -122,34 +129,28 @@ class _UserSettingsScreenState extends State<UserSettingsScreen> {
await sl<HapticService>().success();
}
try {
await _api.put('/user/settings', data: {
'ttsLanguage': _ttsLanguage,
'ttsPitch': _ttsPitch,
'ttsSpeed': _ttsSpeed,
'warnNoGuardian': _warnNoGuardian,
'hapticEnabled': _hapticEnabled,
}).timeout(const Duration(seconds: 8));
_snack('Settings tersimpan.');
sl<TtsService>().speak('Settings disimpan.');
} on DioException catch (e) {
final msg = e.response?.data['message']?.toString() ??
'Server tidak merespons, settings lokal sudah diterapkan.';
_snack(msg);
} catch (_) {
_snack('Settings lokal sudah diterapkan, gagal sync ke server.');
} finally {
if (mounted) setState(() => _saving = false);
}
await runFriendlyAction(
() async {
await _api.put('/user/settings', data: {
'ttsLanguage': _ttsLanguage,
'ttsPitch': _ttsPitch,
'ttsSpeed': _ttsSpeed,
'warnNoGuardian': _warnNoGuardian,
'hapticEnabled': _hapticEnabled,
}).timeout(const Duration(seconds: 8));
_snack('Settings tersimpan.');
sl<TtsService>().speak('Settings disimpan.');
},
onError: _snack,
fallback: 'Settings lokal sudah diterapkan, gagal sync ke server.',
);
if (mounted) setState(() => _saving = false);
}
Future<void> _logout() async {
await sl<SecureStorage>().clearAll();
context.read<AppCubit>().clearSession();
_api
.post('/auth/logout')
.timeout(const Duration(seconds: 3))
.ignore();
_api.post('/auth/logout').timeout(const Duration(seconds: 3)).ignore();
if (mounted) context.go('/login');
}