SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/dialog/DlgDraftPicker.kt

201 lines
5.0 KiB
Kotlin

package jp.juggler.subwaytooter.dialog
import android.annotation.SuppressLint
import android.content.DialogInterface
import android.database.Cursor
import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.BaseAdapter
import android.widget.ListView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import jp.juggler.subwaytooter.ActPost
import jp.juggler.subwaytooter.R
import jp.juggler.subwaytooter.api.entity.TootStatus
import jp.juggler.subwaytooter.table.PostDraft
import jp.juggler.util.JsonObject
import jp.juggler.util.LogCategory
import jp.juggler.util.dismissSafe
import jp.juggler.util.showToast
import kotlinx.coroutines.*
class DlgDraftPicker : AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener,
DialogInterface.OnDismissListener {
companion object {
private val log = LogCategory("DlgDraftPicker")
}
private lateinit var activity : ActPost
private lateinit var callback : (draft : JsonObject) -> Unit
private lateinit var lvDraft : ListView
private lateinit var adapter : MyAdapter
private lateinit var dialog : AlertDialog
private var cursor : Cursor? = null
private var colIdx : PostDraft.ColIdx? = null
private var task : Job? = null
override fun onItemClick(parent : AdapterView<*>, view : View, position : Int, id : Long) {
val json = getPostDraft(position)?.json
if(json != null) {
callback(json)
dialog.dismissSafe()
}
}
override fun onItemLongClick(
parent : AdapterView<*>,
view : View,
position : Int,
id : Long
) : Boolean {
val draft = getPostDraft(position)
if(draft != null) {
activity.showToast(false, R.string.draft_deleted)
draft.delete()
reload()
return true
}
return false
}
override fun onDismiss(dialog : DialogInterface) {
task?.cancel()
task = null
lvDraft.adapter = null
cursor?.close()
}
@SuppressLint("InflateParams")
fun open(_activity : ActPost, _callback : (draft : JsonObject) -> Unit) {
this.activity = _activity
this.callback = _callback
adapter = MyAdapter()
val viewRoot = activity.layoutInflater.inflate(R.layout.dlg_draft_picker, null, false)
lvDraft = viewRoot.findViewById(R.id.lvDraft)
lvDraft.onItemClickListener = this
lvDraft.onItemLongClickListener = this
lvDraft.adapter = adapter
this.dialog = AlertDialog.Builder(activity)
.setTitle(R.string.select_draft)
.setNegativeButton(R.string.cancel, null)
.setView(viewRoot)
.create()
dialog.setOnDismissListener(this)
dialog.show()
reload()
}
private fun reload() {
// cancel old task
task?.cancel()
task = GlobalScope.launch(Dispatchers.Main) {
val cursor = try {
withContext(Dispatchers.IO) {
PostDraft.createCursor()
} ?: error("cursor is null")
} catch(ex : CancellationException) {
return@launch
} catch(ex : Throwable) {
log.trace(ex)
activity.showToast(ex, "failed to loading drafts.")
return@launch
}
if(! dialog.isShowing) {
// dialog is already closed.
cursor.close()
} else {
val old = this@DlgDraftPicker.cursor
this@DlgDraftPicker.cursor = cursor
colIdx = PostDraft.ColIdx(cursor)
adapter.notifyDataSetChanged()
old?.close()
}
}
}
private fun getPostDraft(position : Int) : PostDraft? {
val cursor = this.cursor
return if(cursor == null) null else PostDraft.loadFromCursor(cursor, colIdx, position)
}
private inner class MyViewHolder(view : View) {
val tvTime : TextView
val tvText : TextView
init {
tvTime = view.findViewById(R.id.tvTime)
tvText = view.findViewById(R.id.tvText)
}
fun bind(position : Int) {
val draft = getPostDraft(position) ?: return
tvTime.text = TootStatus.formatTime(tvTime.context, draft.time_save, false)
val json = draft.json
if(json != null) {
val cw = json.string(ActPost.DRAFT_CONTENT_WARNING)
val c = json.string(ActPost.DRAFT_CONTENT)
val sb = StringBuilder()
if(cw?.trim { it <= ' ' }?.isNotEmpty() == true) {
sb.append(cw)
}
if(c?.trim { it <= ' ' }?.isNotEmpty() == true) {
if(sb.isNotEmpty()) sb.append("\n")
sb.append(c)
}
tvText.text = sb
}
}
}
private inner class MyAdapter : BaseAdapter() {
override fun getCount() : Int {
return cursor?.count ?: 0
}
override fun getItem(position : Int) : Any? {
return getPostDraft(position)
}
override fun getItemId(position : Int) : Long {
return 0
}
override fun getView(position : Int, viewOld : View?, parent : ViewGroup) : View {
val view : View
val holder : MyViewHolder
if(viewOld == null) {
view = activity.layoutInflater.inflate(R.layout.lv_draft_picker, parent, false)
holder = MyViewHolder(view)
view.tag = holder
} else {
view = viewOld
holder = view.tag as MyViewHolder
}
holder.bind(position)
return view
}
}
}