mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:28:41 +00:00
fix #289
This commit is contained in:
parent
57334d9eee
commit
94f60b5806
10 changed files with 309 additions and 208 deletions
|
|
@ -5,7 +5,9 @@
|
|||
- Support for groups
|
||||
- Edit & Delete messages
|
||||
- Switched to FFmpeg for improved video compression
|
||||
- Create images using volume buttons
|
||||
- Video max. length increased to 60 seconds
|
||||
- New and improved emoji picker
|
||||
- Removing audio after recording is possible
|
||||
- Edited image is now embedded into the video
|
||||
- New context menu and other UI enhancements
|
||||
|
|
|
|||
|
|
@ -118,6 +118,8 @@ class _AppState extends State<App> with WidgetsBindingObserver {
|
|||
colorScheme: ColorScheme.fromSeed(
|
||||
brightness: Brightness.dark,
|
||||
seedColor: const Color(0xFF57CC99),
|
||||
surface: const Color.fromARGB(255, 20, 18, 23),
|
||||
surfaceContainer: const Color.fromARGB(255, 33, 30, 39),
|
||||
),
|
||||
inputDecorationTheme: const InputDecorationTheme(
|
||||
border: OutlineInputBorder(),
|
||||
|
|
|
|||
|
|
@ -64,8 +64,6 @@ class UserData {
|
|||
@JsonKey(defaultValue: false)
|
||||
bool storeMediaFilesInGallery = false;
|
||||
|
||||
List<String>? lastUsedEditorEmojis;
|
||||
|
||||
String? lastPlanBallance;
|
||||
String? additionalUserInvites;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,9 +40,6 @@ UserData _$UserDataFromJson(Map<String, dynamic> json) => UserData(
|
|||
)
|
||||
..storeMediaFilesInGallery =
|
||||
json['storeMediaFilesInGallery'] as bool? ?? false
|
||||
..lastUsedEditorEmojis = (json['lastUsedEditorEmojis'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList()
|
||||
..lastPlanBallance = json['lastPlanBallance'] as String?
|
||||
..additionalUserInvites = json['additionalUserInvites'] as String?
|
||||
..tutorialDisplayed = (json['tutorialDisplayed'] as List<dynamic>?)
|
||||
|
|
@ -93,7 +90,6 @@ Map<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
|
|||
'preSelectedEmojies': instance.preSelectedEmojies,
|
||||
'autoDownloadOptions': instance.autoDownloadOptions,
|
||||
'storeMediaFilesInGallery': instance.storeMediaFilesInGallery,
|
||||
'lastUsedEditorEmojis': instance.lastUsedEditorEmojis,
|
||||
'lastPlanBallance': instance.lastPlanBallance,
|
||||
'additionalUserInvites': instance.additionalUserInvites,
|
||||
'tutorialDisplayed': instance.tutorialDisplayed,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class TextLayer extends StatefulWidget {
|
|||
class _TextViewState extends State<TextLayer> {
|
||||
double initialRotation = 0;
|
||||
bool deleteLayer = false;
|
||||
double localBottom = 0;
|
||||
bool isDeleted = false;
|
||||
bool elementIsScaled = false;
|
||||
final GlobalKey _widgetKey = GlobalKey(); // Create a GlobalKey
|
||||
|
|
@ -35,9 +36,19 @@ class _TextViewState extends State<TextLayer> {
|
|||
|
||||
textController.text = widget.layerData.text;
|
||||
|
||||
if (widget.layerData.offset.dy == 0) {
|
||||
// Set the initial offset to the center of the screen
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
final mq = MediaQuery.of(context);
|
||||
final globalDesiredBottom = mq.viewInsets.bottom + mq.viewPadding.bottom;
|
||||
final parentBox = context.findRenderObject() as RenderBox?;
|
||||
if (parentBox != null) {
|
||||
final parentTopGlobal = parentBox.localToGlobal(Offset.zero).dy;
|
||||
final screenHeight = mq.size.height;
|
||||
localBottom = (screenHeight - globalDesiredBottom) -
|
||||
parentTopGlobal -
|
||||
(parentBox.size.height);
|
||||
}
|
||||
|
||||
if (widget.layerData.offset.dy == 0) {
|
||||
setState(() {
|
||||
widget.layerData.offset = Offset(
|
||||
0,
|
||||
|
|
@ -47,17 +58,20 @@ class _TextViewState extends State<TextLayer> {
|
|||
);
|
||||
textController.text = widget.layerData.text;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.layerData.isDeleted) return Container();
|
||||
|
||||
final bottom = MediaQuery.of(context).viewInsets.bottom +
|
||||
MediaQuery.of(context).viewPadding.bottom;
|
||||
|
||||
if (widget.layerData.isEditing) {
|
||||
return Positioned(
|
||||
bottom: MediaQuery.of(context).viewInsets.bottom - 100,
|
||||
bottom: bottom - localBottom,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
|
|
|
|||
|
|
@ -1,107 +1,83 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'dart:io';
|
||||
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:twonly/globals.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/camera/image_editor/data/data.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/camera/image_editor/data/layer.dart';
|
||||
|
||||
class Emojis extends StatefulWidget {
|
||||
const Emojis({super.key});
|
||||
|
||||
@override
|
||||
State<Emojis> createState() => _EmojisState();
|
||||
}
|
||||
|
||||
class _EmojisState extends State<Emojis> {
|
||||
List<String> lastUsed = emojis;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
unawaited(initAsync());
|
||||
}
|
||||
|
||||
Future<void> initAsync() async {
|
||||
setState(() {
|
||||
lastUsed = gUser.lastUsedEditorEmojis ?? [];
|
||||
lastUsed.addAll(emojis);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> selectEmojis(String emoji) async {
|
||||
await updateUserdata((user) {
|
||||
if (user.lastUsedEditorEmojis == null) {
|
||||
user.lastUsedEditorEmojis = [emoji];
|
||||
} else {
|
||||
if (user.lastUsedEditorEmojis!.contains(emoji)) {
|
||||
user.lastUsedEditorEmojis!.remove(emoji);
|
||||
}
|
||||
user.lastUsedEditorEmojis!.insert(0, emoji);
|
||||
if (user.lastUsedEditorEmojis!.length > 12) {
|
||||
user.lastUsedEditorEmojis = user.lastUsedEditorEmojis!.sublist(0, 12);
|
||||
}
|
||||
user.lastUsedEditorEmojis!.toSet().toList();
|
||||
}
|
||||
return user;
|
||||
});
|
||||
if (!mounted) return;
|
||||
Navigator.pop(
|
||||
context,
|
||||
EmojiLayerData(
|
||||
text: emoji,
|
||||
),
|
||||
);
|
||||
}
|
||||
class EmojiPickerBottom extends StatelessWidget {
|
||||
const EmojiPickerBottom({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SingleChildScrollView(
|
||||
child: Container(
|
||||
padding: EdgeInsets.zero,
|
||||
height: 400,
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
height: 450,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(32),
|
||||
topRight: Radius.circular(32),
|
||||
),
|
||||
color: Colors.black,
|
||||
color: context.color.surfaceContainer,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
blurRadius: 10.9,
|
||||
color: Color.fromRGBO(0, 0, 0, 0.1),
|
||||
color: context.color.surfaceContainer.withAlpha(25),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
height: 315,
|
||||
padding: EdgeInsets.zero,
|
||||
child: GridView(
|
||||
shrinkWrap: true,
|
||||
physics: const ClampingScrollPhysics(),
|
||||
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
maxCrossAxisExtent: 60,
|
||||
),
|
||||
children: lastUsed.map((String emoji) {
|
||||
return GridTile(
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
await selectEmojis(emoji);
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.zero,
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
emoji,
|
||||
style: const TextStyle(fontSize: 35),
|
||||
),
|
||||
),
|
||||
margin: const EdgeInsets.all(30),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(32),
|
||||
color: Colors.grey,
|
||||
),
|
||||
height: 3,
|
||||
width: 60,
|
||||
),
|
||||
Expanded(
|
||||
child: EmojiPicker(
|
||||
onEmojiSelected: (category, emoji) {
|
||||
Navigator.pop(
|
||||
context,
|
||||
EmojiLayerData(
|
||||
text: emoji.emoji,
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
},
|
||||
// textEditingController: _textFieldController,
|
||||
config: Config(
|
||||
height: 400,
|
||||
locale: Localizations.localeOf(context),
|
||||
viewOrderConfig: const ViewOrderConfig(
|
||||
top: EmojiPickerItem.searchBar,
|
||||
// middle: EmojiPickerItem.emojiView,
|
||||
bottom: EmojiPickerItem.categoryBar,
|
||||
),
|
||||
emojiTextStyle:
|
||||
TextStyle(fontSize: 24 * (Platform.isIOS ? 1.2 : 1)),
|
||||
emojiViewConfig: EmojiViewConfig(
|
||||
backgroundColor: context.color.surfaceContainer,
|
||||
),
|
||||
searchViewConfig: SearchViewConfig(
|
||||
backgroundColor: context.color.surfaceContainer,
|
||||
buttonIconColor: Colors.white,
|
||||
),
|
||||
categoryViewConfig: CategoryViewConfig(
|
||||
backgroundColor: context.color.surfaceContainer,
|
||||
dividerColor: Colors.white,
|
||||
indicatorColor: context.color.primary,
|
||||
iconColorSelected: context.color.primary,
|
||||
iconColor: context.color.secondary,
|
||||
),
|
||||
bottomActionBarConfig: BottomActionBarConfig(
|
||||
backgroundColor: context.color.surfaceContainer,
|
||||
buttonColor: context.color.surfaceContainer,
|
||||
buttonIconColor: context.color.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
|
|||
context: context,
|
||||
backgroundColor: Colors.black,
|
||||
builder: (BuildContext context) {
|
||||
return const Emojis();
|
||||
return const EmojiPickerBottom();
|
||||
},
|
||||
) as Layer?;
|
||||
if (layer == null) return;
|
||||
|
|
|
|||
|
|
@ -11,11 +11,10 @@ import 'package:twonly/src/database/twonly.db.dart';
|
|||
import 'package:twonly/src/model/memory_item.model.dart';
|
||||
import 'package:twonly/src/services/api/messages.dart';
|
||||
import 'package:twonly/src/services/notifications/background.notifications.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/camera/camera_send_to_view.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages_components/chat_date_chip.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages_components/chat_group_action.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages_components/chat_list_entry.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages_components/message_input.dart';
|
||||
import 'package:twonly/src/views/chats/chat_messages_components/response_container.dart';
|
||||
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
||||
import 'package:twonly/src/views/components/flame.dart';
|
||||
|
|
@ -70,10 +69,8 @@ class ChatMessagesView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _ChatMessagesViewState extends State<ChatMessagesView> {
|
||||
TextEditingController newMessageController = TextEditingController();
|
||||
HashSet<int> alreadyReportedOpened = HashSet<int>();
|
||||
late Group group;
|
||||
String currentInputText = '';
|
||||
late StreamSubscription<Group?> userSub;
|
||||
late StreamSubscription<List<Message>> messageSub;
|
||||
StreamSubscription<List<GroupHistory>>? groupActionsSub;
|
||||
|
|
@ -267,21 +264,6 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
setState(() {});
|
||||
}
|
||||
|
||||
Future<void> _sendMessage() async {
|
||||
if (newMessageController.text == '') return;
|
||||
|
||||
await insertAndSendTextMessage(
|
||||
group.groupId,
|
||||
newMessageController.text,
|
||||
quotesMessage?.messageId,
|
||||
);
|
||||
|
||||
newMessageController.clear();
|
||||
currentInputText = '';
|
||||
quotesMessage = null;
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
Future<void> scrollToMessage(String messageId) async {
|
||||
final index = messages.indexWhere(
|
||||
(x) => x.isMessage && x.message!.messageId == messageId,
|
||||
|
|
@ -464,100 +446,15 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
|||
),
|
||||
),
|
||||
if (!group.leftGroup)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 30,
|
||||
left: 20,
|
||||
right: 20,
|
||||
top: 10,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
color: Colors.grey,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 10,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const FaIcon(FontAwesomeIcons.faceSmile),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: newMessageController,
|
||||
focusNode: textFieldFocus,
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: 4,
|
||||
minLines: 1,
|
||||
onChanged: (value) {
|
||||
currentInputText = value;
|
||||
setState(() {});
|
||||
},
|
||||
onSubmitted: (_) {
|
||||
_sendMessage();
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
hintText: context.lang.chatListDetailInput,
|
||||
// contentPadding: const EdgeInsets.symmetric(
|
||||
// horizontal: 20,
|
||||
// vertical: 10,
|
||||
// ),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.primary,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
borderSide: const BorderSide(
|
||||
color: Colors.grey,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (currentInputText != '')
|
||||
IconButton(
|
||||
padding: const EdgeInsets.all(15),
|
||||
icon: const FaIcon(
|
||||
FontAwesomeIcons.solidPaperPlane,
|
||||
),
|
||||
onPressed: _sendMessage,
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
icon: const FaIcon(FontAwesomeIcons.camera),
|
||||
padding: const EdgeInsets.all(15),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CameraSendToView(widget.group);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
MessageInput(
|
||||
group: group,
|
||||
quotesMessage: quotesMessage,
|
||||
textFieldFocus: textFieldFocus,
|
||||
onMessageSend: () {
|
||||
setState(() {
|
||||
quotesMessage = null;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class MessageContextMenu extends StatelessWidget {
|
|||
context: context,
|
||||
backgroundColor: Colors.black,
|
||||
builder: (BuildContext context) {
|
||||
return const Emojis();
|
||||
return const EmojiPickerBottom();
|
||||
},
|
||||
) as EmojiLayerData?;
|
||||
if (layer == null) return;
|
||||
|
|
|
|||
216
lib/src/views/chats/chat_messages_components/message_input.dart
Normal file
216
lib/src/views/chats/chat_messages_components/message_input.dart
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
import 'dart:io';
|
||||
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:twonly/src/database/twonly.db.dart';
|
||||
import 'package:twonly/src/services/api/messages.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/camera/camera_send_to_view.dart';
|
||||
|
||||
class MessageInput extends StatefulWidget {
|
||||
const MessageInput({
|
||||
required this.group,
|
||||
required this.quotesMessage,
|
||||
required this.textFieldFocus,
|
||||
required this.onMessageSend,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final Group group;
|
||||
final FocusNode textFieldFocus;
|
||||
final Message? quotesMessage;
|
||||
final VoidCallback onMessageSend;
|
||||
|
||||
@override
|
||||
State<MessageInput> createState() => _MessageInputState();
|
||||
}
|
||||
|
||||
class _MessageInputState extends State<MessageInput> {
|
||||
late final TextEditingController _textFieldController;
|
||||
final bool isApple = Platform.isIOS;
|
||||
bool _emojiShowing = false;
|
||||
|
||||
Future<void> _sendMessage() async {
|
||||
if (_textFieldController.text == '') return;
|
||||
|
||||
await insertAndSendTextMessage(
|
||||
widget.group.groupId,
|
||||
_textFieldController.text,
|
||||
widget.quotesMessage?.messageId,
|
||||
);
|
||||
|
||||
_textFieldController.clear();
|
||||
_emojiShowing = false;
|
||||
widget.onMessageSend();
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_textFieldController = TextEditingController();
|
||||
widget.textFieldFocus.addListener(_handleTextFocusChange);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.textFieldFocus.removeListener(_handleTextFocusChange);
|
||||
widget.textFieldFocus.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _handleTextFocusChange() {
|
||||
if (widget.textFieldFocus.hasFocus) {
|
||||
setState(() {
|
||||
_emojiShowing = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 10,
|
||||
left: 10,
|
||||
top: 10,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 3,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: context.color.surfaceContainer,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_emojiShowing = !_emojiShowing;
|
||||
if (_emojiShowing) {
|
||||
widget.textFieldFocus.unfocus();
|
||||
} else {
|
||||
widget.textFieldFocus.requestFocus();
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 8,
|
||||
bottom: 8,
|
||||
left: 12,
|
||||
right: 8,
|
||||
),
|
||||
child: FaIcon(
|
||||
size: 20,
|
||||
_emojiShowing
|
||||
? FontAwesomeIcons.keyboard
|
||||
: FontAwesomeIcons.faceSmile,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _textFieldController,
|
||||
focusNode: widget.textFieldFocus,
|
||||
keyboardType: TextInputType.multiline,
|
||||
maxLines: 4,
|
||||
minLines: 1,
|
||||
onChanged: (value) {
|
||||
setState(() {});
|
||||
},
|
||||
onSubmitted: (_) {
|
||||
_sendMessage();
|
||||
},
|
||||
style: const TextStyle(fontSize: 17),
|
||||
decoration: InputDecoration(
|
||||
hintText: context.lang.chatListDetailInput,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_textFieldController.text != '')
|
||||
IconButton(
|
||||
padding: const EdgeInsets.all(15),
|
||||
icon: FaIcon(
|
||||
color: context.color.primary,
|
||||
FontAwesomeIcons.solidPaperPlane,
|
||||
),
|
||||
onPressed: _sendMessage,
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
icon: const FaIcon(FontAwesomeIcons.camera),
|
||||
padding: const EdgeInsets.all(15),
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return CameraSendToView(widget.group);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Offstage(
|
||||
offstage: !_emojiShowing,
|
||||
child: EmojiPicker(
|
||||
textEditingController: _textFieldController,
|
||||
onEmojiSelected: (category, emoji) {
|
||||
setState(() {});
|
||||
},
|
||||
onBackspacePressed: () {
|
||||
setState(() {});
|
||||
},
|
||||
config: Config(
|
||||
height: 300,
|
||||
locale: Localizations.localeOf(context),
|
||||
viewOrderConfig: const ViewOrderConfig(
|
||||
top: EmojiPickerItem.searchBar,
|
||||
// middle: EmojiPickerItem.emojiView,
|
||||
bottom: EmojiPickerItem.categoryBar,
|
||||
),
|
||||
emojiTextStyle:
|
||||
TextStyle(fontSize: 24 * (Platform.isIOS ? 1.2 : 1)),
|
||||
emojiViewConfig: EmojiViewConfig(
|
||||
backgroundColor: context.color.surfaceContainer,
|
||||
),
|
||||
searchViewConfig: SearchViewConfig(
|
||||
backgroundColor: context.color.surfaceContainer,
|
||||
buttonIconColor: Colors.white,
|
||||
),
|
||||
categoryViewConfig: CategoryViewConfig(
|
||||
backgroundColor: context.color.surfaceContainer,
|
||||
dividerColor: Colors.white,
|
||||
indicatorColor: context.color.primary,
|
||||
iconColorSelected: context.color.primary,
|
||||
iconColor: context.color.secondary,
|
||||
),
|
||||
bottomActionBarConfig: BottomActionBarConfig(
|
||||
backgroundColor: context.color.surfaceContainer,
|
||||
buttonColor: context.color.surfaceContainer,
|
||||
buttonIconColor: context.color.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue