kunfei 4 лет назад
Родитель
Сommit
12173f9038

+ 10 - 0
app/src/main/java/io/legado/app/data/dao/KeyboardAssistsDao.kt

@@ -3,6 +3,7 @@ package io.legado.app.data.dao
 import androidx.room.*
 import androidx.room.*
 import io.legado.app.data.entities.KeyboardAssist
 import io.legado.app.data.entities.KeyboardAssist
 import io.legado.app.help.DefaultData
 import io.legado.app.help.DefaultData
+import kotlinx.coroutines.flow.Flow
 
 
 @Dao
 @Dao
 interface KeyboardAssistsDao {
 interface KeyboardAssistsDao {
@@ -13,6 +14,15 @@ interface KeyboardAssistsDao {
     @Query("select * from keyboardAssists where type = :type")
     @Query("select * from keyboardAssists where type = :type")
     fun getByType(type: Int): List<KeyboardAssist>
     fun getByType(type: Int): List<KeyboardAssist>
 
 
+    @get:Query("select * from keyboardAssists")
+    val flowAll: Flow<List<KeyboardAssist>>
+
+    @Query("select * from keyboardAssists where type = :type")
+    fun flowByType(type: Int): Flow<List<KeyboardAssist>>
+
+    @get:Query("select max(serialNo) from keyboardAssists")
+    val maxSerialNo: Int
+
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     @Insert(onConflict = OnConflictStrategy.REPLACE)
     fun insert(vararg keyboardAssist: KeyboardAssist)
     fun insert(vararg keyboardAssist: KeyboardAssist)
 
 

+ 4 - 4
app/src/main/java/io/legado/app/data/entities/KeyboardAssist.kt

@@ -6,11 +6,11 @@ import androidx.room.Entity
 @Entity(tableName = "keyboardAssists", primaryKeys = ["type", "key"])
 @Entity(tableName = "keyboardAssists", primaryKeys = ["type", "key"])
 data class KeyboardAssist(
 data class KeyboardAssist(
     @ColumnInfo(defaultValue = "0")
     @ColumnInfo(defaultValue = "0")
-    val type: Int = 0,
+    var type: Int = 0,
     @ColumnInfo(defaultValue = "")
     @ColumnInfo(defaultValue = "")
-    val key: String,
+    var key: String,
     @ColumnInfo(defaultValue = "")
     @ColumnInfo(defaultValue = "")
-    val value: String,
+    var value: String,
     @ColumnInfo(defaultValue = "0")
     @ColumnInfo(defaultValue = "0")
-    val serialNo: Int
+    var serialNo: Int = 0
 )
 )

+ 1 - 1
app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt

@@ -46,7 +46,7 @@ class GroupManageDialog : BaseDialogFragment(R.layout.dialog_recycler_view),
 
 
     override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
     override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
         binding.toolBar.setBackgroundColor(primaryColor)
         binding.toolBar.setBackgroundColor(primaryColor)
-        binding.toolBar.title = getString(R.string.group_manage)
+        binding.toolBar.setTitle(R.string.group_manage)
         initView()
         initView()
         initData()
         initData()
         initMenu()
         initMenu()

+ 20 - 13
app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt

@@ -17,16 +17,16 @@ import io.legado.app.data.entities.BookSource
 import io.legado.app.data.entities.rule.*
 import io.legado.app.data.entities.rule.*
 import io.legado.app.databinding.ActivityBookSourceEditBinding
 import io.legado.app.databinding.ActivityBookSourceEditBinding
 import io.legado.app.help.config.LocalConfig
 import io.legado.app.help.config.LocalConfig
+import io.legado.app.lib.dialogs.SelectItem
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.dialogs.alert
-import io.legado.app.lib.dialogs.selector
 import io.legado.app.lib.theme.backgroundColor
 import io.legado.app.lib.theme.backgroundColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.ui.book.source.debug.BookSourceDebugActivity
 import io.legado.app.ui.book.source.debug.BookSourceDebugActivity
 import io.legado.app.ui.document.HandleFileContract
 import io.legado.app.ui.document.HandleFileContract
 import io.legado.app.ui.login.SourceLoginActivity
 import io.legado.app.ui.login.SourceLoginActivity
 import io.legado.app.ui.qrcode.QrCodeResult
 import io.legado.app.ui.qrcode.QrCodeResult
-import io.legado.app.ui.widget.KeyboardToolPop
 import io.legado.app.ui.widget.dialog.TextDialog
 import io.legado.app.ui.widget.dialog.TextDialog
+import io.legado.app.ui.widget.keyboard.KeyboardToolPop
 import io.legado.app.utils.*
 import io.legado.app.utils.*
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 
 
@@ -435,17 +435,24 @@ class BookSourceEditActivity :
         return true
         return true
     }
     }
 
 
-    override fun keyboardHelp() {
-        val items = arrayListOf("插入URL参数", "书源教程", "js教程", "正则教程", "选择文件")
-        selector(getString(R.string.help), items) { _, index ->
-            when (index) {
-                0 -> sendText(AppConst.urlOption)
-                1 -> showHelp("ruleHelp")
-                2 -> showHelp("jsHelp")
-                3 -> showHelp("regexHelp")
-                4 -> selectDoc.launch {
-                    mode = HandleFileContract.FILE
-                }
+    override fun helpActions(): List<SelectItem<String>> {
+        return arrayListOf(
+            SelectItem("插入URL参数", "urlOption"),
+            SelectItem("书源教程", "ruleHelp"),
+            SelectItem("js教程", "jsHelp"),
+            SelectItem("正则教程", "regexHelp"),
+            SelectItem("选择文件", "selectFile"),
+        )
+    }
+
+    override fun onHelpActionSelect(action: String) {
+        when (action) {
+            "urlOption" -> sendText(AppConst.urlOption)
+            "ruleHelp" -> showHelp("ruleHelp")
+            "jsHelp" -> showHelp("jsHelp")
+            "regexHelp" -> showHelp("regexHelp")
+            "selectFile" -> selectDoc.launch {
+                mode = HandleFileContract.FILE
             }
             }
         }
         }
     }
     }

+ 16 - 11
app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditActivity.kt

@@ -11,9 +11,9 @@ import io.legado.app.R
 import io.legado.app.base.VMBaseActivity
 import io.legado.app.base.VMBaseActivity
 import io.legado.app.data.entities.ReplaceRule
 import io.legado.app.data.entities.ReplaceRule
 import io.legado.app.databinding.ActivityReplaceEditBinding
 import io.legado.app.databinding.ActivityReplaceEditBinding
-import io.legado.app.lib.dialogs.selector
-import io.legado.app.ui.widget.KeyboardToolPop
+import io.legado.app.lib.dialogs.SelectItem
 import io.legado.app.ui.widget.dialog.TextDialog
 import io.legado.app.ui.widget.dialog.TextDialog
+import io.legado.app.ui.widget.keyboard.KeyboardToolPop
 import io.legado.app.utils.showDialogFragment
 import io.legado.app.utils.showDialogFragment
 import io.legado.app.utils.toastOnUi
 import io.legado.app.utils.toastOnUi
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 import io.legado.app.utils.viewbindingdelegate.viewBinding
@@ -57,7 +57,7 @@ class ReplaceEditActivity :
             upReplaceView(it)
             upReplaceView(it)
         }
         }
         binding.ivHelp.setOnClickListener {
         binding.ivHelp.setOnClickListener {
-            showRegexHelp()
+            showHelp("regexHelp")
         }
         }
     }
     }
 
 
