|
|
@@ -4,90 +4,36 @@ import android.annotation.SuppressLint
|
|
|
import android.content.Context
|
|
|
import android.util.AttributeSet
|
|
|
import android.view.View
|
|
|
-import androidx.recyclerview.widget.RecyclerView
|
|
|
import com.atmob.keyboard_android.R
|
|
|
import com.atmob.keyboard_android.component.base.BaseUIComponent
|
|
|
-import com.atmob.keyboard_android.component.base.FakeComponent
|
|
|
import com.atmob.keyboard_android.component.base.RouteComponent
|
|
|
-import com.atmob.keyboard_android.component.child.IAiChatComponent
|
|
|
import com.atmob.keyboard_android.component.child.IAiKeyboardComponent
|
|
|
-import com.atmob.keyboard_android.component.item.AiKeyboardKeyViewBinder
|
|
|
-import com.atmob.keyboard_android.constant.Constants
|
|
|
import com.atmob.keyboard_android.enums.HelpMode
|
|
|
import com.atmob.keyboard_android.enums.KeyboardGlobalType
|
|
|
-import com.atmob.keyboard_android.ext.click
|
|
|
-import com.atmob.keyboard_android.ext.setGone
|
|
|
-import com.atmob.keyboard_android.ext.setVisible
|
|
|
-import com.atmob.keyboard_android.model.AiKeyboardKeyModel
|
|
|
-import com.atmob.keyboard_android.util.InputMethodUtil
|
|
|
import com.atmob.keyboard_android.util.KeyboardHolder
|
|
|
-import com.atmob.keyboard_android.util.LogUtil
|
|
|
-import com.atmob.keyboard_android.util.UserInfoHelper
|
|
|
-import com.atmob.keyboard_android.util.recyclerview.GridDivider
|
|
|
-import com.atmob.keyboard_android.widget.LongTouchContainer
|
|
|
-import com.atmob.keyboard_android.widget.indicator.TabPagerTitleView
|
|
|
-import com.blankj.utilcode.util.ConvertUtils
|
|
|
-import com.blankj.utilcode.util.ToastUtils
|
|
|
-import com.gcssloop.widget.PagerGridLayoutManager
|
|
|
-import com.gcssloop.widget.PagerGridLayoutManager.PageListener
|
|
|
-import com.gcssloop.widget.PagerGridSnapHelper
|
|
|
-import me.drakeet.multitype.Items
|
|
|
-import me.drakeet.multitype.MultiTypeAdapter
|
|
|
-import net.lucode.hackware.magicindicator.MagicIndicator
|
|
|
-import net.lucode.hackware.magicindicator.buildins.UIUtil
|
|
|
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.CommonNavigator
|
|
|
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.CommonNavigatorAdapter
|
|
|
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerIndicator
|
|
|
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.abs.IPagerTitleView
|
|
|
-import net.lucode.hackware.magicindicator.buildins.commonnavigator.indicators.LinePagerIndicator
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * AI键盘组件
|
|
|
+ * AI键盘组件,里面包含2个组件,分别为通用类型键盘面板、开场白类型键盘面板
|
|
|
*/
|
|
|
class AiKeyboardComponent @JvmOverloads constructor(
|
|
|
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
|
|
) : BaseUIComponent<IAiKeyboardComponent>(context, attrs, defStyleAttr), IAiKeyboardComponent {
|
|
|
- private lateinit var vTabBarLayout: View
|
|
|
- private lateinit var vMagicIndicator: MagicIndicator
|
|
|
- private lateinit var vKeyboardKeyContent: View
|
|
|
- private lateinit var vRouteComponent: RouteComponent
|
|
|
- private lateinit var vPasteBarLayout: View
|
|
|
- private lateinit var vKeyList: RecyclerView
|
|
|
- private lateinit var vPasteBtn: View
|
|
|
- private lateinit var vDeleteBtn: LongTouchContainer
|
|
|
- private lateinit var vClearBtn: View
|
|
|
- private lateinit var vSendBtn: View
|
|
|
-
|
|
|
- private lateinit var mKeyListItems: Items
|
|
|
- private lateinit var mKeyListAdapter: MultiTypeAdapter
|
|
|
-
|
|
|
- /**
|
|
|
- * Tab列表
|
|
|
- */
|
|
|
- private lateinit var mTabList: MutableList<String>
|
|
|
+ private lateinit var vAiKeyboardRouteComponent: RouteComponent
|
|
|
+ private lateinit var vCommonPanel: AiKeyboardCommonPanelComponent
|
|
|
+ private lateinit var vProloguePanel: AiKeyboardProloguePanelComponent
|
|
|
|
|
|
override fun onInflateViewId(): Int {
|
|
|
return R.layout.component_ai_keyboard
|
|
|
}
|
|
|
|
|
|
override fun findView(view: View) {
|
|
|
- vTabBarLayout = view.findViewById(R.id.tar_bar_layout)
|
|
|
- vMagicIndicator = view.findViewById(R.id.magic_indicator)
|
|
|
- vKeyboardKeyContent = view.findViewById(R.id.keyboard_key_content)
|
|
|
- vRouteComponent = view.findViewById(R.id.route_component)
|
|
|
- vPasteBarLayout = view.findViewById(R.id.paste_bar_layout)
|
|
|
- vKeyList = view.findViewById(R.id.key_list)
|
|
|
- vPasteBtn = view.findViewById(R.id.paste_btn)
|
|
|
- vDeleteBtn = view.findViewById(R.id.delete_btn)
|
|
|
- vClearBtn = view.findViewById(R.id.clear_btn)
|
|
|
- vSendBtn = view.findViewById(R.id.send_btn)
|
|
|
+ vAiKeyboardRouteComponent = view.findViewById(R.id.ai_keyboard_route_component)
|
|
|
+ vCommonPanel = view.findViewById(R.id.common_panel)
|
|
|
+ vProloguePanel = view.findViewById(R.id.prologue_panel)
|
|
|
}
|
|
|
|
|
|
override fun bindView(view: View) {
|
|
|
- setupTabBar()
|
|
|
- setupKeyList()
|
|
|
- setupActionBtn()
|
|
|
setupViewModel()
|
|
|
setData()
|
|
|
}
|
|
|
@@ -97,188 +43,11 @@ class AiKeyboardComponent @JvmOverloads constructor(
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 配置Tab栏
|
|
|
- */
|
|
|
- private fun setupTabBar() {
|
|
|
- // 初始化Tab列表
|
|
|
- mTabList = mutableListOf()
|
|
|
-
|
|
|
- // 配置指示器
|
|
|
- vMagicIndicator.setNavigator(CommonNavigator(context).apply {
|
|
|
- scrollPivotX = 0.35f
|
|
|
- // 设置适配器
|
|
|
- setAdapter(object : CommonNavigatorAdapter() {
|
|
|
- override fun getCount(): Int {
|
|
|
- return mTabList.size
|
|
|
- }
|
|
|
-
|
|
|
- override fun getTitleView(context: Context, index: Int): IPagerTitleView {
|
|
|
- val titleView = object : TabPagerTitleView(context) {
|
|
|
- override fun onSelected(index: Int, totalCount: Int) {
|
|
|
- super.onSelected(index, totalCount)
|
|
|
- // 选中Tab,设置为粗体
|
|
|
- setBoldStyle(true)
|
|
|
- }
|
|
|
-
|
|
|
- override fun onDeselected(index: Int, totalCount: Int) {
|
|
|
- super.onDeselected(index, totalCount)
|
|
|
- // 不选中Tab,设置为普通体
|
|
|
- setBoldStyle(false)
|
|
|
- }
|
|
|
- }
|
|
|
- // Tab文字
|
|
|
- titleView.setText(mTabList[index])
|
|
|
- // Tab未选中时的字体颜色
|
|
|
- titleView.setTextColor(context.resources.getColor(R.color.text_color_secondary))
|
|
|
- // Tab选中时的字体颜色
|
|
|
- titleView.setClipColor(context.resources.getColor(R.color.text_color_primary))
|
|
|
- // 字体大小
|
|
|
- titleView.textSize = ConvertUtils.dp2px(12f).toFloat()
|
|
|
- // 设置padding,让文字距离背景有一定间距
|
|
|
- val paddingHorizontal = ConvertUtils.dp2px(18f)
|
|
|
- titleView.setPadding(paddingHorizontal, 0, paddingHorizontal, 0)
|
|
|
- // 点击Tab,切换页面
|
|
|
- titleView.setOnClickListener(object : OnClickListener {
|
|
|
- override fun onClick(v: View?) {
|
|
|
- // 更新Tab
|
|
|
- val newTab = mTabList[index]
|
|
|
- KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
|
|
|
- ?.updateCurrentPrologueTab(newTab)
|
|
|
- }
|
|
|
- })
|
|
|
- return titleView
|
|
|
- }
|
|
|
-
|
|
|
- override fun getIndicator(context: Context): IPagerIndicator {
|
|
|
- val indicator = LinePagerIndicator(context)
|
|
|
- val navigatorHeight =
|
|
|
- context.resources.getDimension(R.dimen.common_navigator_height)
|
|
|
- val borderWidth = UIUtil.dip2px(context, 1.0).toFloat()
|
|
|
- val lineHeight = navigatorHeight - 2 * borderWidth
|
|
|
- indicator.lineHeight = lineHeight
|
|
|
- indicator.roundRadius = lineHeight / 2
|
|
|
- indicator.yOffset = borderWidth
|
|
|
- // 指示器的背景颜色
|
|
|
- indicator.setColors(context.resources.getColor(R.color.bg_tab_indicator_selected))
|
|
|
- return indicator
|
|
|
- }
|
|
|
- })
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置列表
|
|
|
- */
|
|
|
- private fun setupKeyList() {
|
|
|
- vKeyList.apply {
|
|
|
- mKeyListItems = Items()
|
|
|
- mKeyListAdapter = MultiTypeAdapter(mKeyListItems).apply {
|
|
|
- register(AiKeyboardKeyModel::class.java, AiKeyboardKeyViewBinder {
|
|
|
- // 点击键盘按键,打开AI生成内容面板
|
|
|
- if (it.isVip) {
|
|
|
- // 检查是否VIP
|
|
|
- UserInfoHelper.checkVip {
|
|
|
- controlAiChatPageShowing(true)
|
|
|
- LogUtil.d("Ai键盘,已经是VIP,打开Ai内容面板")
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 不需要VIP,直接打开
|
|
|
- controlAiChatPageShowing(true)
|
|
|
- LogUtil.d("Ai键盘,不需要VIP,直接打开Ai内容面板")
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- // 水平分页布局管理器
|
|
|
- layoutManager = PagerGridLayoutManager(
|
|
|
- Constants.AI_KEYBOARD_KEY_LIST_SPAN_COUNT,
|
|
|
- Constants.AI_KEYBOARD_KEY_LIST_SPAN_COUNT,
|
|
|
- PagerGridLayoutManager.HORIZONTAL
|
|
|
- ).apply {
|
|
|
- // 设置滚动监听
|
|
|
- setPageListener(object : PageListener {
|
|
|
- override fun onPageSizeChanged(pageSize: Int) {
|
|
|
- // 当总页数确定时的回调
|
|
|
- }
|
|
|
-
|
|
|
- override fun onPageSelect(pageIndex: Int) {
|
|
|
- // 当页面被选中时的回调(从 0 开始)
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- // 设置滚动辅助工具
|
|
|
- val pageSnapHelper = PagerGridSnapHelper().apply {
|
|
|
- // 设置滚动阀值
|
|
|
- setFlingThreshold(minFlingVelocity)
|
|
|
- }
|
|
|
- pageSnapHelper.attachToRecyclerView(this)
|
|
|
- // 设置适配器
|
|
|
- adapter = mKeyListAdapter
|
|
|
- // 添加分割线
|
|
|
- addItemDecoration(
|
|
|
- GridDivider(
|
|
|
- Constants.AI_KEYBOARD_KEY_LIST_SPAN_COUNT,
|
|
|
- ConvertUtils.dp2px(6f)
|
|
|
- )
|
|
|
- )
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置操作按钮
|
|
|
- */
|
|
|
- @SuppressLint("ClickableViewAccessibility")
|
|
|
- private fun setupActionBtn() {
|
|
|
- // 粘贴
|
|
|
- vPasteBtn.click {
|
|
|
- val text = KeyboardHolder.getKeyboardService()
|
|
|
- ?.getKeyboardViewModel()?.userClipboardData?.value ?: ""
|
|
|
- if (text.isBlank()) {
|
|
|
- return@click
|
|
|
- }
|
|
|
- KeyboardHolder.getKeyboardService()?.asInputMethodService()?.let {
|
|
|
- InputMethodUtil.inputText(it.currentInputConnection, text)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 删除
|
|
|
- vDeleteBtn.setOnLongPressListener {
|
|
|
- KeyboardHolder.getKeyboardService()?.asInputMethodService()?.let {
|
|
|
- InputMethodUtil.deleteInput(it.currentInputConnection)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 清空
|
|
|
- vClearBtn.click {
|
|
|
- KeyboardHolder.getKeyboardService()?.asInputMethodService()?.let {
|
|
|
- InputMethodUtil.clearInput(it.currentInputConnection)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 发送
|
|
|
- vSendBtn.click {
|
|
|
- KeyboardHolder.getKeyboardService()?.asInputMethodService()?.let {
|
|
|
- InputMethodUtil.clickSendBtn(it.currentInputConnection)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
* 配置ViewModel
|
|
|
*/
|
|
|
private fun setupViewModel() {
|
|
|
KeyboardHolder.getKeyboardService()?.run {
|
|
|
- // 监听开场白列表更新
|
|
|
- getKeyboardViewModel().prologueList.observe(getLifecycleOwner()) { list ->
|
|
|
- // 更新Tab列表
|
|
|
- mTabList.clear()
|
|
|
- mTabList.addAll(list.map {
|
|
|
- it.title
|
|
|
- }.toList())
|
|
|
- // 刷新Tab栏
|
|
|
- vMagicIndicator.navigator.notifyDataSetChanged()
|
|
|
- LogUtil.d("开场白列表更新,刷新Tab栏...")
|
|
|
- }
|
|
|
- // 监听键盘类型切换
|
|
|
+ // 监听全局键盘类型切换
|
|
|
getKeyboardViewModel().keyboardGlobalType.observe(getLifecycleOwner()) { globalKeyboardType ->
|
|
|
if (KeyboardGlobalType.AI_KEYBOARD == globalKeyboardType) {
|
|
|
show()
|
|
|
@@ -291,25 +60,6 @@ class AiKeyboardComponent @JvmOverloads constructor(
|
|
|
// 切换键盘
|
|
|
updateKeyboardByHelpMode(newMode)
|
|
|
}
|
|
|
- // 监听Tab切换,更新键盘列表
|
|
|
- getKeyboardViewModel().currentPrologueTab.observe(getLifecycleOwner()) { newTab ->
|
|
|
- // 切换Tab
|
|
|
- vMagicIndicator.onPageSelected(mTabList.indexOf(newTab))
|
|
|
- // 关闭Ai内容生成面板
|
|
|
- controlAiChatPageShowing(false)
|
|
|
- // 根据Tab,重新加载数据
|
|
|
- loadKeyListByTab(newTab)
|
|
|
- }
|
|
|
- // 监听Ai内容生成页,是否显示
|
|
|
- getKeyboardViewModel().aiChatPageShowing.observe(getLifecycleOwner()) { isShowing ->
|
|
|
- // 显示Ai内容生成页,隐藏键盘列表
|
|
|
- if (isShowing) {
|
|
|
- vKeyList.setGone()
|
|
|
- } else {
|
|
|
- // Ai生成页关闭,则显示键盘列表
|
|
|
- vKeyList.setVisible()
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -318,63 +68,6 @@ class AiKeyboardComponent @JvmOverloads constructor(
|
|
|
*/
|
|
|
@SuppressLint("NotifyDataSetChanged")
|
|
|
private fun setData() {
|
|
|
- KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()?.getPrologueList(onFail = {
|
|
|
- ToastUtils.showShort(it)
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据选择的帮助模式,加载按键列表
|
|
|
- */
|
|
|
- @SuppressLint("NotifyDataSetChanged")
|
|
|
- private fun loadKeyListByHelpMode(helpMode: HelpMode) {
|
|
|
- // 开场白
|
|
|
- if (HelpMode.OPEN_REMARKS == helpMode) {
|
|
|
- val currentTab = KeyboardHolder.getKeyboardService()
|
|
|
- ?.getKeyboardViewModel()?.currentPrologueTab?.value ?: ""
|
|
|
- if (currentTab.isBlank()) {
|
|
|
- return
|
|
|
- }
|
|
|
- loadKeyListByTab(currentTab)
|
|
|
- } else {
|
|
|
- // 其他类型
|
|
|
- KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
|
|
|
- ?.getCharacterList(onSuccess = {
|
|
|
- val newList = (it.characterInfos ?: listOf()).map {
|
|
|
- AiKeyboardKeyModel(
|
|
|
- // 显示的文本 = 表情 + 名字
|
|
|
- text = "${it.emoji} ${it.name}",
|
|
|
- // 是否需要VIP
|
|
|
- isVip = it.isVip
|
|
|
- )
|
|
|
- }
|
|
|
- mKeyListItems.clear()
|
|
|
- mKeyListItems.addAll(newList)
|
|
|
- mKeyListAdapter.notifyDataSetChanged()
|
|
|
- }, onFail = {
|
|
|
- ToastUtils.showShort(it)
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据Tab,加载按键列表
|
|
|
- */
|
|
|
- @SuppressLint("NotifyDataSetChanged")
|
|
|
- private fun loadKeyListByTab(tab: String) {
|
|
|
- val list = KeyboardHolder.getKeyboardService()?.getKeyboardViewModel()
|
|
|
- ?.filterPrologueListByTab(tab) ?: listOf()
|
|
|
- val newList = list.map {
|
|
|
- AiKeyboardKeyModel(
|
|
|
- // 显示的文本 = 名字
|
|
|
- text = it.name,
|
|
|
- // 是否需要VIP
|
|
|
- isVip = false
|
|
|
- )
|
|
|
- }.toList()
|
|
|
- mKeyListItems.clear()
|
|
|
- mKeyListItems.addAll(newList)
|
|
|
- mKeyListAdapter.notifyDataSetChanged()
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -383,30 +76,13 @@ class AiKeyboardComponent @JvmOverloads constructor(
|
|
|
private fun updateKeyboardByHelpMode(helpMode: HelpMode) {
|
|
|
// 根据不同的模式,切换不同的键盘
|
|
|
if (HelpMode.OPEN_REMARKS == helpMode) {
|
|
|
- // 开场白,显示Tab布局,隐藏粘贴栏
|
|
|
- vTabBarLayout.setVisible()
|
|
|
- vPasteBarLayout.setGone()
|
|
|
- } else {
|
|
|
- // 其他模式,隐藏Tab布局,显示粘贴栏
|
|
|
- vTabBarLayout.setGone()
|
|
|
- vPasteBarLayout.setVisible()
|
|
|
- }
|
|
|
- // 隐藏AI生成内容面板
|
|
|
- controlAiChatPageShowing(false)
|
|
|
- // 重新加载按键列表
|
|
|
- loadKeyListByHelpMode(helpMode)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 控制Ai生成内容面板,是否显示
|
|
|
- */
|
|
|
- private fun controlAiChatPageShowing(isShow: Boolean) {
|
|
|
- // 切换到Ai生成内容页
|
|
|
- if (isShow) {
|
|
|
- vRouteComponent.routeChildComponent(IAiChatComponent::class.java)
|
|
|
+ // 开场白模式
|
|
|
+ vCommonPanel.hide()
|
|
|
+ vProloguePanel.show()
|
|
|
} else {
|
|
|
- // 切换回键盘页
|
|
|
- vRouteComponent.routeChildComponent(FakeComponent::class.java, true)
|
|
|
+ // 其他模式
|
|
|
+ vCommonPanel.show()
|
|
|
+ vProloguePanel.hide()
|
|
|
}
|
|
|
}
|
|
|
}
|