import 'package:cometchat_chat_uikit/cometchat_chat_uikit.dart';
class ShortcutFormatter extends CometChatTextFormatter {
@override
void init() {
trackingCharacter ??= "!";
}
bool isShortcutTracking = false;
void prepareShortcuts(TextEditingController textEditingController) {
CometChat.callExtension('message-shortcuts', 'GET', '/v1/fetch', null,
onSuccess: (map) {
if (map.isNotEmpty) {
Map<String, dynamic> data = map["data"];
if (data.isNotEmpty) {
Map<String, dynamic> shortcuts = data["shortcuts"];
if (shortcuts.isNotEmpty) {
parseData(shortcuts: shortcuts, textEditingController: textEditingController);
}
}
}
},
onError: (error) {},
);
}
void parseData({Map<String, dynamic>? shortcuts, required TextEditingController textEditingController}) async {
if (shortcuts == null || shortcuts.isEmpty) {
suggestionListEventSink?.add([]);
if (onSearch != null) onSearch!(null);
CometChatUIEvents.hidePanel(composerId, CustomUIPosition.composerPreview);
} else {
CometChatUIEvents.hidePanel(composerId, CustomUIPosition.composerPreview);
if (suggestionListEventSink != null && shortcuts.isNotEmpty) {
List<SuggestionListItem> list = [];
shortcuts.forEach((key, value) => list.add(SuggestionListItem(
id: key,
title: "$key → $value",
onTap: () {
int cursorPos = textEditingController.selection.base.offset;
String left = textEditingController.text.substring(0, cursorPos - 1);
String right = textEditingController.text.substring(cursorPos);
textEditingController.text = "$left$value $right";
updatePreviousText(textEditingController.text);
textEditingController.selection = TextSelection(
baseOffset: cursorPos - 1 + "$value".length + 1,
extentOffset: cursorPos - 1 + "$value".length + 1,
);
resetMatchTracker();
isShortcutTracking = false;
CometChatUIEvents.hidePanel(composerId, CustomUIPosition.composerPreview);
},
)));
suggestionListEventSink?.add(list);
}
}
}
void updatePreviousText(String text) {
previousTextEventSink?.add(text);
}
void resetMatchTracker() {
suggestionListEventSink?.add([]);
if (onSearch != null) onSearch!(null);
}
@override
void onChange(TextEditingController textEditingController, String previousText) {
var cursorPosition = textEditingController.selection.base.offset;
if (textEditingController.text.isEmpty) {
resetMatchTracker();
return;
}
// Handle shortcut tracking logic
String previousCharacter = cursorPosition == 0 ? "" : textEditingController.text[cursorPosition - 1];
bool isSpace = cursorPosition == 1 || (textEditingController.text.length > 1 && cursorPosition > 1 &&
(textEditingController.text[cursorPosition - 2] == " " || textEditingController.text[cursorPosition - 2] == "\n"));
if (isShortcutTracking) {
isShortcutTracking = false;
if (onSearch != null) onSearch!(null);
CometChatUIEvents.hidePanel(composerId, CustomUIPosition.composerPreview);
} else if (previousCharacter == trackingCharacter && isSpace) {
isShortcutTracking = true;
if (onSearch != null) onSearch!(trackingCharacter);
CometChatUIEvents.showPanel(composerId, CustomUIPosition.composerPreview,
(context) => getLoadingIndicator(context, cometChatTheme));
prepareShortcuts(textEditingController);
}
}
@override
TextStyle getMessageInputTextStyle(CometChatTheme theme) {
throw UnimplementedError();
}
@override
void handlePreMessageSend(BuildContext context, BaseMessage baseMessage) {}
@override
void onScrollToBottom(TextEditingController textEditingController) {}
}