diff --git a/app/src/main/java/org/lineageos/recorder/ListActivity.kt b/app/src/main/java/org/lineageos/recorder/ListActivity.kt index 69a61b9c..a5df0dc9 100644 --- a/app/src/main/java/org/lineageos/recorder/ListActivity.kt +++ b/app/src/main/java/org/lineageos/recorder/ListActivity.kt @@ -12,9 +12,12 @@ import android.view.ActionMode import android.view.Menu import android.view.MenuItem import android.view.View +import android.view.inputmethod.EditorInfo +import android.view.inputmethod.InputMethodManager import android.widget.EditText import android.widget.ProgressBar import android.widget.TextView +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.core.view.ViewCompat @@ -26,6 +29,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.lineageos.recorder.ext.scheduleShowSoftInput import org.lineageos.recorder.list.ListActionModeCallback import org.lineageos.recorder.list.RecordingData import org.lineageos.recorder.list.RecordingListCallbacks @@ -48,6 +52,9 @@ class ListActivity : AppCompatActivity(), RecordingListCallbacks { private val listRecyclerView by lazy { findViewById(R.id.listRecyclerView) } private val toolbar by lazy { findViewById(R.id.toolbar) } + // System services + private val inputMethodManager by lazy { getSystemService(InputMethodManager::class.java) } + // Adapters private val adapter by lazy { RecordingsAdapter(this) @@ -127,31 +134,54 @@ class ListActivity : AppCompatActivity(), RecordingListCallbacks { } override fun onRename(index: Int, uri: Uri, currentName: String) { - val view = layoutInflater.inflate(R.layout.dialog_content_rename, null) - - val editText = view.findViewById(R.id.nameEditText) - editText.setText(currentName) - editText.requestFocus() - Utils.showKeyboard(this) + lateinit var alertDialog: AlertDialog + lateinit var editText: EditText - MaterialAlertDialogBuilder(this) - .setTitle(R.string.list_edit_title) - .setView(view) - .setPositiveButton(R.string.list_edit_confirm) { _: DialogInterface?, _: Int -> - val editable = editText.text ?: return@setPositiveButton - if (editable.isEmpty()) { - return@setPositiveButton - } + val onConfirm = { + editText.text?.takeIf { it.isNotEmpty() }?.let { editable -> val newTitle = editable.toString() if (newTitle != currentName) { renameRecording(uri, newTitle, index) } - Utils.closeKeyboard(this) - } - .setNegativeButton(R.string.cancel) { _: DialogInterface?, _: Int -> - Utils.closeKeyboard(this) + + true + } ?: false + } + + val view = layoutInflater.inflate( + R.layout.dialog_content_rename, + null, + false + ) + editText = view.findViewById(R.id.nameEditText).apply { + setText(currentName) + setSelection(0, currentName.length) + setOnEditorActionListener { _, actionId, _ -> + when (actionId) { + EditorInfo.IME_ACTION_UNSPECIFIED, + EditorInfo.IME_ACTION_DONE -> { + onConfirm().also { + if (it) { + alertDialog.dismiss() + } + } + } + + else -> false + } } + } + + alertDialog = MaterialAlertDialogBuilder(this) + .setTitle(R.string.list_edit_title) + .setView(view) + .setPositiveButton(R.string.list_edit_confirm) { _, _ -> onConfirm() } + .setNegativeButton(R.string.cancel, null) .show() + .also { + editText.requestFocus() + inputMethodManager.scheduleShowSoftInput(editText, 0) + } } override fun onCreateOptionsMenu(menu: Menu): Boolean { diff --git a/app/src/main/java/org/lineageos/recorder/ext/InputMethodManager.kt b/app/src/main/java/org/lineageos/recorder/ext/InputMethodManager.kt new file mode 100644 index 00000000..fc2e6fb7 --- /dev/null +++ b/app/src/main/java/org/lineageos/recorder/ext/InputMethodManager.kt @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2024 The LineageOS Project + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.lineageos.recorder.ext + +import android.view.View +import android.view.inputmethod.InputMethodManager + +private const val SHOW_REQUEST_TIMEOUT = 1000 + +private fun InputMethodManager.scheduleShowSoftInput( + view: View, + flags: Int, + runnable: Runnable, + showRequestTime: Long, +) { + if (!view.hasFocus() + || (showRequestTime + SHOW_REQUEST_TIMEOUT) <= System.currentTimeMillis() + ) { + return + } + + if (showSoftInput(view, flags)) { + return + } else { + view.removeCallbacks(runnable) + view.postDelayed(runnable, 50) + } +} + +/** + * @see InputMethodManager.showSoftInput + */ +fun InputMethodManager.scheduleShowSoftInput(view: View, flags: Int) { + val runnable = object : Runnable { + override fun run() { + scheduleShowSoftInput(view, flags, this, System.currentTimeMillis()) + } + } + + runnable.run() +} diff --git a/app/src/main/java/org/lineageos/recorder/utils/Utils.kt b/app/src/main/java/org/lineageos/recorder/utils/Utils.kt index fc5c3ed7..ac317730 100644 --- a/app/src/main/java/org/lineageos/recorder/utils/Utils.kt +++ b/app/src/main/java/org/lineageos/recorder/utils/Utils.kt @@ -7,24 +7,9 @@ package org.lineageos.recorder.utils import android.app.NotificationManager import android.content.Context -import android.view.inputmethod.InputMethodManager import org.lineageos.recorder.service.SoundRecorderService object Utils { - fun showKeyboard(context: Context) { - val inputMethodManager = context.getSystemService( - InputMethodManager::class.java - ) - inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0) - } - - fun closeKeyboard(context: Context) { - val inputMethodManager = context.getSystemService( - InputMethodManager::class.java - ) - inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0) - } - fun cancelShareNotification(context: Context) { val nm = context.getSystemService( NotificationManager::class.java diff --git a/app/src/main/res/layout/dialog_content_rename.xml b/app/src/main/res/layout/dialog_content_rename.xml index 988dadf7..29d58bbb 100644 --- a/app/src/main/res/layout/dialog_content_rename.xml +++ b/app/src/main/res/layout/dialog_content_rename.xml @@ -4,17 +4,16 @@ SPDX-License-Identifier: Apache-2.0 --> + android:paddingHorizontal="?attr/dialogPreferredPadding"> - + android:singleLine="true" /> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 32264626..43dc2cf5 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -10,6 +10,8 @@ shortEdges ?attr/isLightTheme ?attr/isLightTheme + @style/Theme.Recorder.AlertDialog + @style/Theme.Recorder.AlertDialog true @@ -52,4 +54,10 @@ ?attr/colorOnSurface ?attr/colorOnSurface + + +