197 lines
7.6 KiB
Dart
197 lines
7.6 KiB
Dart
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));
|
||
} |