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:
TheOneWithTheBraid 2022-02-14 13:49:46 +01:00
commit b1d1744df8
9 changed files with 117 additions and 11 deletions

View file

@ -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 }