Revert "Reapply "починил выход, наконец-то. Сделал недо жесты, добавил эксперементалбные функции замены цвета у боковой панели и списка чатов, добавил настройку отступа сообщений на андроедах а то может у кого то ломаться""
This reverts commit ceeab44b7b.
This commit is contained in:
@@ -2,7 +2,6 @@ import 'dart:async';
|
||||
import 'dart:ui';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@@ -2973,13 +2972,11 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<ThemeProvider>();
|
||||
|
||||
final isDesktop =
|
||||
kIsWeb ||
|
||||
defaultTargetPlatform == TargetPlatform.windows ||
|
||||
defaultTargetPlatform == TargetPlatform.linux ||
|
||||
defaultTargetPlatform == TargetPlatform.macOS;
|
||||
|
||||
final body = Stack(
|
||||
return Scaffold(
|
||||
extendBodyBehindAppBar: theme.useGlassPanels,
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: _buildAppBar(),
|
||||
body: Stack(
|
||||
children: [
|
||||
Positioned.fill(child: _buildChatWallpaper(theme)),
|
||||
Column(
|
||||
@@ -3053,25 +3050,9 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOutCubic,
|
||||
padding: EdgeInsets.only(
|
||||
bottom: () {
|
||||
final baseInset = MediaQuery.of(
|
||||
bottom: MediaQuery.of(
|
||||
context,
|
||||
).viewInsets.bottom;
|
||||
final isAndroid =
|
||||
defaultTargetPlatform ==
|
||||
TargetPlatform.android;
|
||||
if (!isAndroid) {
|
||||
return baseInset;
|
||||
}
|
||||
final keyboardVisible = baseInset > 0.0;
|
||||
if (keyboardVisible &&
|
||||
theme
|
||||
.ignoreMobileBottomPaddingWhenKeyboard) {
|
||||
return baseInset;
|
||||
}
|
||||
return baseInset +
|
||||
theme.mobileChatBottomPadding;
|
||||
}(),
|
||||
).viewInsets.bottom,
|
||||
),
|
||||
child: ScrollablePositionedList.builder(
|
||||
itemScrollController: _itemScrollController,
|
||||
@@ -3081,9 +3062,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
8.0,
|
||||
8.0,
|
||||
8.0,
|
||||
widget.isChannel
|
||||
? 24.0
|
||||
: (isDesktop ? 100.0 : 0.0),
|
||||
widget.isChannel ? 16.0 : 100.0,
|
||||
),
|
||||
itemCount: _chatItems.length,
|
||||
itemBuilder: (context, index) {
|
||||
@@ -3110,9 +3089,8 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
_searchResults[_currentResultIndex]
|
||||
.id;
|
||||
|
||||
final isControlMessage = message.attaches.any(
|
||||
(a) => a['_type'] == 'CONTROL',
|
||||
);
|
||||
final isControlMessage = message.attaches
|
||||
.any((a) => a['_type'] == 'CONTROL');
|
||||
if (isControlMessage) {
|
||||
return _ControlMessageChip(
|
||||
message: message,
|
||||
@@ -3152,7 +3130,8 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
link['message']
|
||||
as Map<String, dynamic>?;
|
||||
final originalSenderId =
|
||||
forwardedMessage?['sender'] as int?;
|
||||
forwardedMessage?['sender']
|
||||
as int?;
|
||||
if (originalSenderId != null) {
|
||||
final originalSenderContact =
|
||||
_contactDetailsCache[originalSenderId];
|
||||
@@ -3210,7 +3189,9 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
);
|
||||
} else {
|
||||
senderName = 'ID ${message.senderId}';
|
||||
_loadContactIfNeeded(message.senderId);
|
||||
_loadContactIfNeeded(
|
||||
message.senderId,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3230,7 +3211,8 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
|
||||
String? decryptedText;
|
||||
if (_isEncryptionPasswordSetForCurrentChat &&
|
||||
_encryptionConfigForCurrentChat != null &&
|
||||
_encryptionConfigForCurrentChat !=
|
||||
null &&
|
||||
_encryptionConfigForCurrentChat!
|
||||
.password
|
||||
.isNotEmpty &&
|
||||
@@ -3336,7 +3318,8 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
_showComplaintDialog(item.message.id),
|
||||
);
|
||||
|
||||
Widget finalMessageWidget = bubble as Widget;
|
||||
Widget finalMessageWidget =
|
||||
bubble as Widget;
|
||||
|
||||
if (isHighlighted) {
|
||||
return TweenAnimationBuilder<double>(
|
||||
@@ -3358,9 +3341,8 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
.colorScheme
|
||||
.primaryContainer
|
||||
.withOpacity(value),
|
||||
borderRadius: BorderRadius.circular(
|
||||
16,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(16),
|
||||
border: Border.all(
|
||||
color: Theme.of(
|
||||
context,
|
||||
@@ -3390,7 +3372,10 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
return Opacity(
|
||||
opacity: value,
|
||||
child: Transform.translate(
|
||||
offset: Offset(0, 20 * (1 - value)),
|
||||
offset: Offset(
|
||||
0,
|
||||
20 * (1 - value),
|
||||
),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
@@ -3405,8 +3390,13 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
}
|
||||
if (isLastVisual && _isLoadingMore) {
|
||||
return TweenAnimationBuilder<double>(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
tween: Tween<double>(begin: 0.0, end: 1.0),
|
||||
duration: const Duration(
|
||||
milliseconds: 300,
|
||||
),
|
||||
tween: Tween<double>(
|
||||
begin: 0.0,
|
||||
end: 1.0,
|
||||
),
|
||||
curve: Curves.easeOut,
|
||||
builder: (context, value, child) {
|
||||
return Opacity(
|
||||
@@ -3446,7 +3436,9 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
scale: _showScrollToBottomNotifier.value ? 1.0 : 0.0,
|
||||
child: AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 150),
|
||||
opacity: _showScrollToBottomNotifier.value ? 1.0 : 0.0,
|
||||
opacity: _showScrollToBottomNotifier.value
|
||||
? 1.0
|
||||
: 0.0,
|
||||
child: FloatingActionButton(
|
||||
mini: true,
|
||||
onPressed: _scrollToBottom,
|
||||
@@ -3473,30 +3465,6 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
child: _buildTextInput(),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
if (isDesktop) {
|
||||
return Scaffold(
|
||||
extendBodyBehindAppBar: theme.useGlassPanels,
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: _buildAppBar(),
|
||||
body: body,
|
||||
);
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onHorizontalDragEnd: (details) {
|
||||
final velocity = details.primaryVelocity ?? 0;
|
||||
if (velocity > 400) {
|
||||
Navigator.of(context).maybePop();
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
extendBodyBehindAppBar: theme.useGlassPanels,
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: _buildAppBar(),
|
||||
body: body,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1997,63 +1997,13 @@ class _ChatsScreenState extends State<ChatsScreen>
|
||||
],
|
||||
);
|
||||
|
||||
final themeProvider = context.watch<ThemeProvider>();
|
||||
Widget? chatsListBackground;
|
||||
if (themeProvider.useExperimentalChatsListBackground) {
|
||||
switch (themeProvider.experimentalChatsListBackgroundType) {
|
||||
case ChatWallpaperType.solid:
|
||||
chatsListBackground = Container(color: themeProvider.experimentalChatsListBackgroundColor1);
|
||||
break;
|
||||
case ChatWallpaperType.gradient:
|
||||
chatsListBackground = Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
themeProvider.experimentalChatsListBackgroundColor1,
|
||||
themeProvider.experimentalChatsListBackgroundColor2,
|
||||
],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ChatWallpaperType.image:
|
||||
if (themeProvider.experimentalChatsListBackgroundImagePath != null) {
|
||||
chatsListBackground = Image.file(
|
||||
File(themeProvider.experimentalChatsListBackgroundImagePath!),
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
);
|
||||
}
|
||||
break;
|
||||
case ChatWallpaperType.video:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final bodyContentWithBackground = chatsListBackground != null
|
||||
? Stack(
|
||||
children: [
|
||||
Positioned.fill(child: chatsListBackground),
|
||||
bodyContent,
|
||||
],
|
||||
)
|
||||
: bodyContent;
|
||||
|
||||
if (widget.hasScaffold) {
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
final platform = Theme.of(context).platform;
|
||||
final isMobile =
|
||||
platform == TargetPlatform.android ||
|
||||
platform == TargetPlatform.iOS;
|
||||
|
||||
Widget scaffold = Scaffold(
|
||||
return Scaffold(
|
||||
appBar: _buildAppBar(context),
|
||||
drawer: _buildAppDrawer(context),
|
||||
body: Row(children: [Expanded(child: bodyContentWithBackground)]),
|
||||
body: Row(children: [Expanded(child: bodyContent)]),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
_showAddMenu(context);
|
||||
@@ -2063,50 +2013,10 @@ class _ChatsScreenState extends State<ChatsScreen>
|
||||
child: const Icon(Icons.edit),
|
||||
),
|
||||
);
|
||||
|
||||
if (!isMobile) return scaffold;
|
||||
|
||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
scaffold = Scaffold(
|
||||
key: scaffoldKey,
|
||||
appBar: _buildAppBar(context),
|
||||
drawer: _buildAppDrawer(context),
|
||||
body: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onHorizontalDragEnd: (details) {
|
||||
final velocity = details.primaryVelocity ?? 0;
|
||||
// Делаем жест проще: реагируем на более медленный свайп
|
||||
if (velocity < -150) {
|
||||
if (_folderTabController.length > 0 &&
|
||||
_folderTabController.index ==
|
||||
_folderTabController.length - 1) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (ctx) => const SettingsScreen(),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
scaffoldKey.currentState?.openDrawer();
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Row(children: [Expanded(child: bodyContentWithBackground)]),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
_showAddMenu(context);
|
||||
},
|
||||
tooltip: 'Создать',
|
||||
heroTag: 'create_menu',
|
||||
child: const Icon(Icons.edit),
|
||||
),
|
||||
);
|
||||
|
||||
return scaffold;
|
||||
},
|
||||
);
|
||||
} else {
|
||||
return bodyContentWithBackground;
|
||||
return bodyContent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2116,49 +2026,6 @@ class _ChatsScreenState extends State<ChatsScreen>
|
||||
final themeProvider = context.watch<ThemeProvider>();
|
||||
final isDarkMode = themeProvider.themeMode == ThemeMode.dark;
|
||||
|
||||
Widget? _buildBackgroundWidget(ChatWallpaperType type, Color color1, Color color2, String? imagePath) {
|
||||
switch (type) {
|
||||
case ChatWallpaperType.solid:
|
||||
return Container(color: color1);
|
||||
case ChatWallpaperType.gradient:
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [color1, color2],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
),
|
||||
);
|
||||
case ChatWallpaperType.image:
|
||||
if (imagePath != null) {
|
||||
return Image.file(
|
||||
File(imagePath),
|
||||
fit: BoxFit.cover,
|
||||
width: double.infinity,
|
||||
height: double.infinity,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
case ChatWallpaperType.video:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final drawerTopBackground = _buildBackgroundWidget(
|
||||
themeProvider.drawerTopBackgroundType,
|
||||
themeProvider.drawerTopBackgroundColor1,
|
||||
themeProvider.drawerTopBackgroundColor2,
|
||||
themeProvider.drawerTopBackgroundImagePath,
|
||||
);
|
||||
|
||||
final drawerBottomBackground = _buildBackgroundWidget(
|
||||
themeProvider.drawerBottomBackgroundType,
|
||||
themeProvider.drawerBottomBackgroundColor1,
|
||||
themeProvider.drawerBottomBackgroundColor2,
|
||||
themeProvider.drawerBottomBackgroundImagePath,
|
||||
);
|
||||
|
||||
return Drawer(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
@@ -2171,11 +2038,7 @@ class _ChatsScreenState extends State<ChatsScreen>
|
||||
final currentAccount = accountManager.currentAccount;
|
||||
final hasMultipleAccounts = accounts.length > 1;
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
if (drawerTopBackground != null)
|
||||
Positioned.fill(child: drawerTopBackground),
|
||||
Column(
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
@@ -2185,7 +2048,7 @@ class _ChatsScreenState extends State<ChatsScreen>
|
||||
right: 16.0,
|
||||
bottom: 16.0,
|
||||
),
|
||||
decoration: BoxDecoration(color: drawerTopBackground != null ? Colors.transparent : colors.primaryContainer),
|
||||
decoration: BoxDecoration(color: colors.primaryContainer),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -2429,17 +2292,11 @@ class _ChatsScreenState extends State<ChatsScreen>
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: Stack(
|
||||
children: [
|
||||
if (drawerBottomBackground != null)
|
||||
Positioned.fill(child: drawerBottomBackground),
|
||||
Column(
|
||||
child: Column(
|
||||
children: [
|
||||
_buildAccountsSection(context, colors),
|
||||
ListTile(
|
||||
@@ -2586,8 +2443,6 @@ class _ChatsScreenState extends State<ChatsScreen>
|
||||
const SizedBox(height: 8), // Небольшой отступ снизу
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -536,37 +536,6 @@ class _CustomizationScreenState extends State<CustomizationScreen> {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
_ExpandableSection(
|
||||
title: "Отступ внизу чата",
|
||||
initiallyExpanded: false,
|
||||
children: [
|
||||
_SliderTile(
|
||||
icon: Icons.vertical_align_bottom,
|
||||
label: "Доп. отступ снизу (мобилы)",
|
||||
value: theme.mobileChatBottomPadding,
|
||||
min: 60,
|
||||
max: 240,
|
||||
divisions: 18,
|
||||
onChanged: (value) =>
|
||||
theme.setMobileChatBottomPadding(value),
|
||||
displayValue:
|
||||
"${theme.mobileChatBottomPadding.toStringAsFixed(0)} px",
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
_CustomSettingTile(
|
||||
icon: Icons.keyboard,
|
||||
title: "Убирать отступ при открытой клавиатуре",
|
||||
subtitle:
|
||||
"Только Android. Когда вводите текст — отступ снизу не добавляется",
|
||||
child: Switch(
|
||||
value: theme.ignoreMobileBottomPaddingWhenKeyboard,
|
||||
onChanged: (value) => theme
|
||||
.setIgnoreMobileBottomPaddingWhenKeyboard(value),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// Развернуть настройки
|
||||
_ExpandableSection(
|
||||
title: "Настройки",
|
||||
@@ -613,296 +582,6 @@ class _CustomizationScreenState extends State<CustomizationScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
_ModernSection(
|
||||
title: "Экспериментальные настройки фона",
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: colors.errorContainer.withOpacity(0.3),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: colors.error.withOpacity(0.5),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(Icons.science, color: colors.error, size: 20),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Экспериментальные функции. Могут работать нестабильно.",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: colors.onErrorContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
_ExpandableSection(
|
||||
title: "Фон списка чатов",
|
||||
initiallyExpanded: false,
|
||||
children: [
|
||||
_CustomSettingTile(
|
||||
icon: Icons.science,
|
||||
title: "Использовать экспериментальный фон",
|
||||
subtitle: "Фон для экрана со списком чатов",
|
||||
child: Switch(
|
||||
value: theme.useExperimentalChatsListBackground,
|
||||
onChanged: (value) =>
|
||||
theme.setUseExperimentalChatsListBackground(value),
|
||||
),
|
||||
),
|
||||
if (theme.useExperimentalChatsListBackground) ...[
|
||||
const Divider(height: 24),
|
||||
_CustomSettingTile(
|
||||
icon: Icons.image,
|
||||
title: "Тип фона",
|
||||
child: DropdownButton<ChatWallpaperType>(
|
||||
value: theme.experimentalChatsListBackgroundType,
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
theme.setExperimentalChatsListBackgroundType(value);
|
||||
}
|
||||
},
|
||||
items: [
|
||||
ChatWallpaperType.solid,
|
||||
ChatWallpaperType.gradient,
|
||||
ChatWallpaperType.image,
|
||||
].map((type) {
|
||||
return DropdownMenuItem(
|
||||
value: type,
|
||||
child: Text(type.displayName),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
if (theme.experimentalChatsListBackgroundType ==
|
||||
ChatWallpaperType.solid ||
|
||||
theme.experimentalChatsListBackgroundType ==
|
||||
ChatWallpaperType.gradient) ...[
|
||||
const SizedBox(height: 16),
|
||||
_ColorPickerTile(
|
||||
title: "Цвет 1",
|
||||
subtitle: "Основной цвет",
|
||||
color: theme.experimentalChatsListBackgroundColor1,
|
||||
onColorChanged: (color) =>
|
||||
theme.setExperimentalChatsListBackgroundColor1(color),
|
||||
),
|
||||
],
|
||||
if (theme.experimentalChatsListBackgroundType ==
|
||||
ChatWallpaperType.gradient) ...[
|
||||
const SizedBox(height: 16),
|
||||
_ColorPickerTile(
|
||||
title: "Цвет 2",
|
||||
subtitle: "Дополнительный цвет для градиента",
|
||||
color: theme.experimentalChatsListBackgroundColor2,
|
||||
onColorChanged: (color) =>
|
||||
theme.setExperimentalChatsListBackgroundColor2(color),
|
||||
),
|
||||
],
|
||||
if (theme.experimentalChatsListBackgroundType ==
|
||||
ChatWallpaperType.image) ...[
|
||||
const Divider(height: 24),
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.photo_library_outlined),
|
||||
title: const Text("Выбрать изображение"),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () async {
|
||||
final picker = ImagePicker();
|
||||
final image = await picker.pickImage(
|
||||
source: ImageSource.gallery,
|
||||
);
|
||||
if (image != null) {
|
||||
theme.setExperimentalChatsListBackgroundImagePath(
|
||||
image.path,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
if (theme.experimentalChatsListBackgroundImagePath
|
||||
?.isNotEmpty ==
|
||||
true) ...[
|
||||
const SizedBox(height: 8),
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.delete_outline),
|
||||
title: const Text("Удалить изображение"),
|
||||
onTap: () {
|
||||
theme.setExperimentalChatsListBackgroundImagePath(null);
|
||||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_ExpandableSection(
|
||||
title: "Фон боковой панели - верхняя часть (профиль)",
|
||||
initiallyExpanded: false,
|
||||
children: [
|
||||
_CustomSettingTile(
|
||||
icon: Icons.image,
|
||||
title: "Тип фона",
|
||||
child: DropdownButton<ChatWallpaperType>(
|
||||
value: theme.drawerTopBackgroundType,
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
theme.setDrawerTopBackgroundType(value);
|
||||
}
|
||||
},
|
||||
items: [
|
||||
ChatWallpaperType.solid,
|
||||
ChatWallpaperType.gradient,
|
||||
ChatWallpaperType.image,
|
||||
].map((type) {
|
||||
return DropdownMenuItem(
|
||||
value: type,
|
||||
child: Text(type.displayName),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
if (theme.drawerTopBackgroundType == ChatWallpaperType.solid ||
|
||||
theme.drawerTopBackgroundType == ChatWallpaperType.gradient) ...[
|
||||
const SizedBox(height: 16),
|
||||
_ColorPickerTile(
|
||||
title: "Цвет 1",
|
||||
subtitle: "Основной цвет",
|
||||
color: theme.drawerTopBackgroundColor1,
|
||||
onColorChanged: (color) =>
|
||||
theme.setDrawerTopBackgroundColor1(color),
|
||||
),
|
||||
],
|
||||
if (theme.drawerTopBackgroundType == ChatWallpaperType.gradient) ...[
|
||||
const SizedBox(height: 16),
|
||||
_ColorPickerTile(
|
||||
title: "Цвет 2",
|
||||
subtitle: "Дополнительный цвет для градиента",
|
||||
color: theme.drawerTopBackgroundColor2,
|
||||
onColorChanged: (color) =>
|
||||
theme.setDrawerTopBackgroundColor2(color),
|
||||
),
|
||||
],
|
||||
if (theme.drawerTopBackgroundType == ChatWallpaperType.image) ...[
|
||||
const Divider(height: 24),
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.photo_library_outlined),
|
||||
title: const Text("Выбрать изображение"),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () async {
|
||||
final picker = ImagePicker();
|
||||
final image = await picker.pickImage(
|
||||
source: ImageSource.gallery,
|
||||
);
|
||||
if (image != null) {
|
||||
theme.setDrawerTopBackgroundImagePath(image.path);
|
||||
}
|
||||
},
|
||||
),
|
||||
if (theme.drawerTopBackgroundImagePath?.isNotEmpty == true) ...[
|
||||
const SizedBox(height: 8),
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.delete_outline),
|
||||
title: const Text("Удалить изображение"),
|
||||
onTap: () {
|
||||
theme.setDrawerTopBackgroundImagePath(null);
|
||||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
_ExpandableSection(
|
||||
title: "Фон боковой панели - нижняя часть (меню)",
|
||||
initiallyExpanded: false,
|
||||
children: [
|
||||
_CustomSettingTile(
|
||||
icon: Icons.image,
|
||||
title: "Тип фона",
|
||||
child: DropdownButton<ChatWallpaperType>(
|
||||
value: theme.drawerBottomBackgroundType,
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
theme.setDrawerBottomBackgroundType(value);
|
||||
}
|
||||
},
|
||||
items: [
|
||||
ChatWallpaperType.solid,
|
||||
ChatWallpaperType.gradient,
|
||||
ChatWallpaperType.image,
|
||||
].map((type) {
|
||||
return DropdownMenuItem(
|
||||
value: type,
|
||||
child: Text(type.displayName),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
if (theme.drawerBottomBackgroundType == ChatWallpaperType.solid ||
|
||||
theme.drawerBottomBackgroundType == ChatWallpaperType.gradient) ...[
|
||||
const SizedBox(height: 16),
|
||||
_ColorPickerTile(
|
||||
title: "Цвет 1",
|
||||
subtitle: "Основной цвет",
|
||||
color: theme.drawerBottomBackgroundColor1,
|
||||
onColorChanged: (color) =>
|
||||
theme.setDrawerBottomBackgroundColor1(color),
|
||||
),
|
||||
],
|
||||
if (theme.drawerBottomBackgroundType == ChatWallpaperType.gradient) ...[
|
||||
const SizedBox(height: 16),
|
||||
_ColorPickerTile(
|
||||
title: "Цвет 2",
|
||||
subtitle: "Дополнительный цвет для градиента",
|
||||
color: theme.drawerBottomBackgroundColor2,
|
||||
onColorChanged: (color) =>
|
||||
theme.setDrawerBottomBackgroundColor2(color),
|
||||
),
|
||||
],
|
||||
if (theme.drawerBottomBackgroundType == ChatWallpaperType.image) ...[
|
||||
const Divider(height: 24),
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.photo_library_outlined),
|
||||
title: const Text("Выбрать изображение"),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () async {
|
||||
final picker = ImagePicker();
|
||||
final image = await picker.pickImage(
|
||||
source: ImageSource.gallery,
|
||||
);
|
||||
if (image != null) {
|
||||
theme.setDrawerBottomBackgroundImagePath(image.path);
|
||||
}
|
||||
},
|
||||
),
|
||||
if (theme.drawerBottomBackgroundImagePath?.isNotEmpty == true) ...[
|
||||
const SizedBox(height: 8),
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.delete_outline),
|
||||
title: const Text("Удалить изображение"),
|
||||
onTap: () {
|
||||
theme.setDrawerBottomBackgroundImagePath(null);
|
||||
},
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -104,25 +104,6 @@ class CustomThemePreset {
|
||||
bool useDesktopLayout;
|
||||
bool useAutoReplyColor;
|
||||
Color? customReplyColor;
|
||||
double mobileChatBottomPadding;
|
||||
bool ignoreMobileBottomPaddingWhenKeyboard;
|
||||
|
||||
// Экспериментальные настройки фона
|
||||
bool useExperimentalChatsListBackground;
|
||||
ChatWallpaperType experimentalChatsListBackgroundType;
|
||||
Color experimentalChatsListBackgroundColor1;
|
||||
Color experimentalChatsListBackgroundColor2;
|
||||
String? experimentalChatsListBackgroundImagePath;
|
||||
|
||||
ChatWallpaperType drawerTopBackgroundType;
|
||||
Color drawerTopBackgroundColor1;
|
||||
Color drawerTopBackgroundColor2;
|
||||
String? drawerTopBackgroundImagePath;
|
||||
|
||||
ChatWallpaperType drawerBottomBackgroundType;
|
||||
Color drawerBottomBackgroundColor1;
|
||||
Color drawerBottomBackgroundColor2;
|
||||
String? drawerBottomBackgroundImagePath;
|
||||
|
||||
CustomThemePreset({
|
||||
required this.id,
|
||||
@@ -174,21 +155,6 @@ class CustomThemePreset {
|
||||
this.useDesktopLayout = true,
|
||||
this.useAutoReplyColor = true,
|
||||
this.customReplyColor,
|
||||
this.mobileChatBottomPadding = 140.0,
|
||||
this.ignoreMobileBottomPaddingWhenKeyboard = true,
|
||||
this.useExperimentalChatsListBackground = false,
|
||||
this.experimentalChatsListBackgroundType = ChatWallpaperType.solid,
|
||||
this.experimentalChatsListBackgroundColor1 = const Color(0xFF101010),
|
||||
this.experimentalChatsListBackgroundColor2 = const Color(0xFF202020),
|
||||
this.experimentalChatsListBackgroundImagePath,
|
||||
this.drawerTopBackgroundType = ChatWallpaperType.solid,
|
||||
this.drawerTopBackgroundColor1 = const Color(0xFF1E1E1E),
|
||||
this.drawerTopBackgroundColor2 = const Color(0xFF2E2E2E),
|
||||
this.drawerTopBackgroundImagePath,
|
||||
this.drawerBottomBackgroundType = ChatWallpaperType.solid,
|
||||
this.drawerBottomBackgroundColor1 = const Color(0xFF1E1E1E),
|
||||
this.drawerBottomBackgroundColor2 = const Color(0xFF2E2E2E),
|
||||
this.drawerBottomBackgroundImagePath,
|
||||
});
|
||||
|
||||
factory CustomThemePreset.createDefault() {
|
||||
@@ -245,21 +211,6 @@ class CustomThemePreset {
|
||||
bool? useDesktopLayout,
|
||||
bool? useAutoReplyColor,
|
||||
Color? customReplyColor,
|
||||
double? mobileChatBottomPadding,
|
||||
bool? ignoreMobileBottomPaddingWhenKeyboard,
|
||||
bool? useExperimentalChatsListBackground,
|
||||
ChatWallpaperType? experimentalChatsListBackgroundType,
|
||||
Color? experimentalChatsListBackgroundColor1,
|
||||
Color? experimentalChatsListBackgroundColor2,
|
||||
String? experimentalChatsListBackgroundImagePath,
|
||||
ChatWallpaperType? drawerTopBackgroundType,
|
||||
Color? drawerTopBackgroundColor1,
|
||||
Color? drawerTopBackgroundColor2,
|
||||
String? drawerTopBackgroundImagePath,
|
||||
ChatWallpaperType? drawerBottomBackgroundType,
|
||||
Color? drawerBottomBackgroundColor1,
|
||||
Color? drawerBottomBackgroundColor2,
|
||||
String? drawerBottomBackgroundImagePath,
|
||||
}) {
|
||||
return CustomThemePreset(
|
||||
id: id ?? this.id,
|
||||
@@ -320,35 +271,6 @@ class CustomThemePreset {
|
||||
useDesktopLayout: useDesktopLayout ?? this.useDesktopLayout,
|
||||
useAutoReplyColor: useAutoReplyColor ?? this.useAutoReplyColor,
|
||||
customReplyColor: customReplyColor ?? this.customReplyColor,
|
||||
mobileChatBottomPadding:
|
||||
mobileChatBottomPadding ?? this.mobileChatBottomPadding,
|
||||
ignoreMobileBottomPaddingWhenKeyboard:
|
||||
ignoreMobileBottomPaddingWhenKeyboard ??
|
||||
this.ignoreMobileBottomPaddingWhenKeyboard,
|
||||
useExperimentalChatsListBackground: useExperimentalChatsListBackground ??
|
||||
this.useExperimentalChatsListBackground,
|
||||
experimentalChatsListBackgroundType: experimentalChatsListBackgroundType ??
|
||||
this.experimentalChatsListBackgroundType,
|
||||
experimentalChatsListBackgroundColor1: experimentalChatsListBackgroundColor1 ??
|
||||
this.experimentalChatsListBackgroundColor1,
|
||||
experimentalChatsListBackgroundColor2: experimentalChatsListBackgroundColor2 ??
|
||||
this.experimentalChatsListBackgroundColor2,
|
||||
experimentalChatsListBackgroundImagePath: experimentalChatsListBackgroundImagePath ??
|
||||
this.experimentalChatsListBackgroundImagePath,
|
||||
drawerTopBackgroundType: drawerTopBackgroundType ?? this.drawerTopBackgroundType,
|
||||
drawerTopBackgroundColor1:
|
||||
drawerTopBackgroundColor1 ?? this.drawerTopBackgroundColor1,
|
||||
drawerTopBackgroundColor2:
|
||||
drawerTopBackgroundColor2 ?? this.drawerTopBackgroundColor2,
|
||||
drawerTopBackgroundImagePath:
|
||||
drawerTopBackgroundImagePath ?? this.drawerTopBackgroundImagePath,
|
||||
drawerBottomBackgroundType: drawerBottomBackgroundType ?? this.drawerBottomBackgroundType,
|
||||
drawerBottomBackgroundColor1:
|
||||
drawerBottomBackgroundColor1 ?? this.drawerBottomBackgroundColor1,
|
||||
drawerBottomBackgroundColor2:
|
||||
drawerBottomBackgroundColor2 ?? this.drawerBottomBackgroundColor2,
|
||||
drawerBottomBackgroundImagePath:
|
||||
drawerBottomBackgroundImagePath ?? this.drawerBottomBackgroundImagePath,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -403,22 +325,6 @@ class CustomThemePreset {
|
||||
'useDesktopLayout': useDesktopLayout,
|
||||
'useAutoReplyColor': useAutoReplyColor,
|
||||
'customReplyColor': customReplyColor?.value,
|
||||
'mobileChatBottomPadding': mobileChatBottomPadding,
|
||||
'ignoreMobileBottomPaddingWhenKeyboard':
|
||||
ignoreMobileBottomPaddingWhenKeyboard,
|
||||
'useExperimentalChatsListBackground': useExperimentalChatsListBackground,
|
||||
'experimentalChatsListBackgroundType': experimentalChatsListBackgroundType.index,
|
||||
'experimentalChatsListBackgroundColor1': experimentalChatsListBackgroundColor1.value,
|
||||
'experimentalChatsListBackgroundColor2': experimentalChatsListBackgroundColor2.value,
|
||||
'experimentalChatsListBackgroundImagePath': experimentalChatsListBackgroundImagePath,
|
||||
'drawerTopBackgroundType': drawerTopBackgroundType.index,
|
||||
'drawerTopBackgroundColor1': drawerTopBackgroundColor1.value,
|
||||
'drawerTopBackgroundColor2': drawerTopBackgroundColor2.value,
|
||||
'drawerTopBackgroundImagePath': drawerTopBackgroundImagePath,
|
||||
'drawerBottomBackgroundType': drawerBottomBackgroundType.index,
|
||||
'drawerBottomBackgroundColor1': drawerBottomBackgroundColor1.value,
|
||||
'drawerBottomBackgroundColor2': drawerBottomBackgroundColor2.value,
|
||||
'drawerBottomBackgroundImagePath': drawerBottomBackgroundImagePath,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -516,44 +422,6 @@ class CustomThemePreset {
|
||||
customReplyColor: json['customReplyColor'] != null
|
||||
? Color(json['customReplyColor'] as int)
|
||||
: null,
|
||||
mobileChatBottomPadding:
|
||||
(json['mobileChatBottomPadding'] as double? ?? 140.0).clamp(
|
||||
60.0,
|
||||
240.0,
|
||||
),
|
||||
ignoreMobileBottomPaddingWhenKeyboard:
|
||||
json['ignoreMobileBottomPaddingWhenKeyboard'] as bool? ?? true,
|
||||
useExperimentalChatsListBackground: json['useExperimentalChatsListBackground'] as bool? ?? false,
|
||||
experimentalChatsListBackgroundType: () {
|
||||
final index = json['experimentalChatsListBackgroundType'] as int?;
|
||||
if (index == null || index < 0 || index >= ChatWallpaperType.values.length) {
|
||||
return ChatWallpaperType.solid;
|
||||
}
|
||||
return ChatWallpaperType.values[index];
|
||||
}(),
|
||||
experimentalChatsListBackgroundColor1: Color(json['experimentalChatsListBackgroundColor1'] as int? ?? const Color(0xFF101010).value),
|
||||
experimentalChatsListBackgroundColor2: Color(json['experimentalChatsListBackgroundColor2'] as int? ?? const Color(0xFF202020).value),
|
||||
experimentalChatsListBackgroundImagePath: json['experimentalChatsListBackgroundImagePath'] as String?,
|
||||
drawerTopBackgroundType: () {
|
||||
final index = json['drawerTopBackgroundType'] as int?;
|
||||
if (index == null || index < 0 || index >= ChatWallpaperType.values.length) {
|
||||
return ChatWallpaperType.solid;
|
||||
}
|
||||
return ChatWallpaperType.values[index];
|
||||
}(),
|
||||
drawerTopBackgroundColor1: Color(json['drawerTopBackgroundColor1'] as int? ?? const Color(0xFF1E1E1E).value),
|
||||
drawerTopBackgroundColor2: Color(json['drawerTopBackgroundColor2'] as int? ?? const Color(0xFF2E2E2E).value),
|
||||
drawerTopBackgroundImagePath: json['drawerTopBackgroundImagePath'] as String?,
|
||||
drawerBottomBackgroundType: () {
|
||||
final index = json['drawerBottomBackgroundType'] as int?;
|
||||
if (index == null || index < 0 || index >= ChatWallpaperType.values.length) {
|
||||
return ChatWallpaperType.solid;
|
||||
}
|
||||
return ChatWallpaperType.values[index];
|
||||
}(),
|
||||
drawerBottomBackgroundColor1: Color(json['drawerBottomBackgroundColor1'] as int? ?? const Color(0xFF1E1E1E).value),
|
||||
drawerBottomBackgroundColor2: Color(json['drawerBottomBackgroundColor2'] as int? ?? const Color(0xFF2E2E2E).value),
|
||||
drawerBottomBackgroundImagePath: json['drawerBottomBackgroundImagePath'] as String?,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -661,26 +529,6 @@ class ThemeProvider with ChangeNotifier {
|
||||
bool get debugShowMessageCount => _debugShowMessageCount;
|
||||
bool get debugReadOnEnter => _debugReadOnEnter;
|
||||
bool get debugReadOnAction => _debugReadOnAction;
|
||||
double get mobileChatBottomPadding => _activeTheme.mobileChatBottomPadding;
|
||||
bool get ignoreMobileBottomPaddingWhenKeyboard =>
|
||||
_activeTheme.ignoreMobileBottomPaddingWhenKeyboard;
|
||||
|
||||
// Экспериментальные настройки фона
|
||||
bool get useExperimentalChatsListBackground => _activeTheme.useExperimentalChatsListBackground;
|
||||
ChatWallpaperType get experimentalChatsListBackgroundType => _activeTheme.experimentalChatsListBackgroundType;
|
||||
Color get experimentalChatsListBackgroundColor1 => _activeTheme.experimentalChatsListBackgroundColor1;
|
||||
Color get experimentalChatsListBackgroundColor2 => _activeTheme.experimentalChatsListBackgroundColor2;
|
||||
String? get experimentalChatsListBackgroundImagePath => _activeTheme.experimentalChatsListBackgroundImagePath;
|
||||
|
||||
ChatWallpaperType get drawerTopBackgroundType => _activeTheme.drawerTopBackgroundType;
|
||||
Color get drawerTopBackgroundColor1 => _activeTheme.drawerTopBackgroundColor1;
|
||||
Color get drawerTopBackgroundColor2 => _activeTheme.drawerTopBackgroundColor2;
|
||||
String? get drawerTopBackgroundImagePath => _activeTheme.drawerTopBackgroundImagePath;
|
||||
|
||||
ChatWallpaperType get drawerBottomBackgroundType => _activeTheme.drawerBottomBackgroundType;
|
||||
Color get drawerBottomBackgroundColor1 => _activeTheme.drawerBottomBackgroundColor1;
|
||||
Color get drawerBottomBackgroundColor2 => _activeTheme.drawerBottomBackgroundColor2;
|
||||
String? get drawerBottomBackgroundImagePath => _activeTheme.drawerBottomBackgroundImagePath;
|
||||
|
||||
TransitionOption get chatTransition => _activeTheme.ultraOptimizeChats
|
||||
? TransitionOption.systemDefault
|
||||
@@ -1364,101 +1212,6 @@ class ThemeProvider with ChangeNotifier {
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setMobileChatBottomPadding(double value) async {
|
||||
final clamped = value.clamp(60.0, 240.0);
|
||||
_activeTheme = _activeTheme.copyWith(
|
||||
mobileChatBottomPadding: clamped,
|
||||
);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setIgnoreMobileBottomPaddingWhenKeyboard(bool value) async {
|
||||
_activeTheme = _activeTheme.copyWith(
|
||||
ignoreMobileBottomPaddingWhenKeyboard: value,
|
||||
);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setUseExperimentalChatsListBackground(bool value) async {
|
||||
_activeTheme = _activeTheme.copyWith(useExperimentalChatsListBackground: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setExperimentalChatsListBackgroundType(ChatWallpaperType value) async {
|
||||
_activeTheme = _activeTheme.copyWith(experimentalChatsListBackgroundType: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setExperimentalChatsListBackgroundColor1(Color value) async {
|
||||
_activeTheme = _activeTheme.copyWith(experimentalChatsListBackgroundColor1: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setExperimentalChatsListBackgroundColor2(Color value) async {
|
||||
_activeTheme = _activeTheme.copyWith(experimentalChatsListBackgroundColor2: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setExperimentalChatsListBackgroundImagePath(String? path) async {
|
||||
_activeTheme = _activeTheme.copyWith(experimentalChatsListBackgroundImagePath: path);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setDrawerTopBackgroundType(ChatWallpaperType value) async {
|
||||
_activeTheme = _activeTheme.copyWith(drawerTopBackgroundType: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setDrawerTopBackgroundColor1(Color value) async {
|
||||
_activeTheme = _activeTheme.copyWith(drawerTopBackgroundColor1: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setDrawerTopBackgroundColor2(Color value) async {
|
||||
_activeTheme = _activeTheme.copyWith(drawerTopBackgroundColor2: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setDrawerTopBackgroundImagePath(String? path) async {
|
||||
_activeTheme = _activeTheme.copyWith(drawerTopBackgroundImagePath: path);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setDrawerBottomBackgroundType(ChatWallpaperType value) async {
|
||||
_activeTheme = _activeTheme.copyWith(drawerBottomBackgroundType: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setDrawerBottomBackgroundColor1(Color value) async {
|
||||
_activeTheme = _activeTheme.copyWith(drawerBottomBackgroundColor1: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setDrawerBottomBackgroundColor2(Color value) async {
|
||||
_activeTheme = _activeTheme.copyWith(drawerBottomBackgroundColor2: value);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setDrawerBottomBackgroundImagePath(String? path) async {
|
||||
_activeTheme = _activeTheme.copyWith(drawerBottomBackgroundImagePath: path);
|
||||
notifyListeners();
|
||||
await _saveActiveTheme();
|
||||
}
|
||||
|
||||
Future<void> setCustomReplyColor(Color? color) async {
|
||||
_activeTheme = _activeTheme.copyWith(customReplyColor: color);
|
||||
notifyListeners();
|
||||
|
||||
Reference in New Issue
Block a user