231 lines
7.3 KiB
Kotlin
231 lines
7.3 KiB
Kotlin
package jp.juggler.subwaytooter
|
|
|
|
import android.content.Context
|
|
import android.media.Ringtone
|
|
import android.media.RingtoneManager
|
|
import android.net.Uri
|
|
import android.os.Bundle
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import android.widget.AdapterView
|
|
import android.widget.BaseAdapter
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import jp.juggler.subwaytooter.databinding.ActHighlightListBinding
|
|
import jp.juggler.subwaytooter.databinding.LvHighlightWordBinding
|
|
import jp.juggler.subwaytooter.dialog.DlgConfirm.confirm
|
|
import jp.juggler.subwaytooter.table.HighlightWord
|
|
import jp.juggler.subwaytooter.table.daoHighlightWord
|
|
import jp.juggler.util.coroutine.AppDispatchers
|
|
import jp.juggler.util.coroutine.launchAndShowError
|
|
import jp.juggler.util.data.cast
|
|
import jp.juggler.util.data.mayUri
|
|
import jp.juggler.util.data.notBlank
|
|
import jp.juggler.util.data.notZero
|
|
import jp.juggler.util.log.LogCategory
|
|
import jp.juggler.util.ui.*
|
|
import kotlinx.coroutines.withContext
|
|
import java.lang.ref.WeakReference
|
|
|
|
class ActHighlightWordList : AppCompatActivity() {
|
|
|
|
companion object {
|
|
private val log = LogCategory("ActHighlightWordList")
|
|
|
|
private var lastRingtone: WeakReference<Ringtone>? = null
|
|
|
|
private fun stopLastRingtone() {
|
|
try {
|
|
lastRingtone?.get()?.stop()
|
|
} catch (ex: Throwable) {
|
|
log.e(ex, "stopLastRingtone failed.")
|
|
} finally {
|
|
lastRingtone = null
|
|
}
|
|
}
|
|
|
|
private fun tryRingTone(context: Context, uri: Uri?): Boolean {
|
|
try {
|
|
uri?.let { RingtoneManager.getRingtone(context, it) }
|
|
?.let { ringtone ->
|
|
stopLastRingtone()
|
|
lastRingtone = WeakReference(ringtone)
|
|
ringtone.play()
|
|
return true
|
|
}
|
|
} catch (ex: Throwable) {
|
|
log.e(ex, "tryRingTone failed.")
|
|
}
|
|
// fall null case
|
|
return false
|
|
}
|
|
|
|
fun sound(context: Context, item: HighlightWord?) {
|
|
if (lastRingtone?.get()?.isPlaying == true) {
|
|
stopLastRingtone()
|
|
return
|
|
}
|
|
|
|
item ?: return
|
|
val soundType = item.sound_type
|
|
when {
|
|
// サウンドなし
|
|
soundType == HighlightWord.SOUND_TYPE_NONE -> Unit
|
|
|
|
// カスタムサウンドを鳴らせた
|
|
soundType == HighlightWord.SOUND_TYPE_CUSTOM && tryRingTone(
|
|
context,
|
|
item.sound_uri.mayUri()
|
|
) -> Unit
|
|
|
|
// 失敗した場合も通常の音を鳴らす
|
|
else -> tryRingTone(
|
|
context,
|
|
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
private val views by lazy {
|
|
ActHighlightListBinding.inflate(layoutInflater)
|
|
}
|
|
|
|
private lateinit var listAdapter: MyListAdapter
|
|
|
|
private val arEdit = ActivityResultHandler(log) { r ->
|
|
if (r.isNotOk) return@ActivityResultHandler
|
|
loadData()
|
|
}
|
|
|
|
// @Override public void onBackPressed(){
|
|
// setResult( RESULT_OK );
|
|
// super.onBackPressed();
|
|
// }
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
arEdit.register(this)
|
|
App1.setActivityTheme(this)
|
|
initUI()
|
|
loadData()
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
super.onDestroy()
|
|
stopLastRingtone()
|
|
}
|
|
|
|
private fun initUI() {
|
|
setContentView(views.root)
|
|
setSupportActionBar(views.toolbar)
|
|
setNavigationBack(views.toolbar)
|
|
fixHorizontalMargin(views.llContent)
|
|
|
|
// リストのアダプター
|
|
listAdapter = MyListAdapter()
|
|
|
|
// ハンドル部分をドラッグで並べ替えできるRecyclerView
|
|
|
|
views.listView.adapter = listAdapter
|
|
views.listView.onItemClickListener = listAdapter
|
|
views.btnAdd.setOnClickListener { create() }
|
|
}
|
|
|
|
private fun loadData() {
|
|
launchAndShowError {
|
|
listAdapter.items = withContext(AppDispatchers.IO) {
|
|
daoHighlightWord.listAll()
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun create() {
|
|
arEdit.launch(ActHighlightWordEdit.createIntent(this, ""))
|
|
}
|
|
|
|
private fun edit(item: HighlightWord?) {
|
|
item ?: return
|
|
arEdit.launch(ActHighlightWordEdit.createIntent(this, item.id))
|
|
}
|
|
|
|
private fun delete(item: HighlightWord?) {
|
|
item ?: return
|
|
val activity = this
|
|
launchAndShowError {
|
|
confirm(getString(R.string.delete_confirm, item.name))
|
|
daoHighlightWord.delete(applicationContext, item)
|
|
listAdapter.remove(item)
|
|
App1.getAppState(activity).enableSpeech()
|
|
}
|
|
}
|
|
|
|
private fun speech(item: HighlightWord?) {
|
|
item?.name?.notBlank()?.let {
|
|
App1.getAppState(this@ActHighlightWordList)
|
|
.addSpeech(it, dedupMode = DedupMode.None)
|
|
}
|
|
}
|
|
|
|
// リスト要素のViewHolder
|
|
private inner class MyViewHolder(
|
|
parent: ViewGroup?,
|
|
) {
|
|
val views = LvHighlightWordBinding.inflate(layoutInflater, parent, false)
|
|
|
|
private var lastItem: HighlightWord? = null
|
|
|
|
init {
|
|
views.root.tag = this
|
|
views.btnSound.setOnClickListener { sound(this@ActHighlightWordList, lastItem) }
|
|
views.btnSpeech.setOnClickListener { speech(lastItem) }
|
|
views.btnDelete.setOnClickListener { delete(lastItem) }
|
|
}
|
|
|
|
fun bind(item: HighlightWord?) {
|
|
item ?: return
|
|
lastItem = item
|
|
|
|
views.tvName.text = item.name
|
|
views.tvName.setBackgroundColor(item.color_bg)
|
|
views.tvName.setTextColor(
|
|
item.color_fg.notZero()
|
|
?: attrColor(android.R.attr.textColorPrimary)
|
|
)
|
|
|
|
views.btnSound.isEnabledAlpha = item.sound_type != HighlightWord.SOUND_TYPE_NONE
|
|
views.btnSpeech.isEnabledAlpha = item.speech != 0
|
|
}
|
|
}
|
|
|
|
private inner class MyListAdapter : BaseAdapter(), AdapterView.OnItemClickListener {
|
|
|
|
var items: List<HighlightWord> = emptyList()
|
|
set(value) {
|
|
field = value
|
|
notifyDataSetChanged()
|
|
}
|
|
|
|
fun remove(item: HighlightWord) {
|
|
items = items.filter { it != item }
|
|
}
|
|
|
|
override fun getCount() = items.size
|
|
override fun getItem(position: Int) = items.elementAtOrNull(position)
|
|
override fun getItemId(position: Int) = 0L
|
|
|
|
override fun getView(position: Int, convertView: View?, parent: ViewGroup?) =
|
|
(convertView?.tag?.cast() ?: MyViewHolder(parent))
|
|
.also { it.bind(items.elementAtOrNull(position)) }
|
|
.views.root
|
|
|
|
override fun onItemClick(
|
|
parent: AdapterView<*>?,
|
|
view: View?,
|
|
position: Int,
|
|
id: Long,
|
|
) {
|
|
edit(items.elementAtOrNull(position))
|
|
}
|
|
}
|
|
}
|