From 0a5714a6eec17d6a14ec162cc8e55c331ea59333 Mon Sep 17 00:00:00 2001 From: Conny Duck Date: Thu, 18 Apr 2024 20:47:35 +0200 Subject: [PATCH] move json de/serialization completely to room converter --- .../notifications/NotificationTypeMappers.kt | 35 ++-- .../NotificationsRemoteMediator.kt | 9 +- .../notifications/NotificationsViewModel.kt | 16 +- .../timeline/TimelineTypeMappers.kt | 165 ++++++++---------- .../viewmodel/CachedTimelineRemoteMediator.kt | 7 +- .../viewmodel/CachedTimelineViewModel.kt | 12 +- .../viewthread/ViewThreadViewModel.kt | 2 +- .../com/keylesspalace/tusky/db/Converters.kt | 15 ++ .../tusky/db/entity/TimelineAccountEntity.kt | 6 +- .../tusky/db/entity/TimelineStatusEntity.kt | 19 +- .../notifications/NotificationMocker.kt | 39 ++--- .../NotificationsRemoteMediatorTest.kt | 10 -- .../CachedTimelineRemoteMediatorTest.kt | 10 -- .../tusky/components/timeline/StatusMocker.kt | 5 - 14 files changed, 150 insertions(+), 200 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationTypeMappers.kt b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationTypeMappers.kt index 0985f28c9..d3248a672 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationTypeMappers.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationTypeMappers.kt @@ -27,19 +27,18 @@ import com.keylesspalace.tusky.entity.Report import com.keylesspalace.tusky.viewdata.NotificationViewData import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.TranslationViewData -import com.squareup.moshi.Moshi -fun Placeholder.toNotificationEntity(tuskyAccountId: Long): NotificationEntity { - return NotificationEntity( - id = this.id, - tuskyAccountId = tuskyAccountId, - type = null, - accountId = null, - statusId = null, - reportId = null, - loading = loading - ) -} +fun Placeholder.toNotificationEntity( + tuskyAccountId: Long +) = NotificationEntity( + id = this.id, + tuskyAccountId = tuskyAccountId, + type = null, + accountId = null, + statusId = null, + reportId = null, + loading = loading +) fun Notification.toEntity( tuskyAccountId: Long @@ -65,7 +64,6 @@ fun Report.toEntity( ) fun NotificationDataEntity.toViewData( - moshi: Moshi, translation: TranslationViewData? = null ): NotificationViewData { if (type == null || account == null) { @@ -75,10 +73,10 @@ fun NotificationDataEntity.toViewData( return NotificationViewData.Concrete( id = id, type = type, - account = account.toAccount(moshi), + account = account.toAccount(), statusViewData = if (status != null && statusAccount != null) { StatusViewData.Concrete( - status = status.toStatus(moshi, statusAccount), + status = status.toStatus(statusAccount), isExpanded = this.status.expanded, isShowingContent = this.status.contentShowing, isCollapsed = this.status.contentCollapsed, @@ -88,7 +86,7 @@ fun NotificationDataEntity.toViewData( null }, report = if (report != null && reportTargetAccount != null) { - report.toReport(reportTargetAccount, moshi) + report.toReport(reportTargetAccount) } else { null } @@ -96,12 +94,11 @@ fun NotificationDataEntity.toViewData( } fun NotificationReportEntity.toReport( - account: TimelineAccountEntity, - moshi: Moshi + account: TimelineAccountEntity ) = Report( id = serverId, category = category, statusIds = statusIds, createdAt = createdAt, - targetAccount = account.toAccount(moshi) + targetAccount = account.toAccount() ) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsRemoteMediator.kt b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsRemoteMediator.kt index d744b24a8..d6627da58 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsRemoteMediator.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsRemoteMediator.kt @@ -31,7 +31,6 @@ import com.keylesspalace.tusky.db.entity.TimelineStatusEntity import com.keylesspalace.tusky.entity.Notification import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.isLessThan -import com.squareup.moshi.Moshi import retrofit2.HttpException @OptIn(ExperimentalPagingApi::class) @@ -39,7 +38,6 @@ class NotificationsRemoteMediator( private val accountManager: AccountManager, private val api: MastodonApi, private val db: AppDatabase, - private val moshi: Moshi, var excludes: Set ) : RemoteMediator() { @@ -145,9 +143,9 @@ class NotificationsRemoteMediator( } for (notification in notifications) { - accountDao.insert(notification.account.toEntity(activeAccount.id, moshi)) + accountDao.insert(notification.account.toEntity(activeAccount.id)) notification.report?.let { report -> - accountDao.insert(report.targetAccount.toEntity(activeAccount.id, moshi)) + accountDao.insert(report.targetAccount.toEntity(activeAccount.id)) notificationsDao.insertReport(report.toEntity(activeAccount.id)) } @@ -166,12 +164,11 @@ class NotificationsRemoteMediator( val contentShowing = oldStatus?.contentShowing ?: (activeAccount.alwaysShowSensitiveMedia || !status.sensitive) val contentCollapsed = oldStatus?.contentCollapsed ?: true - accountDao.insert(status.account.toEntity(activeAccount.id, moshi)) + accountDao.insert(status.account.toEntity(activeAccount.id)) statusDao.insert( status.toEntity( tuskyAccountId = activeAccount.id, - moshi = moshi, expanded = expanded, contentShowing = contentShowing, contentCollapsed = contentCollapsed diff --git a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsViewModel.kt index 914e15ac4..93bc898dd 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsViewModel.kt @@ -51,7 +51,6 @@ import com.keylesspalace.tusky.util.serialize import com.keylesspalace.tusky.viewdata.NotificationViewData import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.TranslationViewData -import com.squareup.moshi.Moshi import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -75,7 +74,6 @@ class NotificationsViewModel @Inject constructor( private val preferences: SharedPreferences, private val filterModel: FilterModel, private val db: AppDatabase, - private val moshi: Moshi ) : ViewModel() { private val _filters = MutableStateFlow( @@ -86,7 +84,7 @@ class NotificationsViewModel @Inject constructor( /** Map from notification id to translation. */ private val translations = MutableStateFlow(mapOf()) - private var remoteMediator = NotificationsRemoteMediator(accountManager, api, db, moshi, filters.value) + private var remoteMediator = NotificationsRemoteMediator(accountManager, api, db, filters.value) private var readingOrder: ReadingOrder = ReadingOrder.from(preferences.getString(PrefKeys.READING_ORDER, null)) @@ -108,10 +106,7 @@ class NotificationsViewModel @Inject constructor( .combine(translations) { pagingData, translations -> pagingData.map(Dispatchers.Default.asExecutor()) { notification -> val translation = translations[notification.status?.serverId] - notification.toViewData( - moshi, - translation = translation - ) + notification.toViewData(translation = translation) }.filter(Dispatchers.Default.asExecutor()) { notificationViewData -> shouldFilterStatus(notificationViewData) != Filter.Action.HIDE } @@ -338,18 +333,17 @@ class NotificationsViewModel @Inject constructor( } for (notification in notifications) { - accountDao.insert(notification.account.toEntity(activeAccount.id, moshi)) + accountDao.insert(notification.account.toEntity(activeAccount.id)) notification.report?.let { report -> - accountDao.insert(report.targetAccount.toEntity(activeAccount.id, moshi)) + accountDao.insert(report.targetAccount.toEntity(activeAccount.id)) notificationsDao.insertReport(report.toEntity(activeAccount.id)) } notification.status?.let { status -> - accountDao.insert(status.account.toEntity(activeAccount.id, moshi)) + accountDao.insert(status.account.toEntity(activeAccount.id)) statusDao.insert( status.toEntity( tuskyAccountId = activeAccount.id, - moshi = moshi, expanded = activeAccount.alwaysOpenSpoiler, contentShowing = activeAccount.alwaysShowSensitiveMedia || !status.sensitive, contentCollapsed = true diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineTypeMappers.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineTypeMappers.kt index 734196981..42df6721a 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineTypeMappers.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/TimelineTypeMappers.kt @@ -21,17 +21,10 @@ import com.keylesspalace.tusky.db.entity.HomeTimelineData import com.keylesspalace.tusky.db.entity.HomeTimelineEntity import com.keylesspalace.tusky.db.entity.TimelineAccountEntity import com.keylesspalace.tusky.db.entity.TimelineStatusEntity -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 data class Placeholder( @@ -39,7 +32,7 @@ data class Placeholder( val loading: Boolean ) -fun TimelineAccount.toEntity(tuskyAccountId: Long, moshi: Moshi): TimelineAccountEntity { +fun TimelineAccount.toEntity(tuskyAccountId: Long): TimelineAccountEntity { return TimelineAccountEntity( serverId = id, tuskyAccountId = tuskyAccountId, @@ -48,12 +41,12 @@ fun TimelineAccount.toEntity(tuskyAccountId: Long, moshi: Moshi): TimelineAccoun displayName = name, url = url, avatar = avatar, - emojis = moshi.adapter>().toJson(emojis), + emojis = emojis, bot = bot ) } -fun TimelineAccountEntity.toAccount(moshi: Moshi): TimelineAccount { +fun TimelineAccountEntity.toAccount(): TimelineAccount { return TimelineAccount( id = serverId, localUsername = localUsername, @@ -63,7 +56,7 @@ fun TimelineAccountEntity.toAccount(moshi: Moshi): TimelineAccount { url = url, avatar = avatar, bot = bot, - emojis = moshi.adapter?>().fromJson(emojis).orEmpty() + emojis = emojis ) } @@ -79,104 +72,90 @@ fun Placeholder.toEntity(tuskyAccountId: Long): HomeTimelineEntity { fun Status.toEntity( tuskyAccountId: Long, - moshi: Moshi, expanded: Boolean, contentShowing: Boolean, contentCollapsed: Boolean -): TimelineStatusEntity { - return TimelineStatusEntity( - serverId = id, - url = actionableStatus.url, - tuskyAccountId = tuskyAccountId, - 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>().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>().toJson(it) }, - mentions = actionableStatus.mentions.let { moshi.adapter>().toJson(it) }, - tags = actionableStatus.tags.let { moshi.adapter?>().toJson(it) }, - application = actionableStatus.application.let { moshi.adapter().toJson(it) }, - poll = actionableStatus.poll.let { moshi.adapter().toJson(it) }, - muted = actionableStatus.muted, - expanded = expanded, - contentShowing = contentShowing, - contentCollapsed = contentCollapsed, - pinned = actionableStatus.pinned, - card = actionableStatus.card?.let { moshi.adapter().toJson(it) }, - repliesCount = actionableStatus.repliesCount, - language = actionableStatus.language, - filtered = actionableStatus.filtered - ) -} +) = TimelineStatusEntity( + serverId = id, + url = actionableStatus.url, + tuskyAccountId = tuskyAccountId, + authorServerId = actionableStatus.account.id, + inReplyToId = actionableStatus.inReplyToId, + inReplyToAccountId = actionableStatus.inReplyToAccountId, + content = actionableStatus.content, + createdAt = actionableStatus.createdAt.time, + editedAt = actionableStatus.editedAt?.time, + emojis = actionableStatus.emojis, + 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, + mentions = actionableStatus.mentions, + tags = actionableStatus.tags, + application = actionableStatus.application, + poll = actionableStatus.poll, + muted = actionableStatus.muted, + expanded = expanded, + contentShowing = contentShowing, + contentCollapsed = contentCollapsed, + pinned = actionableStatus.pinned, + card = actionableStatus.card, + repliesCount = actionableStatus.repliesCount, + language = actionableStatus.language, + filtered = actionableStatus.filtered +) fun TimelineStatusEntity.toStatus( - moshi: Moshi, account: TimelineAccountEntity -): Status { - val attachments: List = moshi.adapter>().fromJson(attachments).orEmpty() - val mentions: List = moshi.adapter>().fromJson(mentions).orEmpty() - val tags: List = moshi.adapter>().fromJson(tags).orEmpty() - val application = application?.let { moshi.adapter().fromJson(it) } - val emojis: List = moshi.adapter?>().fromJson(emojis).orEmpty() - val poll: Poll? = poll?.let { moshi.adapter().fromJson(it) } - val card: Card? = card?.let { moshi.adapter().fromJson(it) } +) = Status( + id = serverId, + url = url, + account = account.toAccount(), + inReplyToId = inReplyToId, + inReplyToAccountId = inReplyToAccountId, + reblog = null, + content = content, + createdAt = Date(createdAt), + editedAt = editedAt?.let { Date(it) }, + emojis = emojis, + reblogsCount = reblogsCount, + favouritesCount = favouritesCount, + reblogged = reblogged, + favourited = favourited, + bookmarked = bookmarked, + sensitive = sensitive, + spoilerText = spoilerText, + visibility = visibility, + attachments = attachments, + mentions = mentions, + tags = tags, + application = application, + pinned = false, + muted = muted, + poll = poll, + card = card, + repliesCount = repliesCount, + language = language, + filtered = filtered, +) - return Status( - id = serverId, - url = url, - account = account.toAccount(moshi), - inReplyToId = inReplyToId, - inReplyToAccountId = inReplyToAccountId, - reblog = null, - content = content, - createdAt = Date(createdAt), - editedAt = editedAt?.let { Date(it) }, - emojis = emojis, - reblogsCount = reblogsCount, - favouritesCount = favouritesCount, - reblogged = reblogged, - favourited = favourited, - bookmarked = bookmarked, - sensitive = sensitive, - spoilerText = spoilerText, - visibility = visibility, - attachments = attachments, - mentions = mentions, - tags = tags, - application = application, - pinned = false, - muted = muted, - poll = poll, - card = card, - repliesCount = repliesCount, - language = language, - filtered = filtered, - ) -} - -fun HomeTimelineData.toViewData(moshi: Moshi, isDetailed: Boolean = false, translation: TranslationViewData? = null): StatusViewData { +fun HomeTimelineData.toViewData(isDetailed: Boolean = false, translation: TranslationViewData? = null): StatusViewData { if (this.account == null || this.status == null) { return StatusViewData.Placeholder(this.id, loading) } - val originalStatus = status.toStatus(moshi, account) + val originalStatus = status.toStatus(account) val status = if (reblogAccount != null) { Status( id = id, // no url for reblogs url = null, - account = reblogAccount.toAccount(moshi), + account = reblogAccount.toAccount(), inReplyToId = status.inReplyToId, inReplyToAccountId = status.inReplyToAccountId, reblog = originalStatus, diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt index 576d4976b..73bc5e714 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineRemoteMediator.kt @@ -31,7 +31,6 @@ import com.keylesspalace.tusky.db.entity.HomeTimelineEntity import com.keylesspalace.tusky.db.entity.TimelineStatusEntity import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.network.MastodonApi -import com.squareup.moshi.Moshi import retrofit2.HttpException @OptIn(ExperimentalPagingApi::class) @@ -39,7 +38,6 @@ class CachedTimelineRemoteMediator( accountManager: AccountManager, private val api: MastodonApi, private val db: AppDatabase, - private val moshi: Moshi ) : RemoteMediator() { private var initialRefresh = false @@ -146,8 +144,8 @@ class CachedTimelineRemoteMediator( } for (status in statuses) { - accountDao.insert(status.account.toEntity(activeAccount.id, moshi)) - status.reblog?.account?.toEntity(activeAccount.id, moshi)?.let { rebloggedAccount -> + accountDao.insert(status.account.toEntity(activeAccount.id)) + status.reblog?.account?.toEntity(activeAccount.id)?.let { rebloggedAccount -> accountDao.insert(rebloggedAccount) } @@ -168,7 +166,6 @@ class CachedTimelineRemoteMediator( statusDao.insert( status.actionableStatus.toEntity( tuskyAccountId = activeAccount.id, - moshi = moshi, expanded = expanded, contentShowing = contentShowing, contentCollapsed = contentCollapsed diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt index f9bcd1568..35f8dc76c 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/CachedTimelineViewModel.kt @@ -48,7 +48,6 @@ import com.keylesspalace.tusky.usecase.TimelineCases import com.keylesspalace.tusky.util.EmptyPagingSource import com.keylesspalace.tusky.viewdata.StatusViewData import com.keylesspalace.tusky.viewdata.TranslationViewData -import com.squareup.moshi.Moshi import javax.inject.Inject import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.asExecutor @@ -68,8 +67,7 @@ class CachedTimelineViewModel @Inject constructor( accountManager: AccountManager, sharedPreferences: SharedPreferences, filterModel: FilterModel, - private val db: AppDatabase, - private val moshi: Moshi + private val db: AppDatabase ) : TimelineViewModel( timelineCases, api, @@ -87,7 +85,7 @@ class CachedTimelineViewModel @Inject constructor( @OptIn(ExperimentalPagingApi::class) override val statuses = Pager( config = PagingConfig(pageSize = LOAD_AT_ONCE), - remoteMediator = CachedTimelineRemoteMediator(accountManager, api, db, moshi), + remoteMediator = CachedTimelineRemoteMediator(accountManager, api, db), pagingSourceFactory = { val activeAccount = accountManager.activeAccount if (activeAccount == null) { @@ -108,7 +106,6 @@ class CachedTimelineViewModel @Inject constructor( pagingData.map(Dispatchers.Default.asExecutor()) { timelineData -> val translation = translations[timelineData.status?.serverId] timelineData.toViewData( - moshi, isDetailed = false, translation = translation ) @@ -209,15 +206,14 @@ class CachedTimelineViewModel @Inject constructor( } for (status in statuses) { - accountDao.insert(status.account.toEntity(activeAccount.id, moshi)) - status.reblog?.account?.toEntity(activeAccount.id, moshi) + accountDao.insert(status.account.toEntity(activeAccount.id)) + status.reblog?.account?.toEntity(activeAccount.id) ?.let { rebloggedAccount -> accountDao.insert(rebloggedAccount) } statusDao.insert( status.actionableStatus.toEntity( tuskyAccountId = activeAccount.id, - moshi = moshi, expanded = activeAccount.alwaysOpenSpoiler, contentShowing = activeAccount.alwaysShowSensitiveMedia || !status.actionableStatus.sensitive, contentCollapsed = true diff --git a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadViewModel.kt index 757c339af..394606520 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/viewthread/ViewThreadViewModel.kt @@ -114,7 +114,7 @@ class ViewThreadViewModel @Inject constructor( var detailedStatus = if (statusAndAccount != null) { Log.d(TAG, "Loaded status from local timeline") StatusViewData.Concrete( - status = statusAndAccount.first.toStatus(moshi, statusAndAccount.second), + status = statusAndAccount.first.toStatus(statusAndAccount.second), isExpanded = statusAndAccount.first.expanded, isShowingContent = statusAndAccount.first.contentShowing, isCollapsed = statusAndAccount.first.contentCollapsed, diff --git a/app/src/main/java/com/keylesspalace/tusky/db/Converters.kt b/app/src/main/java/com/keylesspalace/tusky/db/Converters.kt index f86f0f77a..6280cc5cf 100644 --- a/app/src/main/java/com/keylesspalace/tusky/db/Converters.kt +++ b/app/src/main/java/com/keylesspalace/tusky/db/Converters.kt @@ -189,6 +189,11 @@ class Converters @Inject constructor( return moshi.adapter().toJson(card) } + @TypeConverter + fun jsonToCard(cardJson: String?): Card? { + return cardJson?.let { moshi.adapter().fromJson(cardJson) } + } + @TypeConverter fun stringListToJson(list: List?): String? { return moshi.adapter?>().toJson(list) @@ -198,4 +203,14 @@ class Converters @Inject constructor( fun jsonToStringList(listJson: String?): List? { return listJson?.let { moshi.adapter?>().fromJson(it) } } + + @TypeConverter + fun applicationToJson(application: Status.Application?): String { + return moshi.adapter().toJson(application) + } + + @TypeConverter + fun jsonToApplication(applicationJson: String?): Status.Application? { + return applicationJson?.let { moshi.adapter().fromJson(it) } + } } diff --git a/app/src/main/java/com/keylesspalace/tusky/db/entity/TimelineAccountEntity.kt b/app/src/main/java/com/keylesspalace/tusky/db/entity/TimelineAccountEntity.kt index 271002815..12499dbe2 100644 --- a/app/src/main/java/com/keylesspalace/tusky/db/entity/TimelineAccountEntity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/db/entity/TimelineAccountEntity.kt @@ -16,10 +16,14 @@ package com.keylesspalace.tusky.db.entity import androidx.room.Entity +import androidx.room.TypeConverters +import com.keylesspalace.tusky.db.Converters +import com.keylesspalace.tusky.entity.Emoji @Entity( primaryKeys = ["serverId", "tuskyAccountId"] ) +@TypeConverters(Converters::class) data class TimelineAccountEntity( val serverId: String, val tuskyAccountId: Long, @@ -28,6 +32,6 @@ data class TimelineAccountEntity( val displayName: String, val url: String, val avatar: String, - val emojis: String, + val emojis: List, val bot: Boolean ) diff --git a/app/src/main/java/com/keylesspalace/tusky/db/entity/TimelineStatusEntity.kt b/app/src/main/java/com/keylesspalace/tusky/db/entity/TimelineStatusEntity.kt index bff19cfdd..2b377d687 100644 --- a/app/src/main/java/com/keylesspalace/tusky/db/entity/TimelineStatusEntity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/db/entity/TimelineStatusEntity.kt @@ -20,7 +20,12 @@ import androidx.room.ForeignKey import androidx.room.Index import androidx.room.TypeConverters import com.keylesspalace.tusky.db.Converters +import com.keylesspalace.tusky.entity.Attachment +import com.keylesspalace.tusky.entity.Card +import com.keylesspalace.tusky.entity.Emoji import com.keylesspalace.tusky.entity.FilterResult +import com.keylesspalace.tusky.entity.HashTag +import com.keylesspalace.tusky.entity.Poll import com.keylesspalace.tusky.entity.Status /** @@ -54,7 +59,7 @@ data class TimelineStatusEntity( val content: String, val createdAt: Long, val editedAt: Long?, - val emojis: String, + val emojis: List, val reblogsCount: Int, val favouritesCount: Int, val repliesCount: Int, @@ -64,19 +69,19 @@ data class TimelineStatusEntity( val sensitive: Boolean, val spoilerText: String, val visibility: Status.Visibility, - val attachments: String, - val mentions: String, - val tags: String, - val application: String?, + val attachments: List, + val mentions: List, + val tags: List, + val application: Status.Application?, // if it has a reblogged status, it's id is stored here - val poll: String?, + val poll: Poll?, val muted: Boolean, /** Also used as the "loading" attribute when this TimelineStatusEntity is a placeholder */ val expanded: Boolean, val contentCollapsed: Boolean, val contentShowing: Boolean, val pinned: Boolean, - val card: String?, + val card: Card?, val language: String?, val filtered: List ) diff --git a/app/src/test/java/com/keylesspalace/tusky/components/notifications/NotificationMocker.kt b/app/src/test/java/com/keylesspalace/tusky/components/notifications/NotificationMocker.kt index 798ee1a22..32820ecc3 100644 --- a/app/src/test/java/com/keylesspalace/tusky/components/notifications/NotificationMocker.kt +++ b/app/src/test/java/com/keylesspalace/tusky/components/notifications/NotificationMocker.kt @@ -9,7 +9,6 @@ import com.keylesspalace.tusky.components.timeline.toEntity import com.keylesspalace.tusky.db.AppDatabase import com.keylesspalace.tusky.db.entity.NotificationDataEntity import com.keylesspalace.tusky.db.entity.NotificationEntity -import com.keylesspalace.tusky.di.NetworkModule import com.keylesspalace.tusky.entity.Notification import com.keylesspalace.tusky.entity.Report import com.keylesspalace.tusky.entity.Status @@ -49,25 +48,21 @@ fun Notification.toNotificationDataEntity( tuskyAccountId: Long, isStatusExpanded: Boolean = false, isStatusContentShowing: Boolean = false -): NotificationDataEntity { - val moshi = NetworkModule.providesMoshi() - return NotificationDataEntity( +) = NotificationDataEntity( + tuskyAccountId = tuskyAccountId, + type = type, + id = id, + account = account.toEntity(tuskyAccountId), + status = status?.toEntity( tuskyAccountId = tuskyAccountId, - type = type, - id = id, - account = account.toEntity(tuskyAccountId, moshi), - status = status?.toEntity( - tuskyAccountId = tuskyAccountId, - moshi = moshi, - expanded = isStatusExpanded, - contentShowing = isStatusContentShowing, - contentCollapsed = true - ), - statusAccount = status?.account?.toEntity(tuskyAccountId, moshi), - report = report?.toEntity(tuskyAccountId), - reportTargetAccount = report?.targetAccount?.toEntity(tuskyAccountId, moshi) - ) -} + expanded = isStatusExpanded, + contentShowing = isStatusContentShowing, + contentCollapsed = true + ), + statusAccount = status?.account?.toEntity(tuskyAccountId), + report = report?.toEntity(tuskyAccountId), + reportTargetAccount = report?.targetAccount?.toEntity(tuskyAccountId) +) fun Placeholder.toNotificationDataEntity( tuskyAccountId: Long @@ -83,18 +78,16 @@ fun Placeholder.toNotificationDataEntity( ) suspend fun AppDatabase.insert(notifications: List, tuskyAccountId: Long = 1) = withTransaction { - val moshi = NetworkModule.providesMoshi() notifications.forEach { notification -> timelineAccountDao().insert( - notification.account.toEntity(tuskyAccountId, moshi) + notification.account.toEntity(tuskyAccountId) ) notification.report?.let { report -> timelineAccountDao().insert( report.targetAccount.toEntity( tuskyAccountId = tuskyAccountId, - moshi = moshi ) ) notificationsDao().insertReport(report.toEntity(tuskyAccountId)) @@ -103,13 +96,11 @@ suspend fun AppDatabase.insert(notifications: List, tuskyAccountId timelineAccountDao().insert( status.account.toEntity( tuskyAccountId = tuskyAccountId, - moshi = moshi ) ) timelineStatusDao().insert( status.toEntity( tuskyAccountId = tuskyAccountId, - moshi = moshi, expanded = false, contentShowing = false, contentCollapsed = true diff --git a/app/src/test/java/com/keylesspalace/tusky/components/notifications/NotificationsRemoteMediatorTest.kt b/app/src/test/java/com/keylesspalace/tusky/components/notifications/NotificationsRemoteMediatorTest.kt index 71a44ae5b..6f3f736b4 100644 --- a/app/src/test/java/com/keylesspalace/tusky/components/notifications/NotificationsRemoteMediatorTest.kt +++ b/app/src/test/java/com/keylesspalace/tusky/components/notifications/NotificationsRemoteMediatorTest.kt @@ -82,7 +82,6 @@ class NotificationsRemoteMediatorTest { onBlocking { notifications(anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull()) } doReturn Response.error(500, "".toResponseBody()) }, db = db, - moshi = moshi, excludes = emptySet() ) @@ -102,7 +101,6 @@ class NotificationsRemoteMediatorTest { onBlocking { notifications(anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull()) } doThrow IOException() }, db = db, - moshi = moshi, excludes = emptySet() ) @@ -119,7 +117,6 @@ class NotificationsRemoteMediatorTest { accountManager = accountManager, api = mock(), db = db, - moshi = moshi, excludes = emptySet() ) @@ -171,7 +168,6 @@ class NotificationsRemoteMediatorTest { ) }, db = db, - moshi = moshi, excludes = emptySet() ) @@ -233,7 +229,6 @@ class NotificationsRemoteMediatorTest { ) }, db = db, - moshi = moshi, excludes = emptySet() ) @@ -294,7 +289,6 @@ class NotificationsRemoteMediatorTest { ) }, db = db, - moshi = moshi, excludes = emptySet() ) @@ -340,7 +334,6 @@ class NotificationsRemoteMediatorTest { ) }, db = db, - moshi = moshi, excludes = emptySet() ) @@ -395,7 +388,6 @@ class NotificationsRemoteMediatorTest { ) }, db = db, - moshi = moshi, excludes = emptySet() ) @@ -457,7 +449,6 @@ class NotificationsRemoteMediatorTest { ) }, db = db, - moshi = moshi, excludes = emptySet() ) @@ -510,7 +501,6 @@ class NotificationsRemoteMediatorTest { ) }, db = db, - moshi = moshi, excludes = emptySet() ) diff --git a/app/src/test/java/com/keylesspalace/tusky/components/timeline/CachedTimelineRemoteMediatorTest.kt b/app/src/test/java/com/keylesspalace/tusky/components/timeline/CachedTimelineRemoteMediatorTest.kt index d5ec75c5a..46d3d65b9 100644 --- a/app/src/test/java/com/keylesspalace/tusky/components/timeline/CachedTimelineRemoteMediatorTest.kt +++ b/app/src/test/java/com/keylesspalace/tusky/components/timeline/CachedTimelineRemoteMediatorTest.kt @@ -82,7 +82,6 @@ class CachedTimelineRemoteMediatorTest { onBlocking { homeTimeline(anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull()) } doReturn Response.error(500, "".toResponseBody()) }, db = db, - moshi = moshi ) val result = remoteMediator.load(LoadType.REFRESH, state()) @@ -101,7 +100,6 @@ class CachedTimelineRemoteMediatorTest { onBlocking { homeTimeline(anyOrNull(), anyOrNull(), anyOrNull(), anyOrNull()) } doThrow IOException() }, db = db, - moshi = moshi ) val result = remoteMediator.load(LoadType.REFRESH, state()) @@ -117,7 +115,6 @@ class CachedTimelineRemoteMediatorTest { accountManager = accountManager, api = mock(), db = db, - moshi = moshi ) val state = state( @@ -168,7 +165,6 @@ class CachedTimelineRemoteMediatorTest { ) }, db = db, - moshi = moshi ) val state = state( @@ -229,7 +225,6 @@ class CachedTimelineRemoteMediatorTest { ) }, db = db, - moshi = moshi ) val state = state( @@ -289,7 +284,6 @@ class CachedTimelineRemoteMediatorTest { ) }, db = db, - moshi = moshi ) val state = state( @@ -334,7 +328,6 @@ class CachedTimelineRemoteMediatorTest { ) }, db = db, - moshi = moshi ) val state = state( @@ -385,7 +378,6 @@ class CachedTimelineRemoteMediatorTest { ) }, db = db, - moshi = moshi ) val state = state( @@ -441,7 +433,6 @@ class CachedTimelineRemoteMediatorTest { ) }, db = db, - moshi = moshi ) val state = state( @@ -493,7 +484,6 @@ class CachedTimelineRemoteMediatorTest { ) }, db = db, - moshi = moshi ) val state = state( diff --git a/app/src/test/java/com/keylesspalace/tusky/components/timeline/StatusMocker.kt b/app/src/test/java/com/keylesspalace/tusky/components/timeline/StatusMocker.kt index 3f7e868e3..90e13aae2 100644 --- a/app/src/test/java/com/keylesspalace/tusky/components/timeline/StatusMocker.kt +++ b/app/src/test/java/com/keylesspalace/tusky/components/timeline/StatusMocker.kt @@ -5,7 +5,6 @@ import androidx.room.withTransaction import com.keylesspalace.tusky.db.AppDatabase import com.keylesspalace.tusky.db.entity.HomeTimelineData import com.keylesspalace.tusky.db.entity.HomeTimelineEntity -import com.keylesspalace.tusky.di.NetworkModule import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.TimelineAccount import com.keylesspalace.tusky.viewdata.StatusViewData @@ -114,27 +113,23 @@ fun mockHomeTimelineData( authorServerId = authorServerId, domain = domain ) - val moshi = NetworkModule.providesMoshi() return HomeTimelineData( id = id, status = mockedStatus.toEntity( tuskyAccountId = tuskyAccountId, - moshi = moshi, expanded = expanded, contentShowing = false, contentCollapsed = true ), account = mockedStatus.account.toEntity( tuskyAccountId = tuskyAccountId, - moshi = moshi ), reblogAccount = reblogAuthorServerId?.let { reblogAuthorId -> mockAccount( id = reblogAuthorId ).toEntity( tuskyAccountId = tuskyAccountId, - moshi = moshi ) }, loading = false