Chepuhagram/lib/presentation/screens/privacy_settings_screen.dart

197 lines
7.6 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:chepuhagram/domain/services/api_service.dart';
class PrivacySettingsScreen extends StatefulWidget {
const PrivacySettingsScreen({super.key});
@override
State<PrivacySettingsScreen> createState() => _PrivacySettingsScreenState();
}
class _PrivacySettingsScreenState extends State<PrivacySettingsScreen> {
static const _showEmailKey = 'privacy_show_email';
static const _showPhoneKey = 'privacy_show_phone';
static const _showAvatarKey = 'privacy_show_avatar';
static const _showAboutKey = 'privacy_show_about';
static const _showLastOnlineKey = 'privacy_show_last_online';
bool _showEmail = true;
bool _showPhone = true;
bool _showAvatar = true;
bool _showAbout = true;
bool _showLastOnline = true;
bool _isSaving = false;
@override
void initState() {
super.initState();
_loadPreferences();
_loadServerSettings();
}
Future<void> _loadPreferences() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_showEmail = prefs.getBool(_showEmailKey) ?? true;
_showPhone = prefs.getBool(_showPhoneKey) ?? true;
_showAvatar = prefs.getBool(_showAvatarKey) ?? true;
_showAbout = prefs.getBool(_showAboutKey) ?? true;
_showLastOnline = prefs.getBool(_showLastOnlineKey) ?? true;
});
}
Future<void> _loadServerSettings() async {
try {
final api = ApiService();
final data = await api.getPrivacySettings();
setState(() {
_showEmail = data['show_email'] ?? true;
_showPhone = data['show_phone'] ?? true;
_showAvatar = data['show_avatar'] ?? true;
_showAbout = data['show_about'] ?? true;
_showLastOnline = data['show_last_online'] ?? true;
});
await _savePreference(_showEmailKey, _showEmail);
await _savePreference(_showPhoneKey, _showPhone);
await _savePreference(_showAvatarKey, _showAvatar);
await _savePreference(_showAboutKey, _showAbout);
await _savePreference(_showLastOnlineKey, _showLastOnline);
} catch (e) {
print('Ошибка загрузки настроек с сервера: $e');
}
}
Future<void> _savePreference(String key, bool value) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(key, value);
}
Future<void> _saveToServer() async {
if (_isSaving) return;
setState(() => _isSaving = true);
try {
final api = ApiService();
final success = await api.updatePrivacySettings(
showEmail: _showEmail,
showPhone: _showPhone,
showAvatar: _showAvatar,
showAbout: _showAbout,
showLastOnline: _showLastOnline,
);
if (success) {
await _savePreference(_showEmailKey, _showEmail);
await _savePreference(_showPhoneKey, _showPhone);
await _savePreference(_showAvatarKey, _showAvatar);
await _savePreference(_showAboutKey, _showAbout);
await _savePreference(_showLastOnlineKey, _showLastOnline);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Настройки видимости сохранены'), behavior: SnackBarBehavior.floating),
);
}
}
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Ошибка: ${e.toString().replaceAll('Exception: ', '')}'), behavior: SnackBarBehavior.floating),
);
}
} finally {
if (mounted) setState(() => _isSaving = false);
}
}
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Scaffold(
backgroundColor: colorScheme.background,
appBar: AppBar(
title: const Text('Видимость данных', style: TextStyle(fontWeight: FontWeight.bold)),
elevation: 0,
backgroundColor: Colors.transparent,
actions: [
Padding(
padding: const EdgeInsets.only(right: 8.0),
child: Center(
child: _isSaving
? SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2, color: colorScheme.primary))
: TextButton.icon(
onPressed: _saveToServer,
icon: const Icon(Icons.save_rounded, size: 18),
label: const Text('Сохранить'),
),
),
),
],
),
body: ListView(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.all(16),
children: [
const Padding(
padding: EdgeInsets.only(left: 8.0, bottom: 12),
child: Text('Кто видит мою информацию:', style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold, letterSpacing: 0.5)),
),
Container(
decoration: BoxDecoration(
color: colorScheme.surfaceVariant.withOpacity(0.2),
borderRadius: BorderRadius.circular(24),
border: Border.all(color: colorScheme.outlineVariant.withOpacity(0.1)),
),
child: Column(
children: [
_buildSwitchTile('Показывать почту другим', _showEmail, (v) => setState(() => _showEmail = v)),
_buildDivider(),
_buildSwitchTile('Показывать телефон другим', _showPhone, (v) => setState(() => _showPhone = v)),
_buildDivider(),
_buildSwitchTile('Показывать аватар другим', _showAvatar, (v) => setState(() => _showAvatar = v)),
_buildDivider(),
_buildSwitchTile('Показывать информацию «О себе»', _showAbout, (v) => setState(() => _showAbout = v)),
_buildDivider(),
_buildSwitchTile('Показывать последний онлайн', _showLastOnline, (v) => setState(() => _showLastOnline = v)),
],
),
),
const SizedBox(height: 24),
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: colorScheme.primary.withOpacity(0.04),
borderRadius: BorderRadius.circular(16),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Icon(Icons.lock_person_rounded, color: colorScheme.primary, size: 20),
const SizedBox(width: 12),
Expanded(
child: Text(
'Эти настройки напрямую влияют на то, какие персональные данные будут доступны другим участникам в глобальном поиске и карточках чатов.',
style: TextStyle(color: colorScheme.outline, fontSize: 13, height: 1.4),
),
),
],
),
),
],
),
);
}
Widget _buildSwitchTile(String title, bool value, ValueChanged<bool> onChanged) {
return SwitchListTile(
title: Text(title, style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w500)),
value: value,
onChanged: onChanged,
contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 2),
);
}
Widget _buildDivider() => Divider(height: 1, indent: 20, endIndent: 20, color: Theme.of(context).colorScheme.outlineVariant.withOpacity(0.2));
}