From c7045b79afefd6c3444551831ffce05930f03b30 Mon Sep 17 00:00:00 2001 From: sspanak Date: Wed, 23 Aug 2023 18:28:57 +0300 Subject: [PATCH] sending messages with OK in Facebook Messenger is now possible --- res/values-bg/strings.xml | 2 + res/values-fr/strings.xml | 2 + res/values-ru/strings.xml | 2 + res/values-uk/strings.xml | 2 + res/values/strings.xml | 2 + res/xml/prefs_screen_setup.xml | 6 ++ .../github/sspanak/tt9/ime/KeyPadHandler.java | 6 +- .../sspanak/tt9/ime/helpers/AppHacks.java | 88 ++++++++++++++++++- .../tt9/preferences/SettingsStore.java | 15 +++- 9 files changed, 118 insertions(+), 7 deletions(-) diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index 190d34c5..2cc03ac5 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -28,6 +28,8 @@ Съвместимост Облик Бутони за бърз достъп + Изпращай съобщения с ОК в Messenger + Позволява изпращането на съобщения с бутона ОК във Facebook Messenger и Messenger Lite. Бутони на екрана Назад Зелена слушалка diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index ad81fd05..29d37e5f 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -28,6 +28,8 @@ Apparance Echec du chargement. Mot inadmissible «%1$s» à la ligne %2$d de langue «%3$s». Le dictionaire est supprimé avec succès. + Envoyer des messages avec OK dans Messenger + La touche OK servira pour envoyer des messages dans Facebook Messenger et Messenger Lite. Boutons à l\'écran Chargement du dictionnaire Chargement est annulé. diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index db8b307d..250ebb43 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -42,6 +42,8 @@ Авто заглавные буквы Автоматически начинать предложение с заглавной буквы. Символ при двойном нажатии клавиши 0 + Отправка сообщения с «ОК» в Messenger + Позволяет отправлять сообщения с помощью кнопки «ОК» в Facebook Messenger и Messenger Lite. Кнопки на экране Не удалось загрузить словарь. Проблема в слове «%1$s» в строке %2$d для языка «%3$s». Отсутствует словарь для языка «%1$s». Вы можете загрузить его в Настройках. diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index d9184979..3fd4c2f1 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -41,6 +41,8 @@ Авто заголовні букви Автоматично починати речення з заголовної букви. Символ при подвійному натисканні клавіші 0 + Надсилати повідомлення з «ОК» до Messenger + Дозволяє надсилати повідомлення за допомогою клавіші «ОК» у Facebook Messenger і Messenger Lite. Кнопки на екрані Назад Виклик diff --git a/res/values/strings.xml b/res/values/strings.xml index baa4a497..8bd20fe2 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -47,6 +47,8 @@ Detailed Debug Logs System Logs Character for Double 0-key Press + Send messages with OK in Messenger + Allows sending messages with the OK key in Facebook Messenger and Messenger Lite. Show On-Screen Keys Show On-Screen Numpad (BETA) diff --git a/res/xml/prefs_screen_setup.xml b/res/xml/prefs_screen_setup.xml index eb4a222b..1e4a7ab2 100644 --- a/res/xml/prefs_screen_setup.xml +++ b/res/xml/prefs_screen_setup.xml @@ -23,5 +23,11 @@ app:title="@string/pref_alternative_suggestion_scrolling" app:summary="@string/pref_alternative_suggestion_scrolling_summary"/> + + diff --git a/src/io/github/sspanak/tt9/ime/KeyPadHandler.java b/src/io/github/sspanak/tt9/ime/KeyPadHandler.java index 44e99e57..781c4759 100644 --- a/src/io/github/sspanak/tt9/ime/KeyPadHandler.java +++ b/src/io/github/sspanak/tt9/ime/KeyPadHandler.java @@ -6,6 +6,7 @@ import android.view.View; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import io.github.sspanak.tt9.Logger; import io.github.sspanak.tt9.ime.helpers.Key; import io.github.sspanak.tt9.preferences.SettingsStore; @@ -74,7 +75,10 @@ abstract class KeyPadHandler extends InputMethodService { */ @Override public void onStartInput(EditorInfo inputField, boolean restarting) { - // Logger.d("T9.onStartInput", "inputType: " + inputField.inputType + " fieldId: " + inputField.fieldId + " fieldName: " + inputField.fieldName + " packageName: " + inputField.packageName + " privateImeOptions: " + inputField.privateImeOptions + " imeOptions: " + inputField.imeOptions + " extras: " + inputField.extras); + Logger.d( + "KeyPadHandler", + "===> Start Up; packageName: " + inputField.packageName + " inputType: " + inputField.inputType + " fieldId: " + inputField.fieldId + " fieldName: " + inputField.fieldName + " privateImeOptions: " + inputField.privateImeOptions + " imeOptions: " + inputField.imeOptions + " extras: " + inputField.extras + ); currentInputConnection = getCurrentInputConnection(); onStart(inputField); } diff --git a/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java b/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java index 4e0c2ab5..1020735d 100644 --- a/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java +++ b/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java @@ -31,7 +31,7 @@ public class AppHacks { * weird side effects occur. Nevertheless, all other text fields in the app are fine, so we detect only these two particular ones. */ private boolean isKindleInvertedTextField() { - return editorInfo != null && editorInfo.inputType == 1 && editorInfo.packageName.contains("com.amazon.kindle"); + return isAppField("com.amazon.kindle", EditorInfo.TYPE_CLASS_TEXT); } @@ -42,10 +42,52 @@ public class AppHacks { * and are ignored by TT9 by default. In order not to ignore Termux, we need this. */ public boolean isTermux() { - return editorInfo != null && editorInfo.inputType == 0 && editorInfo.fieldId > 0 && editorInfo.packageName.contains("com.termux"); + return isAppField("com.termux", EditorInfo.TYPE_NULL) && editorInfo.fieldId > 0; } + /** + * isMessenger + * Facebook Messenger has flaky support for sending messages. To fix that, we detect the chat input field and send the appropriate + * key codes to it. See "onFbMessengerEnter()" for info how the hack works. + */ + private boolean isMessenger() { + return isAppField( + "com.facebook.orca", + EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES + ); + } + + + /** + * isMessengerLite + * Facebook Messenger Lite does not support sending messages with OK/ENTER. To enable that, we + * detect the chat field and apply the proper series of commands to it. See "onFbMessengerEnter()" for info how the hack works. + */ + private boolean isMessengerLite() { + return isAppField( + "com.facebook.mlite", + EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES | EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT + ); + } + + + /** + * isAppField + * Detects a particular input field of a particular application. + */ + private boolean isAppField(String appPackageName, int fieldSpec) { + return + editorInfo != null + && ((editorInfo.inputType & fieldSpec) == fieldSpec) + && editorInfo.packageName.equals(appPackageName); + } + + + /** + * setComposingTextWithHighlightedStem + * A compatibility function for text fields that do not support SpannableString. Effectively disables highlighting. + */ public boolean setComposingTextWithHighlightedStem(@NonNull String word) { if (isKindleInvertedTextField()) { textField.setComposingText(word); @@ -55,6 +97,7 @@ public class AppHacks { return false; } + /** * onBackspace * Performs extra Backspace operations and returns "false", or completely replaces Backspace and returns "true". When "true" is @@ -82,6 +125,8 @@ public class AppHacks { if (isTermux()) { sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER); return true; + } else if (isMessenger() || isMessengerLite()) { + return onEnterFbMessenger(); } return onEnterDefault(); @@ -121,6 +166,45 @@ public class AppHacks { } + /** + * onEnterFbMessenger + * Once we have detected the chat message field we apply the appropriate key combo to send the message. + */ + private boolean onEnterFbMessenger() { + if (textField == null) { + return false; + } + + // in case the setting is disabled, just type a new line as one would expect + if (!settings.getFbMessengerHack()) { + inputConnection.commitText("\n", 1); + return true; + } + + // do not send any commands if the user has not typed anything or the field is invalid + if (!textField.isThereText()) { + return false; + } + + if (isMessenger()) { + // Messenger responds only to ENTER, but not DPAD_CENTER, so we make sure to send the correct code, + // no matter how the hardware key is implemented. + sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER); + } else { + // Messenger Lite responds to no key codes, so we trick it by going right to the Send button, pressing it, + // then going back to the chat field. + sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT); + sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT); + sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_CENTER); + sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT); + sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT); + } + + + return true; + } + + private void sendDownUpKeyEvents(int keyCode) { if (inputConnection != null) { inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode)); diff --git a/src/io/github/sspanak/tt9/preferences/SettingsStore.java b/src/io/github/sspanak/tt9/preferences/SettingsStore.java index 561b800a..a681202d 100644 --- a/src/io/github/sspanak/tt9/preferences/SettingsStore.java +++ b/src/io/github/sspanak/tt9/preferences/SettingsStore.java @@ -265,10 +265,6 @@ public class SettingsStore { /************* internal settings *************/ - public int getSuggestionScrollingDelay() { - return prefs.getBoolean("pref_alternative_suggestion_scrolling", false) ? 200 : 0; - } - public int getDictionaryImportProgressUpdateInterval() { return 250; /* ms */ } public int getDictionaryImportWordChunkSize() { return 1000; /* words */ } @@ -284,4 +280,15 @@ public class SettingsStore { public int getWordFrequencyMax() { return 25500; } public int getWordFrequencyNormalizationDivider() { return 100; } // normalized frequency = getWordFrequencyMax() / getWordFrequencyNormalizationDivider() + + + /************* hack settings *************/ + + public int getSuggestionScrollingDelay() { + return prefs.getBoolean("pref_alternative_suggestion_scrolling", false) ? 200 : 0; + } + + public boolean getFbMessengerHack() { + return prefs.getBoolean("pref_hack_fb_messenger", false); + } }