part of '../settings_modal.dart'; class _PrivacySection extends ConsumerStatefulWidget { final PyramidTheme pt; const _PrivacySection({required this.pt}); @override ConsumerState<_PrivacySection> createState() => _PrivacySectionState(); } class _PrivacySectionState extends ConsumerState<_PrivacySection> { List _ignoredUsers = []; final Set _unblocking = {}; @override void initState() { super.initState(); _loadIgnoredUsers(); } Future _loadIgnoredUsers() async { final client = await ref.read(matrixClientProvider.future); if (mounted) setState(() => _ignoredUsers = List.from(client.ignoredUsers)); } Future _unblockUser(String userId) async { setState(() => _unblocking.add(userId)); try { final client = await ref.read(matrixClientProvider.future); await client.unignoreUser(userId); await _loadIgnoredUsers(); } catch (e) { // ignore — list will be stale but not crash } finally { if (mounted) setState(() => _unblocking.remove(userId)); } } @override Widget build(BuildContext context) { final pt = widget.pt; final presence = ref.watch(privacyPresenceProvider); final readReceipts = ref.watch(privacyReadReceiptsProvider); final typing = ref.watch(privacyTypingProvider); return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _SectionTitle( title: 'Datenschutz', subtitle: 'Steuere, was andere über dich erfahren.', pt: pt), _SettingsGroup(title: 'Sichtbarkeit', pt: pt, children: [ _SettingsRow( title: 'Online-Status anzeigen', desc: 'Anderen anzeigen, wenn du aktiv bist', pt: pt, control: _Toggle( value: presence, pt: pt, onChanged: (v) async { ref.read(privacyPresenceProvider.notifier).set(v); final client = await ref.read(matrixClientProvider.future); await client.setPresence( client.userID!, v ? PresenceType.online : PresenceType.offline, ).catchError((_) {}); }, ), ), _Divider(pt: pt), _SettingsRow( title: 'Lesebestätigungen senden', desc: 'Anderen zeigen, dass du ihre Nachrichten gelesen hast', pt: pt, control: _Toggle( value: readReceipts, pt: pt, onChanged: (v) => ref.read(privacyReadReceiptsProvider.notifier).set(v), ), ), _Divider(pt: pt), _SettingsRow( title: 'Tipp-Indikator senden', desc: '„schreibt…" Anzeige aktivieren', pt: pt, control: _Toggle( value: typing, pt: pt, onChanged: (v) => ref.read(privacyTypingProvider.notifier).set(v), ), ), ]), const SizedBox(height: 20), // ── Blocked users ────────────────────────────────────────────────── _SettingsGroup(title: 'Blockierte Nutzer (${_ignoredUsers.length})', pt: pt, children: [ if (_ignoredUsers.isEmpty) Padding( padding: const EdgeInsets.all(14), child: Text('Keine blockierten Nutzer.', style: TextStyle(color: pt.fgMuted, fontSize: 13)), ) else ..._ignoredUsers.asMap().entries.map((entry) { final i = entry.key; final userId = entry.value; final isUnblocking = _unblocking.contains(userId); return Column(children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), child: Row(children: [ Expanded( child: Text(userId, style: TextStyle(color: pt.fg, fontSize: 13), overflow: TextOverflow.ellipsis), ), if (isUnblocking) const SizedBox(width: 16, height: 16, child: CircularProgressIndicator.adaptive(strokeWidth: 2)) else TextButton( style: TextButton.styleFrom( foregroundColor: pt.accent, padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), minimumSize: Size.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), onPressed: () => _unblockUser(userId), child: const Text('Entblocken', style: TextStyle(fontSize: 12)), ), ]), ), if (i < _ignoredUsers.length - 1) _Divider(pt: pt), ]); }), ]), const SizedBox(height: 20), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: pt.accentSoft, borderRadius: BorderRadius.circular(10), border: Border.all(color: pt.accent.withAlpha(60)), ), child: Row( children: [ Icon(Icons.shield_outlined, size: 16, color: pt.accent), const SizedBox(width: 10), Expanded( child: Text( 'Alle Nachrichten sind Ende-zu-Ende-verschlüsselt.', style: TextStyle(color: pt.fg, fontSize: 12), ), ), ], ), ), ], ), ); } }