@@ -112,12 +112,15 @@ class ReplaceEditActivity :
         return replaceRule
         return replaceRule
     }
     }
 
 
-    override fun keyboardHelp() {
-        val items = arrayListOf("正则教程")
-        selector(getString(R.string.help), items) { _, index ->
-            when (index) {
-                0 -> showRegexHelp()
-            }
+    override fun helpActions(): List<SelectItem<String>> {
+        return arrayListOf(
+            SelectItem("正则教程", "regexHelp")
+        )
+    }
+
+    override fun onHelpActionSelect(action: String) {
+        when (action) {
+            "regexHelp" -> showHelp("regexHelp")
         }
         }
     }
     }
 
 
@@ -138,8 +141,10 @@ class ReplaceEditActivity :
         }
         }
     }
     }
 
 
-    private fun showRegexHelp() {
-        val mdText = String(assets.open("help/regexHelp.md").readBytes())
+    @Suppress("SameParameterValue")
+    private fun showHelp(fileName: String) {
+        //显示目录help下的帮助文档
+        val mdText = String(assets.open("help/${fileName}.md").readBytes())
         showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD))
         showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD))
     }
     }
 
 

+ 35 - 18
app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt

@@ -13,14 +13,15 @@ import io.legado.app.constant.AppConst
 import io.legado.app.data.entities.RssSource
 import io.legado.app.data.entities.RssSource
 import io.legado.app.databinding.ActivityRssSourceEditBinding
 import io.legado.app.databinding.ActivityRssSourceEditBinding
 import io.legado.app.help.config.LocalConfig
 import io.legado.app.help.config.LocalConfig
