diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index fda8ecaf..3641eb0b 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -29,7 +29,7 @@ Облик Бутони за бърз достъп Изпращай съобщения с ОК в Messenger - Позволява изпращането на съобщения с бутона ОК във Facebook Messenger и Messenger Lite. + Позволява изпращането на съобщения с бутона ОК във Facebook Messenger. Бутони на екрана Назад Зелена слушалка diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index c7304ffb..fced2a58 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -29,7 +29,7 @@ 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. + La touche OK servira pour envoyer des messages dans Facebook Messenger. Boutons à l\'écran Chargement du dictionnaire Chargement est annulé. diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 0ed81dfc..9a27aeab 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -43,7 +43,7 @@ Автоматически начинать предложение с заглавной буквы. Символ при двойном нажатии клавиши 0 Отправка сообщения с «ОК» в Messenger - Позволяет отправлять сообщения с помощью кнопки «ОК» в Facebook Messenger и Messenger Lite. + Позволяет отправлять сообщения с помощью кнопки «ОК» в Facebook Messenger. Кнопки на экране Не удалось загрузить словарь. Проблема в слове «%1$s» в строке %2$d для языка «%3$s». Отсутствует словарь для языка «%1$s». Вы можете загрузить его в Настройках. diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 4026acd6..c9cc2dcc 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -42,7 +42,7 @@ Автоматично починати речення з заголовної букви. Символ при подвійному натисканні клавіші 0 Надсилати повідомлення з «ОК» до Messenger - Дозволяє надсилати повідомлення за допомогою клавіші «ОК» у Facebook Messenger і Messenger Lite. + Дозволяє надсилати повідомлення за допомогою клавіші «ОК» у Facebook Messenger. Кнопки на екрані Назад Виклик diff --git a/res/values/strings.xml b/res/values/strings.xml index 919655c2..aa0be93d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -48,7 +48,7 @@ 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. + Allows sending messages with the OK key in Facebook Messenger. Show On-Screen Keys Show On-Screen Numpad (BETA) diff --git a/src/io/github/sspanak/tt9/ime/KeyPadHandler.java b/src/io/github/sspanak/tt9/ime/KeyPadHandler.java index abfa4525..528be1d9 100644 --- a/src/io/github/sspanak/tt9/ime/KeyPadHandler.java +++ b/src/io/github/sspanak/tt9/ime/KeyPadHandler.java @@ -12,8 +12,6 @@ import io.github.sspanak.tt9.preferences.SettingsStore; abstract class KeyPadHandler extends InputMethodService { - protected InputConnection currentInputConnection = null; - protected SettingsStore settings; // temporal key handling @@ -44,7 +42,7 @@ abstract class KeyPadHandler extends InputMethodService { @Override public boolean onEvaluateInputViewShown() { super.onEvaluateInputViewShown(); - onRestart(getCurrentInputEditorInfo()); + setInputField(getCurrentInputConnection(), getCurrentInputEditorInfo()); return shouldBeVisible(); } @@ -79,15 +77,13 @@ abstract class KeyPadHandler extends InputMethodService { "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); + onStart(getCurrentInputConnection(), inputField); } @Override public void onStartInputView(EditorInfo inputField, boolean restarting) { - currentInputConnection = getCurrentInputConnection(); - onRestart(inputField); + onStart(getCurrentInputConnection(), inputField); } @@ -294,10 +290,10 @@ abstract class KeyPadHandler extends InputMethodService { // helpers abstract protected void onInit(); - abstract protected void onStart(EditorInfo inputField); - abstract protected void onRestart(EditorInfo inputField); + abstract protected void onStart(InputConnection inputConnection, EditorInfo inputField); abstract protected void onFinishTyping(); abstract protected void onStop(); + abstract protected void setInputField(InputConnection inputConnection, EditorInfo inputField); // UI abstract protected View createSoftKeyView(); diff --git a/src/io/github/sspanak/tt9/ime/TraditionalT9.java b/src/io/github/sspanak/tt9/ime/TraditionalT9.java index 6f51e195..116e5009 100644 --- a/src/io/github/sspanak/tt9/ime/TraditionalT9.java +++ b/src/io/github/sspanak/tt9/ime/TraditionalT9.java @@ -8,6 +8,7 @@ import android.os.Looper; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; import androidx.annotation.NonNull; @@ -34,18 +35,16 @@ import io.github.sspanak.tt9.ui.tray.StatusBar; import io.github.sspanak.tt9.ui.tray.SuggestionsBar; public class TraditionalT9 extends KeyPadHandler { + private InputConnection currentInputConnection = null; // internal settings/data @NonNull private AppHacks appHacks = new AppHacks(null,null, null, null); @NonNull private TextField textField = new TextField(null, null); @NonNull private InputType inputType = new InputType(null, null); @NonNull private final Handler autoAcceptHandler = new Handler(Looper.getMainLooper()); - @Deprecated // migrate to "ModePassthrough" when "isActive" == "false" - private boolean isActive = false; - // input mode private ArrayList allowedInputModes = new ArrayList<>(); - private InputMode mInputMode; + @NonNull private InputMode mInputMode = InputMode.getInstance(null, null, null, InputMode.MODE_PASSTHROUGH); // language protected ArrayList mEnabledLanguages; @@ -66,23 +65,23 @@ public class TraditionalT9 extends KeyPadHandler { } public boolean isInputModeNumeric() { - return mInputMode != null && mInputMode.is123(); + return mInputMode.is123(); } public boolean isNumericModeStrict() { - return mInputMode != null && mInputMode.is123() && inputType.isNumeric() && !inputType.isPhoneNumber(); + return mInputMode.is123() && inputType.isNumeric() && !inputType.isPhoneNumber(); } public boolean isNumericModeSigned() { - return mInputMode != null && mInputMode.is123() && inputType.isSignedNumber(); + return mInputMode.is123() && inputType.isSignedNumber(); } public boolean isInputModePhone() { - return mInputMode != null && mInputMode.is123() && inputType.isPhoneNumber(); + return mInputMode.is123() && inputType.isPhoneNumber(); } public int getTextCase() { - return mInputMode != null ? mInputMode.getTextCase() : InputMode.CASE_UNDEFINED; + return mInputMode.getTextCase(); } @@ -103,14 +102,18 @@ public class TraditionalT9 extends KeyPadHandler { /** - * determineInputMode - * Restore the last input mode or choose a more appropriate one. + * getInputMode + * Load the last input mode or choose a more appropriate one. * Some input fields support only numbers or are not suited for predictions (e.g. password fields) */ - private void determineInputMode() { + private InputMode getInputMode() { + if (!inputType.isValid() || (inputType.isLimited() && !appHacks.isTermux())) { + return InputMode.getInstance(settings, mLanguage, inputType, InputMode.MODE_PASSTHROUGH); + } + allowedInputModes = textField.determineInputModes(inputType); int validModeId = InputModeValidator.validateMode(settings.getInputMode(), allowedInputModes); - mInputMode = InputMode.getInstance(settings, mLanguage, inputType, validModeId); + return InputMode.getInstance(settings, mLanguage, inputType, validModeId); } @@ -123,7 +126,7 @@ public class TraditionalT9 extends KeyPadHandler { private void determineTextCase() { mInputMode.defaultTextCase(); mInputMode.setTextFieldCase(textField.determineTextCase(inputType)); - mInputMode.determineNextWordTextCase(textField.isThereText(), textField.getTextBeforeCursor()); + mInputMode.determineNextWordTextCase(textField.getTextBeforeCursor()); InputModeValidator.validateTextCase(mInputMode, settings.getTextCase()); } @@ -144,6 +147,7 @@ public class TraditionalT9 extends KeyPadHandler { protected void onInit() { self = this; + Logger.enableDebugLevel(settings.getDebugLogsEnabled()); DictionaryDb.init(this); DictionaryDb.normalizeWordFrequencies(settings); @@ -157,6 +161,14 @@ public class TraditionalT9 extends KeyPadHandler { } + protected void setInputField(InputConnection connection, EditorInfo field) { + currentInputConnection = connection; + inputType = new InputType(currentInputConnection, field); + textField = new TextField(currentInputConnection, field); + appHacks = new AppHacks(settings, connection, field, textField); + } + + private void initTyping() { // in case we are back from Settings screen, update the language list mEnabledLanguages = settings.getEnabledLanguageIds(); @@ -165,7 +177,7 @@ public class TraditionalT9 extends KeyPadHandler { resetKeyRepeat(); setSuggestions(null); - determineInputMode(); + mInputMode = getInputMode(); determineTextCase(); } @@ -188,41 +200,33 @@ public class TraditionalT9 extends KeyPadHandler { if (mainView.createView()) { initTray(); } - statusBar.setText(mInputMode != null ? mInputMode.toString() : ""); + statusBar.setText(mInputMode.toString()); setDarkTheme(); mainView.render(); } - protected void onStart(EditorInfo input) { - inputType = new InputType(currentInputConnection, input); - textField = new TextField(currentInputConnection, input); - appHacks = new AppHacks(settings, currentInputConnection, input, textField); + protected void onStart(InputConnection connection, EditorInfo field) { + Logger.enableDebugLevel(settings.getDebugLogsEnabled()); - if (!inputType.isValid() || (inputType.isLimited() && !appHacks.isTermux())) { + setInputField(connection, field); + initTyping(); + + if (mInputMode.isPassthrough()) { // When the input is invalid or simple, let Android handle it. onStop(); + updateInputViewShown(); return; } - initTyping(); initUi(); - Logger.enableDebugLevel(settings.getDebugLogsEnabled()); - - isActive = true; - } - - - protected void onRestart(EditorInfo inputField) { - if (!isActive) { - onStart(inputField); - } + updateInputViewShown(); } protected void onFinishTyping() { cancelAutoAccept(); - isActive = false; + mInputMode = InputMode.getInstance(null, null, null, InputMode.MODE_PASSTHROUGH); } @@ -286,7 +290,7 @@ public class TraditionalT9 extends KeyPadHandler { // Auto-adjust the text case before each word, if the InputMode supports it. if (getComposingText().isEmpty()) { - mInputMode.determineNextWordTextCase(textField.isThereText(), textField.getTextBeforeCursor()); + mInputMode.determineNextWordTextCase(textField.getTextBeforeCursor()); } if (!mInputMode.onNumber(key, hold, repeat)) { @@ -613,7 +617,7 @@ public class TraditionalT9 extends KeyPadHandler { commitCurrentSuggestion(false); mInputMode.onAcceptSuggestion(lastComposingText, true); autoCorrectSpace(lastComposingText, false, -1); - mInputMode.determineNextWordTextCase(textField.isThereText(), textField.getTextBeforeCursor()); + mInputMode.determineNextWordTextCase(textField.getTextBeforeCursor()); } // display the word suggestions @@ -709,7 +713,7 @@ public class TraditionalT9 extends KeyPadHandler { int nextModeIndex = (allowedInputModes.indexOf(mInputMode.getId()) + 1) % allowedInputModes.size(); mInputMode = InputMode.getInstance(settings, mLanguage, inputType, allowedInputModes.get(nextModeIndex)); mInputMode.setTextFieldCase(textField.determineTextCase(inputType)); - mInputMode.determineNextWordTextCase(textField.isThereText(), textField.getTextBeforeCursor()); + mInputMode.determineNextWordTextCase(textField.getTextBeforeCursor()); resetKeyRepeat(); } @@ -779,12 +783,12 @@ public class TraditionalT9 extends KeyPadHandler { @Override protected boolean shouldBeVisible() { - return !mInputMode.isPassthrough() && isActive; + return !getInputMode().isPassthrough(); } @Override protected boolean shouldBeOff() { - return currentInputConnection == null || !isActive || mInputMode.isPassthrough(); + return currentInputConnection == null || mInputMode.isPassthrough(); } } diff --git a/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java b/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java index 3de1f582..bcbf8d24 100644 --- a/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java +++ b/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java @@ -59,19 +59,6 @@ public class AppHacks { } - /** - * 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. @@ -125,7 +112,7 @@ public class AppHacks { if (isTermux()) { sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER); return true; - } else if (isMessenger() || isMessengerLite()) { + } else if (isMessenger()) { return onEnterFbMessenger(); } @@ -196,17 +183,8 @@ public class AppHacks { // 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; } diff --git a/src/io/github/sspanak/tt9/ime/modes/InputMode.java b/src/io/github/sspanak/tt9/ime/modes/InputMode.java index aaf5b3f0..fa631ca4 100644 --- a/src/io/github/sspanak/tt9/ime/modes/InputMode.java +++ b/src/io/github/sspanak/tt9/ime/modes/InputMode.java @@ -131,7 +131,7 @@ abstract public class InputMode { textCase = allowedTextCases.get(nextIndex); } - public void determineNextWordTextCase(boolean isThereText, String textBeforeCursor) {} + public void determineNextWordTextCase(String textBeforeCursor) {} // Based on the internal logic of the mode (punctuation or grammar rules), re-adjust the text case for when getSuggestions() is called. protected String adjustSuggestionTextCase(String word, int newTextCase) { return word; } diff --git a/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java b/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java index 5c3df9a1..3e59c015 100644 --- a/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java +++ b/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java @@ -295,8 +295,8 @@ public class ModePredictive extends InputMode { } @Override - public void determineNextWordTextCase(boolean isThereText, String textBeforeCursor) { - textCase = autoTextCase.determineNextWordTextCase(isThereText, textCase, textFieldTextCase, textBeforeCursor); + public void determineNextWordTextCase(String textBeforeCursor) { + textCase = autoTextCase.determineNextWordTextCase(textCase, textFieldTextCase, textBeforeCursor); } @Override diff --git a/src/io/github/sspanak/tt9/ime/modes/helpers/AutoTextCase.java b/src/io/github/sspanak/tt9/ime/modes/helpers/AutoTextCase.java index cccdaed7..80ef3128 100644 --- a/src/io/github/sspanak/tt9/ime/modes/helpers/AutoTextCase.java +++ b/src/io/github/sspanak/tt9/ime/modes/helpers/AutoTextCase.java @@ -44,7 +44,7 @@ public class AutoTextCase { * For example, this function will return CASE_LOWER by default, but CASE_UPPER at the beginning * of a sentence. */ - public int determineNextWordTextCase(boolean isThereText, int currentTextCase, int textFieldTextCase, String textBeforeCursor) { + public int determineNextWordTextCase(int currentTextCase, int textFieldTextCase, String textBeforeCursor) { if ( // When the setting is off, don't do any changes. !settings.getAutoTextCase() @@ -60,7 +60,7 @@ public class AutoTextCase { } // start of text - if (!isThereText) { + if (textBeforeCursor.isEmpty()) { return InputMode.CASE_CAPITALIZE; }