Add viewed status for news resources to data layer

pull/595/head
James Rose 2 years ago
parent ebdb8589a6
commit 9ee2acf327

@ -50,6 +50,9 @@ class OfflineFirstUserDataRepository @Inject constructor(
)
}
override suspend fun updateNewsResourceViewed(newsResourceId: String, viewed: Boolean) =
niaPreferencesDataSource.toggleNewsResourceViewed(newsResourceId, viewed)
override suspend fun setThemeBrand(themeBrand: ThemeBrand) {
niaPreferencesDataSource.setThemeBrand(themeBrand)
analyticsHelper.logThemeChanged(themeBrand.name)

@ -43,6 +43,11 @@ interface UserDataRepository {
*/
suspend fun updateNewsResourceBookmark(newsResourceId: String, bookmarked: Boolean)
/**
* Updates the viewed status for a news resource
*/
suspend fun updateNewsResourceViewed(newsResourceId: String, viewed: Boolean)
/**
* Sets the desired theme brand.
*/

@ -47,6 +47,9 @@ class FakeUserDataRepository @Inject constructor(
niaPreferencesDataSource.toggleNewsResourceBookmark(newsResourceId, bookmarked)
}
override suspend fun updateNewsResourceViewed(newsResourceId: String, viewed: Boolean) =
niaPreferencesDataSource.toggleNewsResourceViewed(newsResourceId, viewed)
override suspend fun setThemeBrand(themeBrand: ThemeBrand) {
niaPreferencesDataSource.setThemeBrand(themeBrand)
}

@ -66,6 +66,7 @@ class OfflineFirstUserDataRepositoryTest {
assertEquals(
UserData(
bookmarkedNewsResources = emptySet(),
viewedNewsResources = emptySet(),
followedTopics = emptySet(),
themeBrand = ThemeBrand.DEFAULT,
darkThemeConfig = DarkThemeConfig.FOLLOW_SYSTEM,
@ -160,6 +161,37 @@ class OfflineFirstUserDataRepositoryTest {
)
}
@Test
fun offlineFirstUserDataRepository_update_viewed_news_resources_delegates_to_nia_preferences() =
runTest {
subject.updateNewsResourceViewed(newsResourceId = "0", viewed = true)
assertEquals(
setOf("0"),
subject.userData
.map { it.viewedNewsResources }
.first(),
)
subject.updateNewsResourceViewed(newsResourceId = "1", viewed = true)
assertEquals(
setOf("0", "1"),
subject.userData
.map { it.viewedNewsResources }
.first(),
)
assertEquals(
niaPreferencesDataSource.userData
.map { it.viewedNewsResources }
.first(),
subject.userData
.map { it.viewedNewsResources }
.first(),
)
}
@Test
fun offlineFirstUserDataRepository_set_theme_brand_delegates_to_nia_preferences() =
testScope.runTest {

@ -33,6 +33,7 @@ class NiaPreferencesDataSource @Inject constructor(
.map {
UserData(
bookmarkedNewsResources = it.bookmarkedNewsResourceIdsMap.keys,
viewedNewsResources = it.viewedNewsResourceIdsMap.keys,
followedTopics = it.followedTopicIdsMap.keys,
themeBrand = when (it.themeBrand) {
null,
@ -137,6 +138,18 @@ class NiaPreferencesDataSource @Inject constructor(
}
}
suspend fun toggleNewsResourceViewed(newsResourceId: String, viewed: Boolean) {
userPreferences.updateData {
it.copy {
if (viewed) {
viewedNewsResourceIds.put(newsResourceId, true)
} else {
viewedNewsResourceIds.remove(newsResourceId)
}
}
}
}
suspend fun getChangeListVersions() = userPreferences.data
.map {
ChangeListVersions(

@ -40,6 +40,7 @@ message UserPreferences {
map<string, bool> followed_topic_ids = 13;
map<string, bool> followed_author_ids = 14;
map<string, bool> bookmarked_news_resource_ids = 15;
map<string, bool> viewed_news_resource_ids = 20;
ThemeBrandProto theme_brand = 16;
DarkThemeConfigProto dark_theme_config = 17;
@ -47,4 +48,6 @@ message UserPreferences {
bool should_hide_onboarding = 18;
bool use_dynamic_color = 19;
// NEXT AVAILABLE ID: 21
}

@ -35,6 +35,7 @@ data class UserNewsResource internal constructor(
val type: NewsResourceType,
val followableTopics: List<FollowableTopic>,
val isSaved: Boolean,
val isViewed: Boolean,
) {
constructor(newsResource: NewsResource, userData: UserData) : this(
id = newsResource.id,
@ -51,6 +52,7 @@ data class UserNewsResource internal constructor(
)
},
isSaved = userData.bookmarkedNewsResources.contains(newsResource.id),
isViewed = userData.viewedNewsResources.contains(newsResource.id),
)
}

@ -68,6 +68,7 @@ class UserNewsResourceTest {
val userData = UserData(
bookmarkedNewsResources = setOf("N1"),
viewedNewsResources = setOf("N1"),
followedTopics = setOf("T1"),
themeBrand = DEFAULT,
darkThemeConfig = FOLLOW_SYSTEM,

@ -21,6 +21,7 @@ package com.google.samples.apps.nowinandroid.core.model.data
*/
data class UserData(
val bookmarkedNewsResources: Set<String>,
val viewedNewsResources: Set<String>,
val followedTopics: Set<String>,
val themeBrand: ThemeBrand,
val darkThemeConfig: DarkThemeConfig,

@ -30,6 +30,7 @@ import kotlinx.datetime.toInstant
/* ktlint-disable max-line-length */
val userNewsResourcesTestData: List<UserNewsResource> = UserData(
bookmarkedNewsResources = setOf("1", "4"),
viewedNewsResources = setOf("1", "2", "4"),
followedTopics = emptySet(),
themeBrand = ThemeBrand.ANDROID,
darkThemeConfig = DarkThemeConfig.DARK,

@ -27,6 +27,7 @@ import kotlinx.coroutines.flow.filterNotNull
val emptyUserData = UserData(
bookmarkedNewsResources = emptySet(),
viewedNewsResources = emptySet(),
followedTopics = emptySet(),
themeBrand = ThemeBrand.DEFAULT,
darkThemeConfig = DarkThemeConfig.FOLLOW_SYSTEM,
@ -72,6 +73,21 @@ class TestUserDataRepository : UserDataRepository {
}
}
override suspend fun updateNewsResourceViewed(newsResourceId: String, viewed: Boolean) {
currentUserData.let { current ->
_userData.tryEmit(
current.copy(
viewedNewsResources =
if (viewed) {
current.viewedNewsResources + newsResourceId
} else {
current.viewedNewsResources - newsResourceId
},
),
)
}
}
override suspend fun setThemeBrand(themeBrand: ThemeBrand) {
currentUserData.let { current ->
_userData.tryEmit(current.copy(themeBrand = themeBrand))

@ -40,6 +40,7 @@ class UserNewsResourcePreviewParameterProvider : PreviewParameterProvider<List<U
get() {
val userData: UserData = UserData(
bookmarkedNewsResources = setOf("1", "3"),
viewedNewsResources = setOf("1", "2", "4"),
followedTopics = emptySet(),
themeBrand = ThemeBrand.ANDROID,
darkThemeConfig = DarkThemeConfig.DARK,

Loading…
Cancel
Save