280 lines
10 KiB
Kotlin
280 lines
10 KiB
Kotlin
/* Copyright 2021 Tusky Contributors
|
|
*
|
|
* This file is a part of Tusky.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
* Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
|
* see <http://www.gnu.org/licenses>. */
|
|
|
|
@file:OptIn(ExperimentalStdlibApi::class)
|
|
|
|
package com.keylesspalace.tusky.components.timeline
|
|
|
|
import android.util.Log
|
|
import com.keylesspalace.tusky.db.TimelineAccountEntity
|
|
import com.keylesspalace.tusky.db.TimelineStatusEntity
|
|
import com.keylesspalace.tusky.db.TimelineStatusWithAccount
|
|
import com.keylesspalace.tusky.entity.Attachment
|
|
import com.keylesspalace.tusky.entity.Card
|
|
import com.keylesspalace.tusky.entity.Emoji
|
|
import com.keylesspalace.tusky.entity.HashTag
|
|
import com.keylesspalace.tusky.entity.Poll
|
|
import com.keylesspalace.tusky.entity.Status
|
|
import com.keylesspalace.tusky.entity.TimelineAccount
|
|
import com.keylesspalace.tusky.viewdata.StatusViewData
|
|
import com.keylesspalace.tusky.viewdata.TranslationViewData
|
|
import com.squareup.moshi.Moshi
|
|
import com.squareup.moshi.adapter
|
|
import java.util.Date
|
|
|
|
private const val TAG = "TimelineTypeMappers"
|
|
|
|
data class Placeholder(
|
|
val id: String,
|
|
val loading: Boolean
|
|
)
|
|
|
|
fun TimelineAccount.toEntity(accountId: Long, moshi: Moshi): TimelineAccountEntity {
|
|
return TimelineAccountEntity(
|
|
serverId = id,
|
|
timelineUserId = accountId,
|
|
localUsername = localUsername,
|
|
username = username,
|
|
displayName = name,
|
|
url = url,
|
|
avatar = avatar,
|
|
emojis = moshi.adapter<List<Emoji>>().toJson(emojis),
|
|
bot = bot
|
|
)
|
|
}
|
|
|
|
fun TimelineAccountEntity.toAccount(moshi: Moshi): TimelineAccount {
|
|
return TimelineAccount(
|
|
id = serverId,
|
|
localUsername = localUsername,
|
|
username = username,
|
|
displayName = displayName,
|
|
note = "",
|
|
url = url,
|
|
avatar = avatar,
|
|
bot = bot,
|
|
emojis = moshi.adapter<List<Emoji>?>().fromJson(emojis).orEmpty()
|
|
)
|
|
}
|
|
|
|
fun Placeholder.toEntity(timelineUserId: Long): TimelineStatusEntity {
|
|
return TimelineStatusEntity(
|
|
serverId = this.id,
|
|
url = null,
|
|
timelineUserId = timelineUserId,
|
|
authorServerId = null,
|
|
inReplyToId = null,
|
|
inReplyToAccountId = null,
|
|
content = null,
|
|
createdAt = 0L,
|
|
editedAt = 0L,
|
|
emojis = null,
|
|
reblogsCount = 0,
|
|
favouritesCount = 0,
|
|
reblogged = false,
|
|
favourited = false,
|
|
bookmarked = false,
|
|
sensitive = false,
|
|
spoilerText = "",
|
|
visibility = Status.Visibility.UNKNOWN,
|
|
attachments = null,
|
|
mentions = null,
|
|
tags = null,
|
|
application = null,
|
|
reblogServerId = null,
|
|
reblogAccountId = null,
|
|
poll = null,
|
|
muted = false,
|
|
expanded = loading,
|
|
contentCollapsed = false,
|
|
contentShowing = false,
|
|
pinned = false,
|
|
card = null,
|
|
repliesCount = 0,
|
|
language = null,
|
|
filtered = emptyList()
|
|
)
|
|
}
|
|
|
|
fun Status.toEntity(
|
|
timelineUserId: Long,
|
|
moshi: Moshi,
|
|
expanded: Boolean,
|
|
contentShowing: Boolean,
|
|
contentCollapsed: Boolean
|
|
): TimelineStatusEntity {
|
|
return TimelineStatusEntity(
|
|
serverId = this.id,
|
|
url = actionableStatus.url,
|
|
timelineUserId = timelineUserId,
|
|
authorServerId = actionableStatus.account.id,
|
|
inReplyToId = actionableStatus.inReplyToId,
|
|
inReplyToAccountId = actionableStatus.inReplyToAccountId,
|
|
content = actionableStatus.content,
|
|
createdAt = actionableStatus.createdAt.time,
|
|
editedAt = actionableStatus.editedAt?.time,
|
|
emojis = actionableStatus.emojis.let { moshi.adapter<List<Emoji>>().toJson(it) },
|
|
reblogsCount = actionableStatus.reblogsCount,
|
|
favouritesCount = actionableStatus.favouritesCount,
|
|
reblogged = actionableStatus.reblogged,
|
|
favourited = actionableStatus.favourited,
|
|
bookmarked = actionableStatus.bookmarked,
|
|
sensitive = actionableStatus.sensitive,
|
|
spoilerText = actionableStatus.spoilerText,
|
|
visibility = actionableStatus.visibility,
|
|
attachments = actionableStatus.attachments.let { moshi.adapter<List<Attachment>>().toJson(it) },
|
|
mentions = actionableStatus.mentions.let { moshi.adapter<List<Status.Mention>>().toJson(it) },
|
|
tags = actionableStatus.tags.let { moshi.adapter<List<HashTag>?>().toJson(it) },
|
|
application = actionableStatus.application.let { moshi.adapter<Status.Application?>().toJson(it) },
|
|
reblogServerId = reblog?.id,
|
|
reblogAccountId = reblog?.let { this.account.id },
|
|
poll = actionableStatus.poll.let { moshi.adapter<Poll?>().toJson(it) },
|
|
muted = actionableStatus.muted,
|
|
expanded = expanded,
|
|
contentShowing = contentShowing,
|
|
contentCollapsed = contentCollapsed,
|
|
pinned = actionableStatus.pinned,
|
|
card = actionableStatus.card?.let { moshi.adapter<Card>().toJson(it) },
|
|
repliesCount = actionableStatus.repliesCount,
|
|
language = actionableStatus.language,
|
|
filtered = actionableStatus.filtered
|
|
)
|
|
}
|
|
|
|
fun TimelineStatusWithAccount.toViewData(moshi: Moshi, isDetailed: Boolean = false, translation: TranslationViewData? = null): StatusViewData {
|
|
if (this.account == null) {
|
|
Log.d(TAG, "Constructing Placeholder(${this.status.serverId}, ${this.status.expanded})")
|
|
return StatusViewData.Placeholder(this.status.serverId, this.status.expanded)
|
|
}
|
|
|
|
val attachments: List<Attachment> = status.attachments?.let { moshi.adapter<List<Attachment>?>().fromJson(it) }.orEmpty()
|
|
val mentions: List<Status.Mention> = status.mentions?.let { moshi.adapter<List<Status.Mention>?>().fromJson(it) }.orEmpty()
|
|
val tags: List<HashTag>? = status.tags?.let { moshi.adapter<List<HashTag>?>().fromJson(it) }
|
|
val application = status.application?.let { moshi.adapter<Status.Application?>().fromJson(it) }
|
|
val emojis: List<Emoji> = status.emojis?.let { moshi.adapter<List<Emoji>?>().fromJson(it) }.orEmpty()
|
|
val poll: Poll? = status.poll?.let { moshi.adapter<Poll?>().fromJson(it) }
|
|
val card: Card? = status.card?.let { moshi.adapter<Card?>().fromJson(it) }
|
|
|
|
val reblog = status.reblogServerId?.let { id ->
|
|
Status(
|
|
id = id,
|
|
url = status.url,
|
|
account = account.toAccount(moshi),
|
|
inReplyToId = status.inReplyToId,
|
|
inReplyToAccountId = status.inReplyToAccountId,
|
|
reblog = null,
|
|
content = status.content.orEmpty(),
|
|
createdAt = Date(status.createdAt),
|
|
editedAt = status.editedAt?.let { Date(it) },
|
|
emojis = emojis,
|
|
reblogsCount = status.reblogsCount,
|
|
favouritesCount = status.favouritesCount,
|
|
reblogged = status.reblogged,
|
|
favourited = status.favourited,
|
|
bookmarked = status.bookmarked,
|
|
sensitive = status.sensitive,
|
|
spoilerText = status.spoilerText,
|
|
visibility = status.visibility,
|
|
attachments = attachments,
|
|
mentions = mentions,
|
|
tags = tags,
|
|
application = application,
|
|
pinned = false,
|
|
muted = status.muted ?: false,
|
|
poll = poll,
|
|
card = card,
|
|
repliesCount = status.repliesCount,
|
|
language = status.language,
|
|
filtered = status.filtered.orEmpty(),
|
|
)
|
|
}
|
|
val status = if (reblog != null) {
|
|
Status(
|
|
id = status.serverId,
|
|
// no url for reblogs
|
|
url = null,
|
|
account = this.reblogAccount!!.toAccount(moshi),
|
|
inReplyToId = status.inReplyToId,
|
|
inReplyToAccountId = status.inReplyToAccountId,
|
|
reblog = reblog,
|
|
content = "",
|
|
// lie but whatever?
|
|
createdAt = Date(status.createdAt),
|
|
editedAt = null,
|
|
emojis = emptyList(),
|
|
reblogsCount = 0,
|
|
favouritesCount = 0,
|
|
reblogged = false,
|
|
favourited = false,
|
|
bookmarked = false,
|
|
sensitive = false,
|
|
spoilerText = "",
|
|
visibility = status.visibility,
|
|
attachments = emptyList(),
|
|
mentions = emptyList(),
|
|
tags = emptyList(),
|
|
application = null,
|
|
pinned = status.pinned,
|
|
muted = status.muted ?: false,
|
|
poll = null,
|
|
card = null,
|
|
repliesCount = status.repliesCount,
|
|
language = status.language,
|
|
filtered = status.filtered.orEmpty()
|
|
)
|
|
} else {
|
|
Status(
|
|
id = status.serverId,
|
|
url = status.url,
|
|
account = account.toAccount(moshi),
|
|
inReplyToId = status.inReplyToId,
|
|
inReplyToAccountId = status.inReplyToAccountId,
|
|
reblog = null,
|
|
content = translation?.data?.content ?: status.content.orEmpty(),
|
|
createdAt = Date(status.createdAt),
|
|
editedAt = status.editedAt?.let { Date(it) },
|
|
emojis = emojis,
|
|
reblogsCount = status.reblogsCount,
|
|
favouritesCount = status.favouritesCount,
|
|
reblogged = status.reblogged,
|
|
favourited = status.favourited,
|
|
bookmarked = status.bookmarked,
|
|
sensitive = status.sensitive,
|
|
spoilerText = status.spoilerText,
|
|
visibility = status.visibility,
|
|
attachments = attachments,
|
|
mentions = mentions,
|
|
tags = tags,
|
|
application = application,
|
|
pinned = status.pinned,
|
|
muted = status.muted ?: false,
|
|
poll = poll,
|
|
card = card,
|
|
repliesCount = status.repliesCount,
|
|
language = status.language,
|
|
filtered = status.filtered.orEmpty()
|
|
)
|
|
}
|
|
return StatusViewData.Concrete(
|
|
status = status,
|
|
inReplyToAccount = this.inReplyToAccount?.toAccount(moshi),
|
|
isExpanded = this.status.expanded,
|
|
isShowingContent = this.status.contentShowing,
|
|
isCollapsed = this.status.contentCollapsed,
|
|
isDetailed = isDetailed,
|
|
translation = translation,
|
|
)
|
|
}
|