SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/actpost/ActPostStates.kt

112 lines
3.8 KiB
Kotlin

package jp.juggler.subwaytooter.actpost
import android.os.Bundle
import jp.juggler.subwaytooter.ActPost
import jp.juggler.subwaytooter.api.TootParser
import jp.juggler.subwaytooter.api.entity.EntityId
import jp.juggler.subwaytooter.api.entity.EntityIdSerializer
import jp.juggler.subwaytooter.api.entity.TootScheduled
import jp.juggler.subwaytooter.api.entity.TootVisibility
import jp.juggler.subwaytooter.api.entity.parseItem
import jp.juggler.subwaytooter.kJson
import jp.juggler.subwaytooter.util.AttachmentPicker
import jp.juggler.subwaytooter.util.PostAttachment
import jp.juggler.util.data.decodeJsonObject
import jp.juggler.util.data.toJsonArray
import jp.juggler.util.log.LogCategory
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
private val log = LogCategory("ActPostStates")
@Serializable
data class ActPostStates(
////////////
// states requires special handling
var accountDbId: Long? = null,
var pickerState: String? = null,
var attachmentListEncoded: String? = null,
var scheduledStatusEncoded: String? = null,
////////////
var visibility: TootVisibility? = null,
@Serializable(with = EntityIdSerializer::class)
var redraftStatusId: EntityId? = null,
@Serializable(with = EntityIdSerializer::class)
var editStatusId: EntityId? = null,
var mushroomInput: Int = 0,
var mushroomStart: Int = 0,
var mushroomEnd: Int = 0,
var timeSchedule: Long = 0L,
@Serializable(with = EntityIdSerializer::class)
var inReplyToId: EntityId? = null,
var inReplyToText: String? = null,
var inReplyToImage: String? = null,
var inReplyToUrl: String? = null,
)
// 画面状態の保存
fun ActPost.saveState(outState: Bundle) {
states.accountDbId = account?.db_id
states.pickerState = attachmentPicker.encodeState()
states.scheduledStatusEncoded = scheduledStatus?.encodeSimple()?.toString()
// アップロード完了したものだけ保持する
states.attachmentListEncoded = attachmentList
.filter { it.status == PostAttachment.Status.Ok }
.mapNotNull { it.attachment?.encodeJson() }
.toJsonArray()
.toString()
val encoded = kJson.encodeToString(states)
log.d("onSaveInstanceState: $encoded")
outState.putString(ActPost.STATE_ALL, encoded)
// test decoding
kJson.decodeFromString<AttachmentPicker.States>(encoded)
}
// 画面状態の復元
suspend fun ActPost.restoreState(savedInstanceState: Bundle) {
resetText() // also load account list
savedInstanceState.getString(ActPost.STATE_ALL)?.let { jsonText ->
states = kJson.decodeFromString(jsonText)
states.pickerState?.let { attachmentPicker.restoreState(it) }
this.account = null // いちど選択を外してから再選択させる
accountList.find { it.db_id == states.accountDbId }?.let { selectAccount(it) }
account?.let { a ->
states.scheduledStatusEncoded?.let { jsonText ->
scheduledStatus = parseItem(jsonText.decodeJsonObject()) {
TootScheduled(TootParser(this, a), it)
}
}
}
val stateAttachmentList = appState.attachmentList
if (!isMultiWindowPost && stateAttachmentList != null) {
// static なデータが残ってるならそれを使う
this.attachmentList = stateAttachmentList
// コールバックを新しい画面に差し替える
for (pa in attachmentList) {
pa.callback = this
}
} else {
// state から復元する
states.attachmentListEncoded?.let {
decodeAttachments(it)
saveAttachmentList()
}
}
}
afterUpdateText()
}