feat: implement an emoji keyboard
- add button to show emoji keyboard - change database directory for debug builds Signed-off-by: TheOneWithTheBraid <the-one@with-the-braid.cf>
This commit is contained in:
parent
0f448af5dc
commit
b1d1744df8
9 changed files with 117 additions and 11 deletions
|
|
@ -8,6 +8,7 @@ import 'package:flutter/services.dart';
|
|||
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:desktop_drop/desktop_drop.dart';
|
||||
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
|
||||
import 'package:file_picker_cross/file_picker_cross.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
|
|
@ -125,6 +126,8 @@ class ChatController extends State<Chat> {
|
|||
|
||||
bool showEmojiPicker = false;
|
||||
|
||||
EmojiPickerType emojiPickerType = EmojiPickerType.keyboard;
|
||||
|
||||
void startCallAction() async {
|
||||
final url =
|
||||
'${AppConfig.jitsiInstance}${Uri.encodeComponent(Matrix.of(context).client.generateUniqueTransactionId())}';
|
||||
|
|
@ -178,6 +181,8 @@ class ChatController extends State<Chat> {
|
|||
@override
|
||||
void initState() {
|
||||
scrollController.addListener(_updateScrollController);
|
||||
|
||||
inputFocus.addListener(_inputFocusListener);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
|
@ -239,6 +244,7 @@ class ChatController extends State<Chat> {
|
|||
void dispose() {
|
||||
timeline?.cancelSubscriptions();
|
||||
timeline = null;
|
||||
inputFocus.removeListener(_inputFocusListener);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -426,6 +432,20 @@ class ChatController extends State<Chat> {
|
|||
});
|
||||
}
|
||||
|
||||
void emojiPickerAction() {
|
||||
emojiPickerType = EmojiPickerType.keyboard;
|
||||
setState(() => showEmojiPicker = !showEmojiPicker);
|
||||
_inputFocusListener();
|
||||
}
|
||||
|
||||
void _inputFocusListener() {
|
||||
if (showEmojiPicker) {
|
||||
inputFocus.unfocus();
|
||||
} else {
|
||||
inputFocus.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
void sendLocationAction() async {
|
||||
await showDialog(
|
||||
context: context,
|
||||
|
|
@ -668,7 +688,18 @@ class ChatController extends State<Chat> {
|
|||
|
||||
void scrollDown() => scrollController.jumpTo(0);
|
||||
|
||||
void onEmojiSelected(_, emoji) {
|
||||
void onEmojiSelected(_, Emoji? emoji) {
|
||||
switch (emojiPickerType) {
|
||||
case EmojiPickerType.reaction:
|
||||
senEmojiReaction(emoji);
|
||||
break;
|
||||
case EmojiPickerType.keyboard:
|
||||
typeEmoji(emoji);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void senEmojiReaction(Emoji? emoji) {
|
||||
setState(() => showEmojiPicker = false);
|
||||
if (emoji == null) return;
|
||||
// make sure we don't send the same emoji twice
|
||||
|
|
@ -677,12 +708,41 @@ class ChatController extends State<Chat> {
|
|||
return sendEmojiAction(emoji.emoji);
|
||||
}
|
||||
|
||||
void typeEmoji(Emoji? emoji) {
|
||||
if (emoji == null) return;
|
||||
final text = sendController.text;
|
||||
final selection = sendController.selection;
|
||||
final newText = sendController.text.isEmpty
|
||||
? emoji.emoji
|
||||
: text.replaceRange(selection.start, selection.end, emoji.emoji);
|
||||
sendController.value = TextEditingValue(
|
||||
text: newText,
|
||||
selection: TextSelection.collapsed(
|
||||
// don't forget an UTF-8 combined emoji might have a length > 1
|
||||
offset: selection.baseOffset + emoji.emoji.length,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
late Iterable<Event> _allReactionEvents;
|
||||
|
||||
void cancelEmojiPicker() => setState(() => showEmojiPicker = false);
|
||||
void emojiPickerBackspace() {
|
||||
switch (emojiPickerType) {
|
||||
case EmojiPickerType.reaction:
|
||||
setState(() => showEmojiPicker = false);
|
||||
break;
|
||||
case EmojiPickerType.keyboard:
|
||||
sendController
|
||||
..text = sendController.text.characters.skipLast(1).toString()
|
||||
..selection = TextSelection.fromPosition(
|
||||
TextPosition(offset: sendController.text.length));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void pickEmojiAction(Iterable<Event> allReactionEvents) async {
|
||||
void pickEmojiReactionAction(Iterable<Event> allReactionEvents) async {
|
||||
_allReactionEvents = allReactionEvents;
|
||||
emojiPickerType = EmojiPickerType.reaction;
|
||||
setState(() => showEmojiPicker = true);
|
||||
}
|
||||
|
||||
|
|
@ -902,3 +962,5 @@ class ChatController extends State<Chat> {
|
|||
@override
|
||||
Widget build(BuildContext context) => ChatView(this);
|
||||
}
|
||||
|
||||
enum EmojiPickerType { reaction, keyboard }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue