5d772389d6
Reine Verschiebung per Dart part/part-of (keine Umbenennung, keine Logikänderung) - settings_modal.dart schrumpft von 5541 auf 270 Zeilen. Verifiziert per automatisiertem Blockvergleich gegen das Original und flutter analyze (Baseline unverändert: 1 bekannter Hinweis). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
163 lines
6.0 KiB
Dart
163 lines
6.0 KiB
Dart
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<String> _ignoredUsers = [];
|
|
final Set<String> _unblocking = {};
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadIgnoredUsers();
|
|
}
|
|
|
|
Future<void> _loadIgnoredUsers() async {
|
|
final client = await ref.read(matrixClientProvider.future);
|
|
if (mounted) setState(() => _ignoredUsers = List.from(client.ignoredUsers));
|
|
}
|
|
|
|
Future<void> _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),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|