небольшие изменения

This commit is contained in:
Jganenokk
2026-07-05 19:07:27 +07:00
parent 26f0094705
commit 9f9b0e0734
214 changed files with 27592 additions and 15353 deletions
@@ -2,11 +2,12 @@ import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart';
import '../../../core/utils/haptics.dart';
import '../../../l10n/app_localizations.dart';
import '../../../main.dart' show accountModule, isOnemeFlavor;
import '../../widgets/connection_status.dart';
import '../../widgets/custom_notification.dart';
import '../../widgets/glossy_pill.dart';
import '../../widgets/section_header.dart';
import '../../widgets/settings_card.dart';
class NotificationsScreen extends StatefulWidget {
const NotificationsScreen({super.key});
@@ -16,8 +17,6 @@ class NotificationsScreen extends StatefulWidget {
}
class _NotificationsScreenState extends State<NotificationsScreen> {
static const String _defaultSound = 'oki.aiff';
bool _loading = true;
bool _saving = false;
@@ -49,7 +48,7 @@ class _NotificationsScreenState extends State<NotificationsScreen> {
Future<void> _apply(
bool value,
Map<String, dynamic> settings,
Future<void> Function() action,
ValueChanged<bool> assign,
) async {
if (_saving) return;
@@ -58,11 +57,14 @@ class _NotificationsScreenState extends State<NotificationsScreen> {
_saving = true;
});
try {
await accountModule.updatePrivacyConfig(settings);
await action();
} catch (e) {
if (mounted) {
setState(() => assign(!value));
showCustomNotification(context, 'Не удалось сохранить: $e');
showCustomNotification(
context,
AppLocalizations.of(context)!.notificationsSaveFailed(e.toString()),
);
}
} finally {
if (mounted) setState(() => _saving = false);
@@ -76,22 +78,24 @@ class _NotificationsScreenState extends State<NotificationsScreen> {
}
void _onFkmTap() {
final l10n = AppLocalizations.of(context)!;
showCustomNotification(
context,
isOnemeFlavor
? 'А зачем? У тебя уже FCM.'
: 'Скачай лучше FCM-версию.',
? l10n.notificationsFkmAlreadyHasFcm
: l10n.notificationsFkmDownloadFcm,
);
}
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
final l10n = AppLocalizations.of(context)!;
return Scaffold(
backgroundColor: cs.surface,
appBar: ConnectionTitleBar(
titleText: 'Уведомления',
titleText: l10n.notificationsTitle,
backgroundColor: cs.surface,
),
body: SafeArea(
@@ -102,207 +106,123 @@ class _NotificationsScreenState extends State<NotificationsScreen> {
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.fromLTRB(16, 12, 16, 120),
children: [
const SectionHeader(
'FKM',
padding: EdgeInsets.fromLTRB(8, 0, 8, 8),
SectionHeader(
l10n.notificationsFkmSectionTitle,
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
fontSize: 14,
),
_card(cs, [
_toggleRow(
cs,
icon: Symbols.notifications_active,
label: 'Включить уведомления',
subtitle:
'Для работы FKM уведомлений, приложению понадобится держать уведомление в шторке.',
value: false,
onChanged: (_) => _onFkmTap(),
),
]),
SettingsCard(
children: [
SettingsToggleTile(
icon: Symbols.notifications_active,
label: l10n.notificationsFkmEnableLabel,
subtitle: l10n.notificationsFkmEnableSubtitle,
value: false,
onChanged: (_) => _onFkmTap(),
),
],
),
const SizedBox(height: 20),
const SectionHeader(
'Уведомления',
padding: EdgeInsets.fromLTRB(8, 0, 8, 8),
SectionHeader(
l10n.notificationsMainSectionTitle,
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
fontSize: 14,
),
_card(cs, [
_toggleRow(
cs,
icon: Symbols.notifications,
label: 'Все уведомления',
value: _allNotifications,
onChanged: (v) => _apply(
v,
{'CHATS_PUSH_NOTIFICATION': v ? 'ON' : 'OFF'},
(b) => _allNotifications = b,
),
),
]),
const SizedBox(height: 20),
const SectionHeader(
'Все новые уведомления',
padding: EdgeInsets.fromLTRB(8, 0, 8, 8),
fontSize: 14,
),
_card(cs, [
_toggleRow(
cs,
icon: Symbols.chat,
label: 'Предпросмотр сообщений',
value: _messagePreview,
enabled: _allNotifications,
onChanged: (v) => _apply(
v,
{'PUSH_DETAILS': v},
(b) => _messagePreview = b,
),
),
_divider(cs),
_toggleRow(
cs,
icon: Symbols.music_note,
label: 'Звук',
value: _sound,
enabled: _allNotifications,
onChanged: (v) => _apply(
v,
{
'PUSH_SOUND': v ? _defaultSound : '',
'CHATS_PUSH_SOUND': v ? _defaultSound : '',
},
(b) => _sound = b,
),
),
]),
const SizedBox(height: 20),
const SectionHeader(
'Дополнительно',
padding: EdgeInsets.fromLTRB(8, 0, 8, 8),
fontSize: 14,
),
_card(cs, [
_toggleRow(
cs,
icon: Symbols.call,
label: 'Уведомления о звонках',
value: _callNotifications,
onChanged: (v) => _apply(
v,
{'M_CALL_PUSH_NOTIFICATION': v ? 'ON' : 'OFF'},
(b) => _callNotifications = b,
),
),
_divider(cs),
_toggleRow(
cs,
icon: Symbols.person_add,
label: 'Уведомления от новых контактов',
value: _newContacts,
onChanged: (v) => _apply(
v,
{'PUSH_NEW_CONTACTS': v},
(b) => _newContacts = b,
),
),
]),
const SizedBox(height: 20),
const SectionHeader(
'Тактильная отдача',
padding: EdgeInsets.fromLTRB(8, 0, 8, 8),
fontSize: 14,
),
_card(cs, [
_toggleRow(
cs,
icon: Symbols.vibration,
label: 'Тактильная отдача',
subtitle: 'Виброотклик при действиях в приложении',
value: _hapticsEnabled,
onChanged: _setHaptics,
),
]),
],
),
),
);
}
Widget _card(ColorScheme cs, List<Widget> children) {
return GlossyPill(
color: cs.surfaceContainerHigh,
borderRadius: BorderRadius.circular(20),
depth: 6,
child: Column(children: children),
);
}
Widget _divider(ColorScheme cs) {
return Padding(
padding: const EdgeInsets.only(left: 58),
child: Divider(
height: 1,
thickness: 1,
color: cs.outlineVariant.withValues(alpha: 0.35),
),
);
}
Widget _toggleRow(
ColorScheme cs, {
required IconData icon,
required String label,
String? subtitle,
required bool value,
required ValueChanged<bool> onChanged,
bool enabled = true,
}) {
return AnimatedOpacity(
duration: const Duration(milliseconds: 200),
opacity: enabled ? 1 : 0.4,
child: IgnorePointer(
ignoring: !enabled,
child: Material(
color: Colors.transparent,
child: InkWell(
onTap: () => onChanged(!value),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14),
child: Row(
children: [
Icon(icon, color: cs.onSurfaceVariant, size: 22, weight: 400),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
label,
style: TextStyle(
color: cs.onSurface,
fontSize: 16,
fontWeight: FontWeight.w500,
),
SettingsCard(
children: [
SettingsToggleTile(
icon: Symbols.notifications,
label: l10n.notificationsAllLabel,
value: _allNotifications,
onChanged: (v) => _apply(
v,
() => accountModule.setChatsPushNotification(v),
(b) => _allNotifications = b,
),
if (subtitle != null) ...[
const SizedBox(height: 2),
Text(
subtitle,
style: TextStyle(
color: cs.onSurfaceVariant,
fontSize: 13,
height: 1.3,
),
),
],
],
),
),
],
),
const SizedBox(height: 20),
SectionHeader(
l10n.notificationsNewSectionTitle,
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
fontSize: 14,
),
SettingsCard(
children: [
SettingsToggleTile(
icon: Symbols.chat,
label: l10n.notificationsPreviewLabel,
value: _messagePreview,
enabled: _allNotifications,
onChanged: (v) => _apply(
v,
() => accountModule.setMessagePreview(v),
(b) => _messagePreview = b,
),
),
SettingsToggleTile(
icon: Symbols.music_note,
label: l10n.notificationsSoundLabel,
value: _sound,
enabled: _allNotifications,
onChanged: (v) => _apply(
v,
() => accountModule.setNotificationSound(v),
(b) => _sound = b,
),
),
],
),
const SizedBox(height: 20),
SectionHeader(
l10n.notificationsAdditionalSectionTitle,
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
fontSize: 14,
),
SettingsCard(
children: [
SettingsToggleTile(
icon: Symbols.call,
label: l10n.notificationsCallsLabel,
value: _callNotifications,
onChanged: (v) => _apply(
v,
() => accountModule.setCallNotifications(v),
(b) => _callNotifications = b,
),
),
SettingsToggleTile(
icon: Symbols.person_add,
label: l10n.notificationsNewContactsLabel,
value: _newContacts,
onChanged: (v) => _apply(
v,
() => accountModule.setNewContacts(v),
(b) => _newContacts = b,
),
),
],
),
const SizedBox(height: 20),
SectionHeader(
l10n.notificationsHapticsSectionTitle,
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
fontSize: 14,
),
SettingsCard(
children: [
SettingsToggleTile(
icon: Symbols.vibration,
label: l10n.notificationsHapticsLabel,
subtitle: l10n.notificationsHapticsSubtitle,
value: _hapticsEnabled,
onChanged: _setHaptics,
),
],
),
const SizedBox(width: 12),
Switch(value: value, onChanged: onChanged),
],
),
),
),
),
),
);
}