+import io.legado.app.lib.dialogs.SelectItem
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.lib.dialogs.alert
-import io.legado.app.lib.dialogs.selector
 import io.legado.app.lib.theme.primaryColor
 import io.legado.app.lib.theme.primaryColor
+import io.legado.app.ui.document.HandleFileContract
 import io.legado.app.ui.login.SourceLoginActivity
 import io.legado.app.ui.login.SourceLoginActivity
 import io.legado.app.ui.qrcode.QrCodeResult
 import io.legado.app.ui.qrcode.QrCodeResult
 import io.legado.app.ui.rss.source.debug.RssSourceDebugActivity
 import io.legado.app.ui.rss.source.debug.RssSourceDebugActivity
-import io.legado.app.ui.widget.KeyboardToolPop
 import io.legado.app.ui.widget.dialog.TextDialog
 import io.legado.app.ui.widget.dialog.TextDialog
+import io.legado.app.ui.widget.keyboard.KeyboardToolPop
 import io.legado.app.utils.*
 import io.legado.app.utils.*
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 
 
@@ -35,6 +36,15 @@ class RssSourceEditActivity :
     }
     }
     private val adapter by lazy { RssSourceEditAdapter() }
     private val adapter by lazy { RssSourceEditAdapter() }
     private val sourceEntities: ArrayList<EditEntity> = ArrayList()
     private val sourceEntities: ArrayList<EditEntity> = ArrayList()
+    private val selectDoc = registerForActivityResult(HandleFileContract()) {
+        it.uri?.let { uri ->
+            if (uri.isContentScheme()) {
+                sendText(uri.toString())
+            } else {
+                sendText(uri.path.toString())
+            }
+        }
+    }
     private val qrCodeResult = registerForActivityResult(QrCodeResult()) {
     private val qrCodeResult = registerForActivityResult(QrCodeResult()) {
         it?.let {
         it?.let {
             viewModel.importSource(it) { source: RssSource ->
             viewModel.importSource(it) { source: RssSource ->
@@ -54,7 +64,7 @@ class RssSourceEditActivity :
     override fun onPostCreate(savedInstanceState: Bundle?) {
     override fun onPostCreate(savedInstanceState: Bundle?) {
         super.onPostCreate(savedInstanceState)
         super.onPostCreate(savedInstanceState)
         if (!LocalConfig.ruleHelpVersionIsLast) {
         if (!LocalConfig.ruleHelpVersionIsLast) {
-            showRuleHelp()
+            showHelp("ruleHelp")
         }
         }
     }
     }
 
 
@@ -130,7 +140,7 @@ class RssSourceEditActivity :
                 getString(R.string.share_rss_source),
                 getString(R.string.share_rss_source),
                 ErrorCorrectionLevel.L
                 ErrorCorrectionLevel.L
             )
             )
-            R.id.menu_help -> showRuleHelp()
+            R.id.menu_help -> showHelp("ruleHelp")
         }
         }
         return super.onCompatOptionsItemSelected(item)
         return super.onCompatOptionsItemSelected(item)
     }
     }
