From 0fe69316795d35f8f5728f2f8052f085b25b40fb Mon Sep 17 00:00:00 2001 From: Lee0701 Date: Sun, 3 May 2026 23:03:30 +0900 Subject: [PATCH 1/4] Add Emoji IME mode with simple emoji selector --- app/build.gradle.kts | 1 + .../java/ee/oyatl/ime/fusion/DimensionUtil.kt | 42 ++++++ .../ee/oyatl/ime/fusion/FusionIMEService.kt | 2 + .../ee/oyatl/ime/fusion/mode/CommonIMEMode.kt | 36 +----- .../ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt | 120 ++++++++++++++++++ gradle/libs.versions.toml | 2 + 6 files changed, 171 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/ee/oyatl/ime/fusion/DimensionUtil.kt create mode 100644 app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4eecaf70..75145fee 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -72,6 +72,7 @@ dependencies { implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) + implementation(libs.androidx.emoji2.emojipicker) implementation(libs.material) implementation(libs.guava) implementation(libs.protobuf.java) diff --git a/app/src/main/java/ee/oyatl/ime/fusion/DimensionUtil.kt b/app/src/main/java/ee/oyatl/ime/fusion/DimensionUtil.kt new file mode 100644 index 00000000..dacec3de --- /dev/null +++ b/app/src/main/java/ee/oyatl/ime/fusion/DimensionUtil.kt @@ -0,0 +1,42 @@ +package ee.oyatl.ime.fusion + +import android.annotation.SuppressLint +import android.content.Context +import android.content.res.Configuration +import android.util.TypedValue +import androidx.preference.PreferenceManager +import kotlin.math.roundToInt + +object DimensionUtil { + fun getOrientationSuffix(context: Context): String { + val landscape = context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE + val suffix = if(landscape) "_landscape" else "_portrait" + return suffix + } + + fun getOrientationInteger(context: Context, key: String): Float { + val preference = PreferenceManager.getDefaultSharedPreferences(context) + val suffix = getOrientationSuffix(context) + @SuppressLint("DiscouragedApi") + val defaultId = context.resources.getIdentifier("${key}${suffix}_default", "integer", context.packageName) + val defaultValue = context.resources.getInteger(defaultId).toFloat() + val value = preference.getFloat("${key}${suffix}", defaultValue) + return value + } + + fun getOrientationBoolean(context: Context, key: String): Boolean { + val preference = PreferenceManager.getDefaultSharedPreferences(context) + val suffix = getOrientationSuffix(context) + @SuppressLint("DiscouragedApi") + val defaultId = context.resources.getIdentifier("${key}${suffix}_default", "bool", context.packageName) + val defaultValue = context.resources.getBoolean(defaultId) + val value = preference.getBoolean("${key}${suffix}", defaultValue) + return value + } + + fun getKeyboardHeight(context: Context): Int { + val rowHeightDIP = getOrientationInteger(context, "keyboard_height") + val height = (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rowHeightDIP, context.resources.displayMetrics) * 4).roundToInt() + return height + } +} \ No newline at end of file diff --git a/app/src/main/java/ee/oyatl/ime/fusion/FusionIMEService.kt b/app/src/main/java/ee/oyatl/ime/fusion/FusionIMEService.kt index 9a9dd802..fab7a838 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/FusionIMEService.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/FusionIMEService.kt @@ -15,6 +15,7 @@ import androidx.core.view.WindowCompat import androidx.preference.PreferenceManager import com.android.inputmethod.latin.RichInputMethodManager import com.android.inputmethod.latin.settings.Settings +import ee.oyatl.ime.fusion.mode.EmojiIMEMode import ee.oyatl.ime.fusion.mode.IMEMode import ee.oyatl.ime.fusion.mode.IMEModeSwitcher import ee.oyatl.ime.fusion.mode.LatinIMEMode @@ -75,6 +76,7 @@ class FusionIMEService: InputMethodService(), IMEMode.Listener, IMEModeSwitcher. IMEMode.Params.parse(item) }.toMutableList() if(params.isEmpty()) params += LatinIMEMode.Params() + params += EmojiIMEMode.Params() params.forEach { p -> entries += IMEModeSwitcher.Entry(p.getShortLabel(this, params), p.create(this)) } diff --git a/app/src/main/java/ee/oyatl/ime/fusion/mode/CommonIMEMode.kt b/app/src/main/java/ee/oyatl/ime/fusion/mode/CommonIMEMode.kt index 05000adf..f8ef8428 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/mode/CommonIMEMode.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/mode/CommonIMEMode.kt @@ -1,8 +1,6 @@ package ee.oyatl.ime.fusion.mode -import android.annotation.SuppressLint import android.content.Context -import android.content.res.Configuration import android.util.TypedValue import android.view.KeyCharacterMap import android.view.KeyEvent @@ -12,6 +10,7 @@ import android.view.inputmethod.InputConnection import androidx.preference.PreferenceManager import ee.oyatl.ime.candidate.CandidateView import ee.oyatl.ime.candidate.ScrollingCandidateView +import ee.oyatl.ime.fusion.DimensionUtil import ee.oyatl.ime.fusion.Feature import ee.oyatl.ime.fusion.FlickAction import ee.oyatl.ime.fusion.KeyEventUtil @@ -155,41 +154,14 @@ abstract class CommonIMEMode( submitCandidates(emptyList()) } - private fun getOrientationSuffix(context: Context): String { - val landscape = context.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE - val suffix = if(landscape) "_landscape" else "_portrait" - return suffix - } - - private fun getOrientationInteger(context: Context, key: String): Float { - val preference = PreferenceManager.getDefaultSharedPreferences(context) - val suffix = getOrientationSuffix(context) - @SuppressLint("DiscouragedApi") - val defaultId = context.resources.getIdentifier("${key}${suffix}_default", "integer", context.packageName) - val defaultValue = context.resources.getInteger(defaultId).toFloat() - val value = preference.getFloat("${key}${suffix}", defaultValue) - return value - } - - private fun getOrientationBoolean(context: Context, key: String): Boolean { - val preference = PreferenceManager.getDefaultSharedPreferences(context) - val suffix = getOrientationSuffix(context) - @SuppressLint("DiscouragedApi") - val defaultId = context.resources.getIdentifier("${key}${suffix}_default", "bool", context.packageName) - val defaultValue = context.resources.getBoolean(defaultId) - val value = preference.getBoolean("${key}${suffix}", defaultValue) - return value - } - override fun createInputView(context: Context): View { val preference = PreferenceManager.getDefaultSharedPreferences(context) val defaultScreenMode = context.resources.getString(R.string.screen_mode_default) val screenMode = KeyboardState.ScreenMode.valueOf(preference.getString("screen_mode", null) ?: defaultScreenMode) - val rowHeightDIP = getOrientationInteger(context, "keyboard_height") - val height = (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rowHeightDIP, context.resources.displayMetrics) * 4).roundToInt() - val split = Feature.SplitKeyboard.availableInCurrentVersion && getOrientationBoolean(context, "split_keyboard") - val splitRatio = if(split) getOrientationInteger(context, "split_ratio") else 0f + val height = DimensionUtil.getKeyboardHeight(context) + val split = Feature.SplitKeyboard.availableInCurrentVersion && DimensionUtil.getOrientationBoolean(context, "split_keyboard") + val splitRatio = if(split) DimensionUtil.getOrientationInteger(context, "split_ratio") else 0f val splitWidthDIP = context.resources.configuration.screenWidthDp / 100f * splitRatio val splitWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, splitWidthDIP, context.resources.displayMetrics).roundToInt() val showPreviewPopup = preference.getBoolean("preview_popup", true) diff --git a/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt b/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt new file mode 100644 index 00000000..1a75cf20 --- /dev/null +++ b/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt @@ -0,0 +1,120 @@ +package ee.oyatl.ime.fusion.mode + +import android.content.Context +import android.view.View +import android.view.ViewGroup +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputConnection +import androidx.core.util.Consumer +import androidx.emoji2.emojipicker.EmojiPickerView +import androidx.emoji2.emojipicker.EmojiViewItem +import ee.oyatl.ime.candidate.CandidateView +import ee.oyatl.ime.candidate.ScrollingCandidateView +import ee.oyatl.ime.fusion.DimensionUtil +import ee.oyatl.ime.fusion.KeyEventUtil + +class EmojiIMEMode( + private val listener: IMEMode.Listener +): IMEMode, Consumer, CandidateView.Listener { + + private var emojiPickerView: EmojiPickerView? = null + var candidateView: CandidateView? = null + private var util: KeyEventUtil? = null + private val currentInputConnection: InputConnection? get() = util?.currentInputConnection + + override suspend fun onLoad(context: Context) { + } + + override fun onStart( + inputConnection: InputConnection, + editorInfo: EditorInfo + ) { + util = KeyEventUtil(inputConnection, editorInfo) + currentInputConnection?.finishComposingText() + } + + override fun onFinish() { + currentInputConnection?.finishComposingText() + } + + override fun createInputView(context: Context): View { + val emojiPickerView = EmojiPickerView(context) + val height = DimensionUtil.getKeyboardHeight(context) + emojiPickerView.layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + height + ) + emojiPickerView.setOnEmojiPickedListener(this) + this.emojiPickerView = emojiPickerView + return emojiPickerView + } + + override fun createCandidateView(context: Context): View { + candidateView = ScrollingCandidateView(context, null).apply { + listener = this@EmojiIMEMode + } + return candidateView as View + } + + override fun getInputView(): View? { + return emojiPickerView + } + + override fun accept(value: EmojiViewItem) { + currentInputConnection?.finishComposingText() + currentInputConnection?.setComposingText(value.emoji, 1) + val candidates = value.variants.map { Candidate(it) } + submitCandidates(candidates) + } + + private fun submitCandidates(candidates: List) { + candidateView?.submitList(candidates) + listener.onCandidateViewVisibilityChange(candidates.isNotEmpty()) + } + + override fun onCandidateSelected(candidate: CandidateView.Candidate) { + currentInputConnection?.setComposingText(candidate.text, 1) + currentInputConnection?.finishComposingText() + submitCandidates(emptyList()) + } + + override fun onKeyDown(keyCode: Int, metaState: Int) = Unit + + override fun onKeyUp(keyCode: Int, metaState: Int) = Unit + + override fun updateSelection( + oldSelStart: Int, + oldSelEnd: Int, + newSelStart: Int, + newSelEnd: Int, + candidatesStart: Int, + candidatesEnd: Int + ) = Unit + + data class Candidate( + override val text: CharSequence + ): CandidateView.Candidate + + class Params: IMEMode.Params { + override val type: String = TYPE + + override fun create(listener: IMEMode.Listener): IMEMode { + return EmojiIMEMode(listener) + } + + override fun getLabel(context: Context): String { + return "Emoji" + } + + override fun getShortLabel( + context: Context, + params: List + ): String { + return "\uD83D\uDE00" + } + } + + companion object { + const val TYPE: String = "emoji" + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0889c1d5..ddd87d5f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -16,6 +16,7 @@ legacySupportV4 = "1.0.0" annotation = "1.10.0" preference = "1.2.1" desugarJdkLibs = "2.1.5" +emoji2Emojipicker = "1.5.0" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -33,6 +34,7 @@ androidx-legacy-support-v4 = { group = "androidx.legacy", name = "legacy-support androidx-annotation = { group = "androidx.annotation", name = "annotation", version.ref = "annotation" } androidx-preference = { group = "androidx.preference", name = "preference", version.ref = "preference" } desugar-jdk-libs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "desugarJdkLibs" } +androidx-emoji2-emojipicker = { group = "androidx.emoji2", name = "emoji2-emojipicker", version.ref = "emoji2Emojipicker" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } From 3ddf0c6999e9d86b616d10e4020eac746d601713 Mon Sep 17 00:00:00 2001 From: Lee0701 Date: Mon, 4 May 2026 14:35:54 +0900 Subject: [PATCH 2/4] Add delete button to emoji picker --- .../ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt | 27 +++++++++----- app/src/main/res/layout/emoji_ime_mode.xml | 35 +++++++++++++++++++ 2 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 app/src/main/res/layout/emoji_ime_mode.xml diff --git a/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt b/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt index 1a75cf20..aa0c02ee 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt @@ -1,24 +1,25 @@ package ee.oyatl.ime.fusion.mode import android.content.Context +import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputConnection import androidx.core.util.Consumer -import androidx.emoji2.emojipicker.EmojiPickerView import androidx.emoji2.emojipicker.EmojiViewItem import ee.oyatl.ime.candidate.CandidateView import ee.oyatl.ime.candidate.ScrollingCandidateView import ee.oyatl.ime.fusion.DimensionUtil import ee.oyatl.ime.fusion.KeyEventUtil +import ee.oyatl.ime.fusion.databinding.EmojiImeModeBinding class EmojiIMEMode( private val listener: IMEMode.Listener ): IMEMode, Consumer, CandidateView.Listener { - private var emojiPickerView: EmojiPickerView? = null - var candidateView: CandidateView? = null + private var inputView: View? = null + private var candidateView: CandidateView? = null private var util: KeyEventUtil? = null private val currentInputConnection: InputConnection? get() = util?.currentInputConnection @@ -38,15 +39,18 @@ class EmojiIMEMode( } override fun createInputView(context: Context): View { - val emojiPickerView = EmojiPickerView(context) val height = DimensionUtil.getKeyboardHeight(context) - emojiPickerView.layoutParams = ViewGroup.LayoutParams( + val binding = EmojiImeModeBinding.inflate(LayoutInflater.from(context)) + binding.emojiPickerView.setOnEmojiPickedListener(this) + binding.buttonDelete.setOnClickListener { + onDelete() + } + binding.root.layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height ) - emojiPickerView.setOnEmojiPickedListener(this) - this.emojiPickerView = emojiPickerView - return emojiPickerView + this.inputView = binding.root + return binding.root } override fun createCandidateView(context: Context): View { @@ -57,7 +61,7 @@ class EmojiIMEMode( } override fun getInputView(): View? { - return emojiPickerView + return inputView } override fun accept(value: EmojiViewItem) { @@ -78,6 +82,11 @@ class EmojiIMEMode( submitCandidates(emptyList()) } + private fun onDelete() { + currentInputConnection?.finishComposingText() + currentInputConnection?.deleteSurroundingText(1, 0) + } + override fun onKeyDown(keyCode: Int, metaState: Int) = Unit override fun onKeyUp(keyCode: Int, metaState: Int) = Unit diff --git a/app/src/main/res/layout/emoji_ime_mode.xml b/app/src/main/res/layout/emoji_ime_mode.xml new file mode 100644 index 00000000..aac31043 --- /dev/null +++ b/app/src/main/res/layout/emoji_ime_mode.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + \ No newline at end of file From ec14eebc5cfa69b47e84f1452bc6f082c7403420 Mon Sep 17 00:00:00 2001 From: Lee0701 Date: Mon, 4 May 2026 14:39:30 +0900 Subject: [PATCH 3/4] Fix delete surrounding text function --- app/src/main/java/ee/oyatl/ime/fusion/KeyEventUtil.kt | 8 ++++++++ .../main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt | 2 +- .../main/java/ee/oyatl/ime/fusion/mode/KoreanIMEMode.kt | 2 +- .../main/java/ee/oyatl/ime/fusion/mode/PinyinIMEMode.kt | 4 ++-- .../main/java/ee/oyatl/ime/fusion/mode/ZhuyinIMEMode.kt | 3 +-- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/ee/oyatl/ime/fusion/KeyEventUtil.kt b/app/src/main/java/ee/oyatl/ime/fusion/KeyEventUtil.kt index b4f2a73e..9efaa998 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/KeyEventUtil.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/KeyEventUtil.kt @@ -1,5 +1,6 @@ package ee.oyatl.ime.fusion +import android.os.Build import android.os.SystemClock import android.view.KeyCharacterMap import android.view.KeyEvent @@ -115,4 +116,11 @@ class KeyEventUtil( } } + fun deleteSurroundingText(beforeLength: Int, afterLength: Int) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + currentInputConnection.deleteSurroundingTextInCodePoints(beforeLength, afterLength) + } else { + currentInputConnection.deleteSurroundingText(beforeLength, afterLength) + } + } } \ No newline at end of file diff --git a/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt b/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt index aa0c02ee..d0427685 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt @@ -84,7 +84,7 @@ class EmojiIMEMode( private fun onDelete() { currentInputConnection?.finishComposingText() - currentInputConnection?.deleteSurroundingText(1, 0) + util?.deleteSurroundingText(1, 0) } override fun onKeyDown(keyCode: Int, metaState: Int) = Unit diff --git a/app/src/main/java/ee/oyatl/ime/fusion/mode/KoreanIMEMode.kt b/app/src/main/java/ee/oyatl/ime/fusion/mode/KoreanIMEMode.kt index 112fd6aa..35ad84ab 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/mode/KoreanIMEMode.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/mode/KoreanIMEMode.kt @@ -109,7 +109,7 @@ abstract class KoreanIMEMode( } else if(wordComposer.composingText.isNotEmpty()) { wordComposer.delete(1) } else { - currentInputConnection?.deleteSurroundingText(1, 0) + util?.deleteSurroundingText(1, 0) } renderInputView() } diff --git a/app/src/main/java/ee/oyatl/ime/fusion/mode/PinyinIMEMode.kt b/app/src/main/java/ee/oyatl/ime/fusion/mode/PinyinIMEMode.kt index 734c43a3..f854ee67 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/mode/PinyinIMEMode.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/mode/PinyinIMEMode.kt @@ -325,7 +325,7 @@ class PinyinIMEMode( if (SIMULATE_KEY_DELETE) { simulateKeyEventDownUp(keyCode) } else { - currentInputConnection?.deleteSurroundingText(1, 0) + util?.deleteSurroundingText(1, 0) } return true } @@ -360,7 +360,7 @@ class PinyinIMEMode( if (SIMULATE_KEY_DELETE) { simulateKeyEventDownUp(keyCode) } else { - currentInputConnection?.deleteSurroundingText(1, 0) + util?.deleteSurroundingText(1, 0) } return true } else if (keyCode == KeyEvent.KEYCODE_ENTER) { diff --git a/app/src/main/java/ee/oyatl/ime/fusion/mode/ZhuyinIMEMode.kt b/app/src/main/java/ee/oyatl/ime/fusion/mode/ZhuyinIMEMode.kt index 082e7b6f..e968ec1f 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/mode/ZhuyinIMEMode.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/mode/ZhuyinIMEMode.kt @@ -136,14 +136,13 @@ class ZhuyinIMEMode( } private fun handleBackspace() { - val ic = currentInputConnection ?: return var deleteChar = false if (wordComposer.typedWord?.isNotEmpty() == true) { val length: Int = wordComposer.typedWord.length if (length > 0) { wordComposer.deleteLast() } else { - ic.deleteSurroundingText(1, 0) + util?.deleteSurroundingText(1, 0) } } else { deleteChar = true From 983f6ad2217a6fe276b58a0d9f3b0cfc7cd98227 Mon Sep 17 00:00:00 2001 From: Lee0701 Date: Mon, 4 May 2026 14:46:25 +0900 Subject: [PATCH 4/4] Add emoji input mode to type selector --- .../main/java/ee/oyatl/ime/fusion/FusionIMEService.kt | 2 -- .../main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt | 9 ++++++++- app/src/main/java/ee/oyatl/ime/fusion/mode/IMEMode.kt | 1 + app/src/main/res/values/arrays.xml | 2 ++ app/src/main/res/values/strings.xml | 1 + 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/ee/oyatl/ime/fusion/FusionIMEService.kt b/app/src/main/java/ee/oyatl/ime/fusion/FusionIMEService.kt index fab7a838..9a9dd802 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/FusionIMEService.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/FusionIMEService.kt @@ -15,7 +15,6 @@ import androidx.core.view.WindowCompat import androidx.preference.PreferenceManager import com.android.inputmethod.latin.RichInputMethodManager import com.android.inputmethod.latin.settings.Settings -import ee.oyatl.ime.fusion.mode.EmojiIMEMode import ee.oyatl.ime.fusion.mode.IMEMode import ee.oyatl.ime.fusion.mode.IMEModeSwitcher import ee.oyatl.ime.fusion.mode.LatinIMEMode @@ -76,7 +75,6 @@ class FusionIMEService: InputMethodService(), IMEMode.Listener, IMEModeSwitcher. IMEMode.Params.parse(item) }.toMutableList() if(params.isEmpty()) params += LatinIMEMode.Params() - params += EmojiIMEMode.Params() params.forEach { p -> entries += IMEModeSwitcher.Entry(p.getShortLabel(this, params), p.create(this)) } diff --git a/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt b/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt index d0427685..73edb615 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/mode/EmojiIMEMode.kt @@ -12,6 +12,7 @@ import ee.oyatl.ime.candidate.CandidateView import ee.oyatl.ime.candidate.ScrollingCandidateView import ee.oyatl.ime.fusion.DimensionUtil import ee.oyatl.ime.fusion.KeyEventUtil +import ee.oyatl.ime.fusion.R import ee.oyatl.ime.fusion.databinding.EmojiImeModeBinding class EmojiIMEMode( @@ -112,7 +113,7 @@ class EmojiIMEMode( } override fun getLabel(context: Context): String { - return "Emoji" + return context.getString(R.string.input_mode_emoji) } override fun getShortLabel( @@ -121,6 +122,12 @@ class EmojiIMEMode( ): String { return "\uD83D\uDE00" } + + companion object { + fun parse(map: Map): Params { + return Params() + } + } } companion object { diff --git a/app/src/main/java/ee/oyatl/ime/fusion/mode/IMEMode.kt b/app/src/main/java/ee/oyatl/ime/fusion/mode/IMEMode.kt index 20e221ef..c9ced0bc 100644 --- a/app/src/main/java/ee/oyatl/ime/fusion/mode/IMEMode.kt +++ b/app/src/main/java/ee/oyatl/ime/fusion/mode/IMEMode.kt @@ -52,6 +52,7 @@ interface IMEMode { ZhuyinIMEMode.TYPE -> ZhuyinIMEMode.Params.parse(map) CangjieIMEMode.TYPE -> CangjieIMEMode.Params.parse(map) VietIMEMode.TYPE -> VietIMEMode.Params.parse(map) + EmojiIMEMode.TYPE -> EmojiIMEMode.Params.parse(map) else -> null } } diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index a7e03d0e..e0d5e09c 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -45,6 +45,7 @@ @string/input_mode_zhuyin @string/input_mode_cangjie @string/input_mode_viet + @string/input_mode_emoji @@ -55,6 +56,7 @@ zhuyin cangjie viet + emoji diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2f4cc7bb..a8d16414 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -88,6 +88,7 @@ Bopomofo (Traditional Chinese) Cangjie Vietnamese + Emoji German English