2018-01-04 19:52:25 +01:00
|
|
|
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
|
2020-01-07 09:03:32 +01:00
|
|
|
import androidx.appcompat.app.AlertDialog
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.ActPost
|
|
|
|
import jp.juggler.subwaytooter.R
|
2021-06-28 09:09:00 +02:00
|
|
|
import jp.juggler.subwaytooter.actpost.DRAFT_CONTENT
|
|
|
|
import jp.juggler.subwaytooter.actpost.DRAFT_CONTENT_WARNING
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.api.entity.TootStatus
|
2022-07-20 06:27:19 +02:00
|
|
|
import jp.juggler.subwaytooter.global.appDispatchers
|
2018-01-04 19:52:25 +01:00
|
|
|
import jp.juggler.subwaytooter.table.PostDraft
|
2021-05-22 00:03:16 +02:00
|
|
|
import jp.juggler.util.*
|
2022-07-20 06:27:19 +02:00
|
|
|
import kotlinx.coroutines.CancellationException
|
|
|
|
import kotlinx.coroutines.Job
|
|
|
|
import kotlinx.coroutines.withContext
|
2018-01-04 19:52:25 +01:00
|
|
|
|
2019-09-12 15:43:11 +02:00
|
|
|
class DlgDraftPicker : AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener,
|
2020-12-17 04:17:48 +01:00
|
|
|
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(
|
2021-05-27 04:15:59 +02:00
|
|
|
parent: AdapterView<*>,
|
|
|
|
view: View,
|
|
|
|
position: Int,
|
2021-06-20 15:12:25 +02:00
|
|
|
id: Long,
|
2021-05-27 04:15:59 +02:00
|
|
|
): Boolean {
|
2020-12-17 04:17:48 +01:00
|
|
|
|
|
|
|
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")
|
2021-06-20 15:12:25 +02:00
|
|
|
fun open(activityArg: ActPost, callbackArg: (draft: JsonObject) -> Unit) {
|
|
|
|
this.activity = activityArg
|
|
|
|
this.callback = callbackArg
|
2020-12-17 04:17:48 +01:00
|
|
|
|
|
|
|
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 updateCursor(newCursor: Cursor?) {
|
|
|
|
if (!dialog.isShowing) {
|
|
|
|
// dialog is already closed.
|
|
|
|
newCursor?.close()
|
|
|
|
} else if (newCursor != null) {
|
|
|
|
val old = this.cursor
|
|
|
|
this.cursor = newCursor
|
|
|
|
colIdx = PostDraft.ColIdx(newCursor)
|
|
|
|
adapter.notifyDataSetChanged()
|
|
|
|
old?.close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun reload() {
|
|
|
|
|
|
|
|
// cancel old task
|
|
|
|
task?.cancel()
|
|
|
|
|
2021-06-20 15:12:25 +02:00
|
|
|
task = launchMain {
|
2020-12-17 04:17:48 +01:00
|
|
|
val cursor = try {
|
2022-07-20 06:27:19 +02:00
|
|
|
withContext(appDispatchers.io) {
|
2020-12-17 04:17:48 +01:00
|
|
|
PostDraft.createCursor()
|
|
|
|
} ?: error("cursor is null")
|
2021-06-20 15:12:25 +02:00
|
|
|
} catch (ignored: CancellationException) {
|
2021-05-27 04:15:59 +02:00
|
|
|
return@launchMain
|
2020-12-17 04:17:48 +01:00
|
|
|
} catch (ex: Throwable) {
|
2022-12-27 03:54:52 +01:00
|
|
|
log.e(ex, "failed to loading drafts.")
|
2020-12-17 04:17:48 +01:00
|
|
|
activity.showToast(ex, "failed to loading drafts.")
|
2021-05-27 04:15:59 +02:00
|
|
|
return@launchMain
|
2020-12-17 04:17:48 +01:00
|
|
|
}
|
|
|
|
updateCursor(cursor)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2021-06-23 06:14:25 +02:00
|
|
|
val cw = json.string(DRAFT_CONTENT_WARNING)
|
|
|
|
val c = json.string(DRAFT_CONTENT)
|
2020-12-17 04:17:48 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
2018-01-04 19:52:25 +01:00
|
|
|
}
|