@@ -225,13 +235,24 @@ class RssSourceEditActivity :
         return true
         return true
     }
     }
 
 
-    override fun keyboardHelp() {
-        val items = arrayListOf("插入URL参数", "订阅源教程", "正则教程")
-        selector(getString(R.string.help), items) { _, index ->
-            when (index) {
-                0 -> sendText(AppConst.urlOption)
-                1 -> showRuleHelp()
-                2 -> showRegexHelp()
+    override fun helpActions(): List<SelectItem<String>> {
+        return arrayListOf(
+            SelectItem("插入URL参数", "urlOption"),
+            SelectItem("订阅源教程", "ruleHelp"),
+            SelectItem("js教程", "jsHelp"),
+            SelectItem("正则教程", "regexHelp"),
+            SelectItem("选择文件", "selectFile"),
+        )
+    }
+
+    override fun onHelpActionSelect(action: String) {
+        when (action) {
+            "urlOption" -> sendText(AppConst.urlOption)
+            "ruleHelp" -> showHelp("ruleHelp")
+            "jsHelp" -> showHelp("jsHelp")
+            "regexHelp" -> showHelp("regexHelp")
+            "selectFile" -> selectDoc.launch {
+                mode = HandleFileContract.FILE
             }
             }
         }
         }
     }
     }
@@ -251,13 +272,9 @@ class RssSourceEditActivity :
         }
         }
     }
     }
 
 
-    private fun showRuleHelp() {
-        val mdText = String(assets.open("help/ruleHelp.md").readBytes())
-        showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD))
-    }
-
-    private fun showRegexHelp() {
-        val mdText = String(assets.open("help/regexHelp.md").readBytes())
+    private fun showHelp(fileName: String) {
+        //显示目录help下的帮助文档
+        val mdText = String(assets.open("help/${fileName}.md").readBytes())
         showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD))
         showDialogFragment(TextDialog(mdText, TextDialog.Mode.MD))
     }
     }
 
 

+ 156 - 0
app/src/main/java/io/legado/app/ui/widget/keyboard/KeyboardAssistsConfig.kt

