diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/adapter/JsonColumnAdapter.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/adapter/JsonColumnAdapter.kt index 9f961b895..3edf23e4f 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/adapter/JsonColumnAdapter.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/data/database/adapter/JsonColumnAdapter.kt @@ -4,11 +4,14 @@ import app.cash.sqldelight.ColumnAdapter import dev.dimension.flare.common.decodeJson import dev.dimension.flare.common.encodeJson import kotlinx.serialization.KSerializer +import kotlin.io.encoding.Base64 +import kotlin.io.encoding.ExperimentalEncodingApi +@OptIn(ExperimentalEncodingApi::class) internal class JsonColumnAdapter( private val serializer: KSerializer, ) : ColumnAdapter { - override fun decode(databaseValue: String): T = databaseValue.decodeJson(serializer) + override fun decode(databaseValue: String): T = Base64.decode(databaseValue).decodeToString().decodeJson(serializer) - override fun encode(value: T) = value.encodeJson(serializer) + override fun encode(value: T) = Base64.encode(value.encodeJson(serializer).encodeToByteArray()) } diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/xqt/model/Url.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/xqt/model/Url.kt index 5b3e7beaf..3ecc43865 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/xqt/model/Url.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/data/network/xqt/model/Url.kt @@ -30,11 +30,11 @@ import kotlinx.serialization.Serializable @Serializable internal data class Url( @SerialName(value = "display_url") - val displayUrl: kotlin.String, + val displayUrl: kotlin.String? = null, @Contextual @SerialName(value = "expanded_url") - val expandedUrl: String, + val expandedUrl: String? = null, @SerialName(value = "indices") - val indices: kotlin.collections.List, + val indices: kotlin.collections.List? = null, @Contextual @SerialName(value = "url") val url: String, ) diff --git a/shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/XQT.kt b/shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/XQT.kt index a56321fa9..a5c4895d8 100644 --- a/shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/XQT.kt +++ b/shared/src/commonMain/kotlin/dev/dimension/flare/ui/model/mapper/XQT.kt @@ -1,7 +1,6 @@ package dev.dimension.flare.ui.model.mapper import de.cketti.codepoints.deluxe.codePointSequence -import dev.dimension.flare.common.encodeJson import dev.dimension.flare.data.network.xqt.model.GetProfileSpotlightsQuery200Response import dev.dimension.flare.data.network.xqt.model.Media import dev.dimension.flare.data.network.xqt.model.Tweet @@ -51,7 +50,7 @@ internal fun Tweet.toUi(accountKey: MicroBlogKey): UiStatus.XQT { is UserUnavailable -> null } }?.toUi() - requireNotNull(user) + requireNotNull(user) { "user is null" } val uiCard = card?.legacy?.let { val title = it.get("title")?.stringValue @@ -156,33 +155,33 @@ internal fun Tweet.toUi(accountKey: MicroBlogKey): UiStatus.XQT { accountKey = accountKey, statusKey = MicroBlogKey( - id = legacy?.idStr ?: throw Exception("no id for tweet: ${this.encodeJson()}"), + id = legacy?.idStr ?: restId, host = accountKey.host, ), user = user, - createdAt = parseCustomDateTime(legacy.createdAt) ?: Clock.System.now(), + createdAt = legacy?.createdAt?.let { parseCustomDateTime(it) } ?: Clock.System.now(), content = text, medias = medias, card = uiCard, matrices = UiStatus.XQT.Matrices( - replyCount = legacy.replyCount.toLong(), - likeCount = legacy.favoriteCount.toLong(), - retweetCount = legacy.retweetCount.toLong(), + replyCount = legacy?.replyCount?.toLong() ?: 0, + likeCount = legacy?.favoriteCount?.toLong() ?: 0, + retweetCount = legacy?.retweetCount?.toLong() ?: 0, ), reaction = UiStatus.XQT.Reaction( - liked = legacy.favorited, - retweeted = legacy.retweeted, - bookmarked = legacy.bookmarked ?: false, + liked = legacy?.favorited ?: false, + retweeted = legacy?.retweeted ?: false, + bookmarked = legacy?.bookmarked ?: false, ), retweet = retweet, quote = quote, - inReplyToScreenName = legacy.in_reply_to_screen_name, - inReplyToStatusId = legacy.in_reply_to_status_id_str, - inReplyToUserId = legacy.in_reply_to_user_id_str, + inReplyToScreenName = legacy?.in_reply_to_screen_name, + inReplyToStatusId = legacy?.in_reply_to_status_id_str, + inReplyToUserId = legacy?.in_reply_to_user_id_str, poll = poll, - sensitive = legacy.possiblySensitive == true, + sensitive = legacy?.possiblySensitive == true, raw = this, ) } diff --git a/shared/src/commonMain/sqldelight/cache/migrations/1.sqm b/shared/src/commonMain/sqldelight/cache/migrations/1.sqm new file mode 100644 index 000000000..44d146881 --- /dev/null +++ b/shared/src/commonMain/sqldelight/cache/migrations/1.sqm @@ -0,0 +1,15 @@ +import dev.dimension.flare.data.database.cache.model.StatusContent; +import dev.dimension.flare.model.MicroBlogKey; +import dev.dimension.flare.model.PlatformType; + +DROP TABLE IF EXISTS DbStatus; + +CREATE TABLE IF NOT EXISTS DbStatus ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + status_key TEXT AS MicroBlogKey NOT NULL, + account_key TEXT AS MicroBlogKey NOT NULL, + user_key TEXT AS MicroBlogKey, + platform_type TEXT AS PlatformType NOT NULL, + content TEXT AS StatusContent NOT NULL, + UNIQUE (status_key, account_key) +); \ No newline at end of file