zcash-android-wallet/app/src/main/java/cash/z/ecc/android/ui/setup/SeedWordAdapter.kt

104 lines
3.9 KiB
Kotlin

package com.tylersuehr.chips
import android.content.Context
import android.text.TextUtils
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import cash.z.ecc.android.R
import cash.z.ecc.android.ext.toAppColor
import cash.z.ecc.android.ui.setup.SeedWordChip
class SeedWordAdapter : ChipsAdapter {
constructor(existingAdapter: ChipsAdapter) : super(existingAdapter.mDataSource, existingAdapter.mEditText, existingAdapter.mOptions)
val editText = mEditText
private var onDataSetChangedListener: (() -> Unit)? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == CHIP) SeedWordHolder(SeedWordChipView(parent.context))
else object : RecyclerView.ViewHolder(mEditText) {}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (getItemViewType(position) == CHIP) { // Chips
// Display the chip information on the chip view
(holder as SeedWordHolder).seedChipView.bind(mDataSource.getSelectedChip(position), position)
} else {
val size = mDataSource.selectedChips.size
// tricky bugfix:
// keep this always enabled otherwise older versions of android crash when this
// view is given focus. As a work around, just hide the cursor when the user is done
// editing. This is not ideal but it's better than a crash during wallet restore!
mEditText.isEnabled = true
mEditText.hint = if (size < 3) {
mEditText.isCursorVisible = true
mEditText.setHintTextColor(R.color.text_light_dimmed.toAppColor())
val ordinal = when (size) { 2 -> "3rd"; 1 -> "2nd"; else -> "1st" }
"Enter $ordinal seed word"
} else if (size >= 24) {
mEditText.setHintTextColor(R.color.zcashGreen.toAppColor())
mEditText.isCursorVisible = false
"done"
} else {
mEditText.isCursorVisible = true
mEditText.setHintTextColor(R.color.zcashYellow.toAppColor())
"${size + 1}"
}
}
}
override fun onChipDataSourceChanged() {
super.onChipDataSourceChanged()
onDataSetChangedListener?.invoke()
}
fun onDataSetChanged(block: () -> Unit): SeedWordAdapter {
onDataSetChangedListener = block
return this
}
override fun onKeyboardActionDone(text: String?) {
if (TextUtils.isEmpty(text)) return
if (mDataSource.originalChips.firstOrNull { it.title == text } != null) {
mDataSource.addSelectedChip(DefaultCustomChip(text))
mEditText.apply {
postDelayed(
{
setText("")
requestFocus()
},
50L
)
}
}
}
// this function is called with the contents of the field, split by the delimiter
override fun onKeyboardDelimiter(text: String) {
val firstMatchingWord = (mDataSource.filteredChips.firstOrNull() as? SeedWordChip)?.word?.takeUnless {
!it.startsWith(text)
}
if (firstMatchingWord != null) {
onKeyboardActionDone(firstMatchingWord)
} else {
onKeyboardActionDone(text)
}
}
private inner class SeedWordHolder(chipView: SeedWordChipView) : ChipsAdapter.ChipHolder(chipView) {
val seedChipView = super.chipView as SeedWordChipView
}
private inner class SeedWordChipView(context: Context) : ChipView(context) {
private val indexView: TextView = findViewById(R.id.chip_index)
fun bind(chip: Chip, index: Int) {
super.inflateFromChip(chip)
indexView.text = (index + 1).toString()
}
}
}