@@ -0,0 +1,156 @@
+package io.legado.app.ui.widget.keyboard
+
+import android.content.Context
+import android.os.Bundle
+import android.view.MenuItem
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.widget.Toolbar
+import androidx.recyclerview.widget.ItemTouchHelper
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import io.legado.app.R
+import io.legado.app.base.BaseDialogFragment
+import io.legado.app.base.adapter.ItemViewHolder
+import io.legado.app.base.adapter.RecyclerAdapter
+import io.legado.app.data.appDb
+import io.legado.app.data.entities.KeyboardAssist
+import io.legado.app.databinding.DialogMultipleEditTextBinding
+import io.legado.app.databinding.DialogRecyclerViewBinding
+import io.legado.app.databinding.Item1lineTextAndDelBinding
+import io.legado.app.lib.dialogs.alert
+import io.legado.app.lib.theme.primaryColor
+import io.legado.app.ui.widget.recycler.ItemTouchCallback
+import io.legado.app.ui.widget.recycler.VerticalDivider
+import io.legado.app.utils.applyTint
+import io.legado.app.utils.setLayout
+import io.legado.app.utils.viewbindingdelegate.viewBinding
+import io.legado.app.utils.visible
+import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.launch
+
+class KeyboardAssistsConfig : BaseDialogFragment(R.layout.dialog_recycler_view),
+    Toolbar.OnMenuItemClickListener {
+
+    private val binding by viewBinding(DialogRecyclerViewBinding::bind)
+    private val adapter by lazy { KeyAdapter(requireContext()) }
+
+    override fun onStart() {
+        super.onStart()
+        setLayout(0.9f, 0.9f)
+    }
+
+    override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
+        binding.toolBar.setBackgroundColor(primaryColor)
+        binding.toolBar.setTitle(R.string.assists_key_config)
+        initView()
+        initMenu()
+        initData()
+    }
+
+    private fun initView() {
+        binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
+        binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
+        binding.recyclerView.adapter = adapter
+        val itemTouchCallback = ItemTouchCallback(adapter)
+        itemTouchCallback.isCanDrag = true
+        ItemTouchHelper(itemTouchCallback).attachToRecyclerView(binding.recyclerView)
+
+    }
+
+    private fun initMenu() {
+        binding.toolBar.setOnMenuItemClickListener(this)
+        binding.toolBar.inflateMenu(R.menu.keyboard_assists_config)
+        binding.toolBar.menu.applyTint(requireContext())
+    }
+
+    private fun initData() {
+        launch {
+            appDb.keyboardAssistsDao.flowAll.collect {
+                adapter.setItems(it)
+            }
+        }
+    }
+
+    override fun onMenuItemClick(item: MenuItem?): Boolean {
+        when (item?.itemId) {
+            R.id.menu_add -> editKey(null)
+        }
+        return false
+    }
+
+    private fun editKey(keyboardAssist: KeyboardAssist?) {
+        alert {
+            setTitle("辅助按键")
+            val alertBinding = DialogMultipleEditTextBinding.inflate(layoutInflater).apply {
+                layout1.hint = "key"
+                layout2.hint = "value"
+                layout2.visible()
+            }
+            setCustomView(alertBinding.root)
+            cancelButton()
+            okButton {
+                launch(IO) {
+                    val newKeyboardAssist = KeyboardAssist(
+                        key = alertBinding.edit1.text.toString(),
+                        value = alertBinding.edit2.text.toString()
+                    )
+                    if (keyboardAssist == null) {
+                        newKeyboardAssist.serialNo = appDb.keyboardAssistsDao.maxSerialNo + 1
+                        appDb.keyboardAssistsDao.insert(newKeyboardAssist)
+                    } else {
+                        newKeyboardAssist.serialNo = keyboardAssist.serialNo
+                        appDb.keyboardAssistsDao.delete(keyboardAssist)
+                        appDb.keyboardAssistsDao.insert(newKeyboardAssist)
+                    }
+                }
+            }
+        }
+    }
+
+    private inner class KeyAdapter(context: Context) :
+        RecyclerAdapter<KeyboardAssist, Item1lineTextAndDelBinding>(context),
+        ItemTouchCallback.Callback {
+
+        private var isMoved = false
+
+        override fun getViewBinding(parent: ViewGroup): Item1lineTextAndDelBinding {
+            return Item1lineTextAndDelBinding.inflate(inflater, parent, false)
+        }
+
+        override fun convert(
+            holder: ItemViewHolder,
+            binding: Item1lineTextAndDelBinding,
+            item: KeyboardAssist,
+            payloads: MutableList<Any>
+        ) {
+            binding.textView.text = item.key
+        }
+
+        override fun registerListener(holder: ItemViewHolder, binding: Item1lineTextAndDelBinding) {
+            binding.ivDelete.setOnClickListener {
+                getItemByLayoutPosition(holder.layoutPosition)?.let { keyboardAssist ->
+                    editKey(keyboardAssist)
+                }
+            }
+        }
+
+        override fun swap(srcPosition: Int, targetPosition: Int): Boolean {
+            swapItem(srcPosition, targetPosition)
+            isMoved = true
+            return true
+        }
+
+        override fun onClearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
+            if (isMoved) {
+                for ((index, item) in getItems().withIndex()) {
+                    item.serialNo = index + 1
+                }
+                launch(IO) {
+                    appDb.keyboardAssistsDao.update(*getItems().toTypedArray())
+                }
+            }
+            isMoved = false
+        }
+    }
+}

+ 29 - 8
app/src/main/java/io/legado/app/ui/widget/KeyboardToolPop.kt → app/src/main/java/io/legado/app/ui/widget/keyboard/KeyboardToolPop.kt

@@ -1,20 +1,23 @@
-package io.legado.app.ui.widget
+package io.legado.app.ui.widget.keyboard
 
 
 import android.content.Context
 import android.content.Context
 import android.graphics.Rect
 import android.graphics.Rect
 import android.view.*
 import android.view.*
 import android.widget.PopupWindow
 import android.widget.PopupWindow
+import io.legado.app.R
 import io.legado.app.base.adapter.ItemViewHolder
 import io.legado.app.base.adapter.ItemViewHolder
 import io.legado.app.base.adapter.RecyclerAdapter
 import io.legado.app.base.adapter.RecyclerAdapter
 import io.legado.app.data.appDb
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.KeyboardAssist
 import io.legado.app.data.entities.KeyboardAssist
 import io.legado.app.databinding.ItemFilletTextBinding
 import io.legado.app.databinding.ItemFilletTextBinding
 import io.legado.app.databinding.PopupKeyboardToolBinding
 import io.legado.app.databinding.PopupKeyboardToolBinding
+import io.legado.app.lib.dialogs.SelectItem
+import io.legado.app.lib.dialogs.selector
+import io.legado.app.utils.activity
+import io.legado.app.utils.showDialogFragment
 import io.legado.app.utils.windowSize
 import io.legado.app.utils.windowSize
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
 import splitties.systemservices.layoutInflater
 import splitties.systemservices.layoutInflater
 import splitties.systemservices.windowManager
 import splitties.systemservices.windowManager
 import kotlin.math.abs
 import kotlin.math.abs
@@ -83,7 +86,7 @@ class KeyboardToolPop(
             ItemFilletTextBinding.inflate(context.layoutInflater, it, false).apply {
             ItemFilletTextBinding.inflate(context.layoutInflater, it, false).apply {
                 textView.text = helpChar
                 textView.text = helpChar
                 root.setOnClickListener {
                 root.setOnClickListener {
-                    callBack.keyboardHelp()
+                    helpAlert()
                 }
                 }
             }
             }
         }
         }
@@ -92,13 +95,29 @@ class KeyboardToolPop(
     @Suppress("MemberVisibilityCanBePrivate")
     @Suppress("MemberVisibilityCanBePrivate")
     fun upAdapterData() {
     fun upAdapterData() {
         scope.launch {
         scope.launch {
-            val items = withContext(IO) {
-                appDb.keyboardAssistsDao.getOrDefault()
+            appDb.keyboardAssistsDao.flowByType(0).collect {
+                adapter.setItems(it)
             }
             }
-            adapter.setItems(items)
         }
         }
     }
     }
 
 
+    private fun helpAlert() {
+        val items = arrayListOf(
+            SelectItem(context.getString(R.string.assists_key_config), "keyConfig")
+        )
+        items.addAll(callBack.helpActions())
+        context.selector(context.getString(R.string.help), items) { _, selectItem, i ->
+            when (selectItem.value) {
+                "keyConfig" -> config()
+                else -> callBack.onHelpActionSelect(selectItem.value)
+            }
+        }
+    }
+
+    private fun config() {
+        contentView.activity?.showDialogFragment<KeyboardAssistsConfig>()
+    }
+
     inner class Adapter(context: Context) :
     inner class Adapter(context: Context) :
         RecyclerAdapter<KeyboardAssist, ItemFilletTextBinding>(context) {
         RecyclerAdapter<KeyboardAssist, ItemFilletTextBinding>(context) {
 
 
@@ -130,7 +149,9 @@ class KeyboardToolPop(
 
 
     interface CallBack {
     interface CallBack {
 
 
-        fun keyboardHelp()
+        fun helpActions(): List<SelectItem<String>> = arrayListOf()
+
+        fun onHelpActionSelect(action: String)
 
 
         fun sendText(text: String)
         fun sendText(text: String)
 
 

+ 45 - 0
app/src/main/res/layout/dialog_multiple_edit_text.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:overScrollMode="ifContentScrolls"
+    android:paddingLeft="16dp"
+    android:paddingRight="16dp">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <io.legado.app.ui.widget.text.TextInputLayout
+            android:id="@+id/layout_1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <io.legado.app.ui.widget.text.AutoCompleteTextView
+                android:id="@+id/edit_1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
+
+        </io.legado.app.ui.widget.text.TextInputLayout>
+
+        <io.legado.app.ui.widget.text.TextInputLayout
+            android:id="@+id/layout_2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:visibility="gone">
+
+            <io.legado.app.ui.widget.text.AutoCompleteTextView
+                android:id="@+id/edit_2"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck" />
+
+        </io.legado.app.ui.widget.text.TextInputLayout>
+
+
+    </LinearLayout>
+
+</androidx.core.widget.NestedScrollView>

+ 11 - 0
app/src/main/res/menu/keyboard_assists_config.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:id="@+id/menu_add"
+        android:icon="@drawable/ic_add"
+        android:title="@string/add"
+        app:showAsAction="always" />
+
+</menu>

+ 1 - 0
app/src/main/res/values-es-rES/strings.xml

@@ -955,5 +955,6 @@
     <string name="show_icon">显示图标</string>
     <string name="show_icon">显示图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="cache_export">缓存/导出</string>
     <string name="cache_export">缓存/导出</string>
+    <string name="assists_key_config">辅助按键配置</string>
     <!-- string end -->
     <!-- string end -->
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-ja-rJP/strings.xml

@@ -958,5 +958,6 @@
     <string name="show_icon">显示图标</string>
     <string name="show_icon">显示图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="cache_export">缓存/导出</string>
     <string name="cache_export">缓存/导出</string>
+    <string name="assists_key_config">辅助按键配置</string>
     <!-- string end -->
     <!-- string end -->
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-pt-rBR/strings.xml

@@ -958,5 +958,6 @@
     <string name="show_icon">显示图标</string>
     <string name="show_icon">显示图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="cache_export">缓存/导出</string>
     <string name="cache_export">缓存/导出</string>
+    <string name="assists_key_config">辅助按键配置</string>
     <!-- string end -->
     <!-- string end -->
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-zh-rHK/strings.xml

@@ -955,5 +955,6 @@
     <string name="show_icon">显示图标</string>
     <string name="show_icon">显示图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="cache_export">缓存/导出</string>
     <string name="cache_export">缓存/导出</string>
+    <string name="assists_key_config">辅助按键配置</string>
     <!-- string end -->
     <!-- string end -->
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-zh-rTW/strings.xml

@@ -957,5 +957,6 @@
     <string name="show_icon">显示图标</string>
     <string name="show_icon">显示图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="cache_export">缓存/导出</string>
     <string name="cache_export">缓存/导出</string>
+    <string name="assists_key_config">辅助按键配置</string>
     <!-- string end -->
     <!-- string end -->
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values-zh/strings.xml

@@ -957,5 +957,6 @@
     <string name="show_icon">显示图标</string>
     <string name="show_icon">显示图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="cache_export">缓存/导出</string>
     <string name="cache_export">缓存/导出</string>
+    <string name="assists_key_config">辅助按键配置</string>
     <!-- string end -->
     <!-- string end -->
 </resources>
 </resources>

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -958,5 +958,6 @@
     <string name="show_icon">显示图标</string>
     <string name="show_icon">显示图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="show_default_book_icon">显示默认书籍图标</string>
     <string name="cache_export">缓存/导出</string>
     <string name="cache_export">缓存/导出</string>
+    <string name="assists_key_config">辅助按键配置</string>
     <!-- string end -->
     <!-- string end -->
 </resources>
 </resources>