Move models back into separate module

Change-Id: Ibe3e115e7618505a51fe34c8ebbf80691d344ad5
dt/clean-arch
Don Turner 10 months ago
parent 80be5c8c59
commit 86e322886a

@ -35,7 +35,7 @@ import androidx.test.espresso.Espresso
import androidx.test.espresso.NoActivityResumedException
import com.google.samples.apps.nowinandroid.MainActivity
import com.google.samples.apps.nowinandroid.R
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.rules.GrantPostNotificationsPermissionRule
import dagger.hilt.android.testing.BindValue

@ -44,8 +44,8 @@ import com.google.samples.apps.nowinandroid.core.analytics.LocalAnalyticsHelper
import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor
import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.repository.UserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.ui.LocalTimeZone
import com.google.samples.apps.nowinandroid.ui.NiaApp

@ -20,7 +20,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.samples.apps.nowinandroid.MainActivityUiState.Loading
import com.google.samples.apps.nowinandroid.MainActivityUiState.Success
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.model.UserData
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.SharingStarted

@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.core.data.test.repository
import com.google.samples.apps.nowinandroid.core.data.model.asEntity
import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceEntity
import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
@ -46,7 +46,7 @@ internal class FakeNewsRepository @Inject constructor(
override fun getNewsResources(
query: NewsResourceQuery,
): Flow<List<NewsResource>> =
): Flow<List<com.google.samples.apps.nowinandroid.core.model.NewsResource>> =
flow {
emit(
datasource

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.data.test.repository
import com.google.samples.apps.nowinandroid.core.domain.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.domain.repository.RecentSearchRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
@ -28,7 +28,7 @@ import javax.inject.Inject
internal class FakeRecentSearchRepository @Inject constructor() : RecentSearchRepository {
override suspend fun insertOrReplaceRecentSearch(searchQuery: String) = Unit
override fun getRecentSearchQueries(limit: Int): Flow<List<RecentSearchQuery>> =
override fun getRecentSearchQueries(limit: Int): Flow<List<com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery>> =
flowOf(emptyList())
override suspend fun clearRecentSearches() = Unit

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.data.test.repository
import com.google.samples.apps.nowinandroid.core.domain.model.SearchResult
import com.google.samples.apps.nowinandroid.core.model.SearchResult
import com.google.samples.apps.nowinandroid.core.domain.repository.SearchContentsRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
@ -28,6 +28,6 @@ import javax.inject.Inject
internal class FakeSearchContentsRepository @Inject constructor() : SearchContentsRepository {
override suspend fun populateFtsData() = Unit
override fun searchContents(searchQuery: String): Flow<SearchResult> = flowOf()
override fun searchContents(searchQuery: String): Flow<com.google.samples.apps.nowinandroid.core.model.SearchResult> = flowOf()
override fun getSearchContentsCount(): Flow<Int> = flowOf(1)
}

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.data.test.repository
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
@ -40,10 +40,10 @@ internal class FakeTopicsRepository @Inject constructor(
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher,
private val datasource: FakeNiaNetworkDataSource,
) : TopicsRepository {
override fun getTopics(): Flow<List<Topic>> = flow {
override fun getTopics(): Flow<List<com.google.samples.apps.nowinandroid.core.model.Topic>> = flow {
emit(
datasource.getTopics().map {
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = it.id,
name = it.name,
shortDescription = it.shortDescription,
@ -55,7 +55,7 @@ internal class FakeTopicsRepository @Inject constructor(
)
}.flowOn(ioDispatcher)
override fun getTopic(id: String): Flow<Topic> = getTopics()
override fun getTopic(id: String): Flow<com.google.samples.apps.nowinandroid.core.model.Topic> = getTopics()
.map { it.first { topic -> topic.id == id } }
override suspend fun syncWith(synchronizer: Synchronizer) = true

@ -17,9 +17,9 @@
package com.google.samples.apps.nowinandroid.core.data.test.repository
import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.UserData
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
@ -34,7 +34,7 @@ internal class FakeUserDataRepository @Inject constructor(
private val niaPreferencesDataSource: NiaPreferencesDataSource,
) : UserDataRepository {
override val userData: Flow<UserData> =
override val userData: Flow<com.google.samples.apps.nowinandroid.core.model.UserData> =
niaPreferencesDataSource.userData
override suspend fun setFollowedTopicIds(followedTopicIds: Set<String>) =
@ -50,11 +50,11 @@ internal class FakeUserDataRepository @Inject constructor(
override suspend fun setNewsResourceViewed(newsResourceId: String, viewed: Boolean) =
niaPreferencesDataSource.setNewsResourceViewed(newsResourceId, viewed)
override suspend fun setThemeBrand(themeBrand: ThemeBrand) {
override suspend fun setThemeBrand(themeBrand: com.google.samples.apps.nowinandroid.core.model.ThemeBrand) {
niaPreferencesDataSource.setThemeBrand(themeBrand)
}
override suspend fun setDarkThemeConfig(darkThemeConfig: DarkThemeConfig) {
override suspend fun setDarkThemeConfig(darkThemeConfig: com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig) {
niaPreferencesDataSource.setDarkThemeConfig(darkThemeConfig)
}

@ -17,9 +17,10 @@
package com.google.samples.apps.nowinandroid.core.data.model
import com.google.samples.apps.nowinandroid.core.database.model.RecentSearchQueryEntity
import com.google.samples.apps.nowinandroid.core.domain.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery
fun RecentSearchQueryEntity.asExternalModel() = RecentSearchQuery(
query = query,
queriedDate = queriedDate,
)
fun RecentSearchQueryEntity.asExternalModel() =
com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery(
query = query,
queriedDate = queriedDate,
)

@ -16,8 +16,8 @@
package com.google.samples.apps.nowinandroid.core.data.repository
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.mapToUserNewsResources
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.mapToUserNewsResources
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
@ -44,7 +44,7 @@ class CompositeUserNewsResourceRepository @Inject constructor(
*/
override fun observeAll(
query: NewsResourceQuery,
): Flow<List<UserNewsResource>> =
): Flow<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>> =
newsRepository.getNewsResources(query)
.combine(userDataRepository.userData) { newsResources, userData ->
newsResources.mapToUserNewsResources(userData)
@ -53,7 +53,7 @@ class CompositeUserNewsResourceRepository @Inject constructor(
/**
* Returns available news resources (joined with user data) for the followed topics.
*/
override fun observeAllForFollowedTopics(): Flow<List<UserNewsResource>> =
override fun observeAllForFollowedTopics(): Flow<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>> =
userDataRepository.userData.map { it.followedTopics }.distinctUntilChanged()
.flatMapLatest { followedTopics ->
when {
@ -62,7 +62,7 @@ class CompositeUserNewsResourceRepository @Inject constructor(
}
}
override fun observeAllBookmarked(): Flow<List<UserNewsResource>> =
override fun observeAllBookmarked(): Flow<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>> =
userDataRepository.userData.map { it.bookmarkedNewsResources }.distinctUntilChanged()
.flatMapLatest { bookmarkedNewsResources ->
when {

@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.core.data.repository
import com.google.samples.apps.nowinandroid.core.data.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryDao
import com.google.samples.apps.nowinandroid.core.database.model.RecentSearchQueryEntity
import com.google.samples.apps.nowinandroid.core.domain.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.domain.repository.RecentSearchRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
@ -38,7 +38,7 @@ internal class DefaultRecentSearchRepository @Inject constructor(
)
}
override fun getRecentSearchQueries(limit: Int): Flow<List<RecentSearchQuery>> =
override fun getRecentSearchQueries(limit: Int): Flow<List<com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery>> =
recentSearchQueryDao.getRecentSearchQueryEntities(limit).map { searchQueries ->
searchQueries.map { it.asExternalModel() }
}

@ -23,7 +23,7 @@ import com.google.samples.apps.nowinandroid.core.database.dao.TopicFtsDao
import com.google.samples.apps.nowinandroid.core.database.model.PopulatedNewsResource
import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.database.model.asFtsEntity
import com.google.samples.apps.nowinandroid.core.domain.model.SearchResult
import com.google.samples.apps.nowinandroid.core.model.SearchResult
import com.google.samples.apps.nowinandroid.core.domain.repository.SearchContentsRepository
import com.google.samples.apps.nowinandroid.core.network.Dispatcher
import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO
@ -59,7 +59,7 @@ internal class DefaultSearchContentsRepository @Inject constructor(
}
}
override fun searchContents(searchQuery: String): Flow<SearchResult> {
override fun searchContents(searchQuery: String): Flow<com.google.samples.apps.nowinandroid.core.model.SearchResult> {
// Surround the query by asterisks to match the query when it's in the middle of
// a word
val newsResourceIds = newsResourceFtsDao.searchAllNewsResources("*$searchQuery*")
@ -76,7 +76,7 @@ internal class DefaultSearchContentsRepository @Inject constructor(
.distinctUntilChanged()
.flatMapLatest(topicDao::getTopicEntities)
return combine(newsResourcesFlow, topicsFlow) { newsResources, topics ->
SearchResult(
com.google.samples.apps.nowinandroid.core.model.SearchResult(
topics = topics.map { it.asExternalModel() },
newsResources = newsResources.map { it.asExternalModel() },
)

@ -26,8 +26,8 @@ import com.google.samples.apps.nowinandroid.core.database.model.PopulatedNewsRes
import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity
import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource
import com.google.samples.apps.nowinandroid.core.domain.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
@ -57,7 +57,7 @@ internal class OfflineFirstNewsRepository @Inject constructor(
override fun getNewsResources(
query: NewsResourceQuery,
): Flow<List<NewsResource>> = newsResourceDao.getNewsResources(
): Flow<List<com.google.samples.apps.nowinandroid.core.model.NewsResource>> = newsResourceDao.getNewsResources(
useFilterTopicIds = query.filterTopicIds != null,
filterTopicIds = query.filterTopicIds ?: emptySet(),
useFilterNewsIds = query.filterNewsIds != null,
@ -68,7 +68,7 @@ internal class OfflineFirstNewsRepository @Inject constructor(
override suspend fun syncWith(synchronizer: Synchronizer): Boolean {
var isFirstSync = false
return synchronizer.changeListSync(
versionReader = ChangeListVersions::newsResourceVersion,
versionReader = com.google.samples.apps.nowinandroid.core.model.ChangeListVersions::newsResourceVersion,
changeListFetcher = { currentVersion ->
isFirstSync = currentVersion <= 0
network.getNewsResourceChangeList(after = currentVersion)

@ -21,8 +21,8 @@ import com.google.samples.apps.nowinandroid.core.data.util.changeListSync
import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao
import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity
import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.domain.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource
@ -40,16 +40,16 @@ internal class OfflineFirstTopicsRepository @Inject constructor(
private val network: NiaNetworkDataSource,
) : TopicsRepository {
override fun getTopics(): Flow<List<Topic>> =
override fun getTopics(): Flow<List<com.google.samples.apps.nowinandroid.core.model.Topic>> =
topicDao.getTopicEntities()
.map { it.map(TopicEntity::asExternalModel) }
override fun getTopic(id: String): Flow<Topic> =
override fun getTopic(id: String): Flow<com.google.samples.apps.nowinandroid.core.model.Topic> =
topicDao.getTopicEntity(id).map { it.asExternalModel() }
override suspend fun syncWith(synchronizer: Synchronizer): Boolean =
synchronizer.changeListSync(
versionReader = ChangeListVersions::topicVersion,
versionReader = com.google.samples.apps.nowinandroid.core.model.ChangeListVersions::topicVersion,
changeListFetcher = { currentVersion ->
network.getTopicChangeList(after = currentVersion)
},

@ -19,9 +19,9 @@ package com.google.samples.apps.nowinandroid.core.data.repository
import androidx.annotation.VisibleForTesting
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.UserData
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
@ -31,7 +31,7 @@ internal class OfflineFirstUserDataRepository @Inject constructor(
private val analyticsHelper: AnalyticsHelper,
) : UserDataRepository {
override val userData: Flow<UserData> =
override val userData: Flow<com.google.samples.apps.nowinandroid.core.model.UserData> =
niaPreferencesDataSource.userData
@VisibleForTesting
@ -54,12 +54,12 @@ internal class OfflineFirstUserDataRepository @Inject constructor(
override suspend fun setNewsResourceViewed(newsResourceId: String, viewed: Boolean) =
niaPreferencesDataSource.setNewsResourceViewed(newsResourceId, viewed)
override suspend fun setThemeBrand(themeBrand: ThemeBrand) {
override suspend fun setThemeBrand(themeBrand: com.google.samples.apps.nowinandroid.core.model.ThemeBrand) {
niaPreferencesDataSource.setThemeBrand(themeBrand)
analyticsHelper.logThemeChanged(themeBrand.name)
}
override suspend fun setDarkThemeConfig(darkThemeConfig: DarkThemeConfig) {
override suspend fun setDarkThemeConfig(darkThemeConfig: com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig) {
niaPreferencesDataSource.setDarkThemeConfig(darkThemeConfig)
analyticsHelper.logDarkThemeConfigChanged(darkThemeConfig.name)
}

@ -17,7 +17,7 @@
package com.google.samples.apps.nowinandroid.core.data.util
import android.util.Log
import com.google.samples.apps.nowinandroid.core.domain.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
import com.google.samples.apps.nowinandroid.core.network.model.NetworkChangeList
import kotlinx.coroutines.flow.Flow
@ -60,9 +60,9 @@ private suspend fun <T> suspendRunCatching(block: suspend () -> T): Result<T> =
* implementation must guarantee this.
*/
suspend fun Synchronizer.changeListSync(
versionReader: (ChangeListVersions) -> Int,
versionReader: (com.google.samples.apps.nowinandroid.core.model.ChangeListVersions) -> Int,
changeListFetcher: suspend (Int) -> List<NetworkChangeList>,
versionUpdater: ChangeListVersions.(Int) -> ChangeListVersions,
versionUpdater: com.google.samples.apps.nowinandroid.core.model.ChangeListVersions.(Int) -> com.google.samples.apps.nowinandroid.core.model.ChangeListVersions,
modelDeleter: suspend (List<String>) -> Unit,
modelUpdater: suspend (List<String>) -> Unit,
) = suspendRunCatching {

@ -17,9 +17,9 @@
package com.google.samples.apps.nowinandroid.core.data
import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.model.mapToUserNewsResources
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.model.mapToUserNewsResources
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository
import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository
@ -134,7 +134,7 @@ class CompositeUserNewsResourceRepositoryTest {
}
}
private val sampleTopic1 = Topic(
private val sampleTopic1 = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "Topic1",
name = "Headlines",
shortDescription = "",
@ -143,7 +143,7 @@ private val sampleTopic1 = Topic(
imageUrl = "image URL",
)
private val sampleTopic2 = Topic(
private val sampleTopic2 = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "Topic2",
name = "UI",
shortDescription = "",
@ -153,7 +153,7 @@ private val sampleTopic2 = Topic(
)
private val sampleNewsResources = listOf(
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "1",
title = "Thanks for helping us reach 1M YouTube Subscribers",
content = "Thank you everyone for following the Now in Android series and everything the " +
@ -166,7 +166,7 @@ private val sampleNewsResources = listOf(
type = "Video 📺",
topics = listOf(sampleTopic1),
),
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "2",
title = "Transformations and customisations in the Paging Library",
content = "A demonstration of different operations that can be performed with Paging. " +
@ -178,7 +178,7 @@ private val sampleNewsResources = listOf(
type = "Video 📺",
topics = listOf(sampleTopic1, sampleTopic2),
),
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "3",
title = "Community tip on Paging",
content = "Tips for using the Paging library from the developer community",

@ -16,13 +16,13 @@
package com.google.samples.apps.nowinandroid.core.data
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.FOLLOW_SYSTEM
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.FOLLOW_SYSTEM
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.model.UserData
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import kotlinx.datetime.Clock.System
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
@ -37,7 +37,7 @@ class UserNewsResourceTest {
*/
@Test
fun userNewsResourcesAreConstructedFromNewsResourcesAndUserData() {
val newsResource1 = NewsResource(
val newsResource1 = com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "N1",
title = "Test news title",
content = "Test news content",
@ -46,7 +46,7 @@ class UserNewsResourceTest {
publishDate = System.now(),
type = "Article 📚",
topics = listOf(
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "T1",
name = "Topic 1",
shortDescription = "Topic 1 short description",
@ -54,7 +54,7 @@ class UserNewsResourceTest {
url = "Topic 1 URL",
imageUrl = "Topic 1 image URL",
),
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "T2",
name = "Topic 2",
shortDescription = "Topic 2 short description",
@ -65,7 +65,7 @@ class UserNewsResourceTest {
),
)
val userData = UserData(
val userData = com.google.samples.apps.nowinandroid.core.model.UserData(
bookmarkedNewsResources = setOf("N1"),
viewedNewsResources = setOf("N1"),
followedTopics = setOf("T1"),
@ -75,7 +75,10 @@ class UserNewsResourceTest {
shouldHideOnboarding = true,
)
val userNewsResource = UserNewsResource(newsResource1, userData)
val userNewsResource = com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource1,
userData
)
// Check that the simple field mappings have been done correctly.
assertEquals(newsResource1.id, userNewsResource.id)
@ -89,7 +92,7 @@ class UserNewsResourceTest {
assertEquals(newsResource1.topics.size, userNewsResource.followableTopics.size)
for (topic in newsResource1.topics) {
// Construct the expected FollowableTopic.
val followableTopic = FollowableTopic(
val followableTopic = com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = topic,
isFollowed = topic.id in userData.followedTopics,
)

@ -32,8 +32,8 @@ import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity
import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource
import com.google.samples.apps.nowinandroid.core.datastore.test.testUserPreferencesDataStore
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
import com.google.samples.apps.nowinandroid.core.network.model.NetworkChangeList
@ -150,8 +150,8 @@ class OfflineFirstNewsRepositoryTest {
.map(PopulatedNewsResource::asExternalModel)
assertEquals(
newsResourcesFromNetwork.map(NewsResource::id).sorted(),
newsResourcesFromDb.map(NewsResource::id).sorted(),
newsResourcesFromNetwork.map(com.google.samples.apps.nowinandroid.core.model.NewsResource::id).sorted(),
newsResourcesFromDb.map(com.google.samples.apps.nowinandroid.core.model.NewsResource::id).sorted(),
)
// After sync version should be updated
@ -176,7 +176,7 @@ class OfflineFirstNewsRepositoryTest {
// Delete half of the items on the network
val deletedItems = newsResourcesFromNetwork
.map(NewsResource::id)
.map(com.google.samples.apps.nowinandroid.core.model.NewsResource::id)
.partition { it.chars().sum() % 2 == 0 }
.first
.toSet()
@ -197,8 +197,8 @@ class OfflineFirstNewsRepositoryTest {
// Assert that items marked deleted on the network have been deleted locally
assertEquals(
expected = (newsResourcesFromNetwork.map(NewsResource::id) - deletedItems).sorted(),
actual = newsResourcesFromDb.map(NewsResource::id).sorted(),
expected = (newsResourcesFromNetwork.map(com.google.samples.apps.nowinandroid.core.model.NewsResource::id) - deletedItems).sorted(),
actual = newsResourcesFromDb.map(com.google.samples.apps.nowinandroid.core.model.NewsResource::id).sorted(),
)
// After sync version should be updated
@ -242,8 +242,8 @@ class OfflineFirstNewsRepositoryTest {
.map(PopulatedNewsResource::asExternalModel)
assertEquals(
expected = newsResourcesFromNetwork.map(NewsResource::id).sorted(),
actual = newsResourcesFromDb.map(NewsResource::id).sorted(),
expected = newsResourcesFromNetwork.map(com.google.samples.apps.nowinandroid.core.model.NewsResource::id).sorted(),
actual = newsResourcesFromDb.map(com.google.samples.apps.nowinandroid.core.model.NewsResource::id).sorted(),
)
// After sync version should be updated
@ -349,7 +349,7 @@ class OfflineFirstNewsRepositoryTest {
// that the user follows
assertEquals(
expected = followedNewsResourceIdsFromNetwork,
actual = notifier.addedNewsResources.first().map(NewsResource::id).sorted(),
actual = notifier.addedNewsResources.first().map(com.google.samples.apps.nowinandroid.core.model.NewsResource::id).sorted(),
)
}
@ -369,8 +369,8 @@ class OfflineFirstNewsRepositoryTest {
newsResourceDao.upsertNewsResources(networkNewsResources)
val followedTopicIds = newsResources
.flatMap(NewsResource::topics)
.map(Topic::id)
.flatMap(com.google.samples.apps.nowinandroid.core.model.NewsResource::topics)
.map(com.google.samples.apps.nowinandroid.core.model.Topic::id)
.toSet()
// Follow all topics

@ -25,7 +25,7 @@ import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity
import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel
import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource
import com.google.samples.apps.nowinandroid.core.datastore.test.testUserPreferencesDataStore
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic
import kotlinx.coroutines.flow.first
@ -144,7 +144,7 @@ class OfflineFirstTopicsRepositoryTest {
// Delete half of the items on the network
val deletedItems = networkTopics
.map(Topic::id)
.map(com.google.samples.apps.nowinandroid.core.model.Topic::id)
.partition { it.chars().sum() % 2 == 0 }
.first
.toSet()
@ -165,8 +165,8 @@ class OfflineFirstTopicsRepositoryTest {
// Assert that items marked deleted on the network have been deleted locally
assertEquals(
networkTopics.map(Topic::id) - deletedItems,
dbTopics.map(Topic::id),
networkTopics.map(com.google.samples.apps.nowinandroid.core.model.Topic::id) - deletedItems,
dbTopics.map(com.google.samples.apps.nowinandroid.core.model.Topic::id),
)
// After sync version should be updated

@ -19,11 +19,11 @@ package com.google.samples.apps.nowinandroid.core.data.repository
import com.google.samples.apps.nowinandroid.core.analytics.NoOpAnalyticsHelper
import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource
import com.google.samples.apps.nowinandroid.core.datastore.test.testUserPreferencesDataStore
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.FOLLOW_SYSTEM
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.FOLLOW_SYSTEM
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.core.model.UserData
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.test.TestScope
@ -66,7 +66,7 @@ class OfflineFirstUserDataRepositoryTest {
fun offlineFirstUserDataRepository_default_user_data_is_correct() =
testScope.runTest {
assertEquals(
UserData(
com.google.samples.apps.nowinandroid.core.model.UserData(
bookmarkedNewsResources = emptySet(),
viewedNewsResources = emptySet(),
followedTopics = emptySet(),
@ -197,16 +197,16 @@ class OfflineFirstUserDataRepositoryTest {
@Test
fun offlineFirstUserDataRepository_set_theme_brand_delegates_to_nia_preferences() =
testScope.runTest {
subject.setThemeBrand(ThemeBrand.ANDROID)
subject.setThemeBrand(com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID)
assertEquals(
ThemeBrand.ANDROID,
com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID,
subject.userData
.map { it.themeBrand }
.first(),
)
assertEquals(
ThemeBrand.ANDROID,
com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID,
niaPreferencesDataSource
.userData
.map { it.themeBrand }
@ -237,16 +237,16 @@ class OfflineFirstUserDataRepositoryTest {
@Test
fun offlineFirstUserDataRepository_set_dark_theme_config_delegates_to_nia_preferences() =
testScope.runTest {
subject.setDarkThemeConfig(DarkThemeConfig.DARK)
subject.setDarkThemeConfig(com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK)
assertEquals(
DarkThemeConfig.DARK,
com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK,
subject.userData
.map { it.darkThemeConfig }
.first(),
)
assertEquals(
DarkThemeConfig.DARK,
com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK,
niaPreferencesDataSource
.userData
.map { it.darkThemeConfig }

@ -17,7 +17,7 @@
package com.google.samples.apps.nowinandroid.core.data.repository
import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource
import com.google.samples.apps.nowinandroid.core.domain.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
/**
@ -26,10 +26,10 @@ import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
class TestSynchronizer(
private val niaPreferences: NiaPreferencesDataSource,
) : Synchronizer {
override suspend fun getChangeListVersions(): ChangeListVersions =
override suspend fun getChangeListVersions(): com.google.samples.apps.nowinandroid.core.model.ChangeListVersions =
niaPreferences.getChangeListVersions()
override suspend fun updateChangeListVersions(
update: ChangeListVersions.() -> ChangeListVersions,
update: com.google.samples.apps.nowinandroid.core.model.ChangeListVersions.() -> com.google.samples.apps.nowinandroid.core.model.ChangeListVersions,
) = niaPreferences.updateChangeListVersion(update)
}

@ -16,8 +16,8 @@
package com.google.samples.apps.nowinandroid.core.database.model
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.Topic
import kotlinx.datetime.Instant
import org.junit.Test
import kotlin.test.assertEquals
@ -49,7 +49,7 @@ class PopulatedNewsResourceKtTest {
val newsResource = populatedNewsResource.asExternalModel()
assertEquals(
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "1",
title = "news",
content = "Hilt",
@ -58,7 +58,7 @@ class PopulatedNewsResourceKtTest {
type = "Video 📺",
publishDate = Instant.fromEpochMilliseconds(1),
topics = listOf(
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "3",
name = "name",
shortDescription = "short description",

@ -30,7 +30,7 @@ android {
}
dependencies {
api(projects.core.domain)
api(projects.core.model)
implementation(libs.kotlinx.datetime)

@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.core.database.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import kotlinx.datetime.Instant
/**
@ -42,7 +42,7 @@ data class NewsResourceEntity(
)
fun NewsResourceEntity.asExternalModel() =
com.google.samples.apps.nowinandroid.core.domain.model.NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = id,
title = title,
content = content,

@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.core.database.model
import androidx.room.Embedded
import androidx.room.Junction
import androidx.room.Relation
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.NewsResource
/**
* External data layer representation of a fully populated NiA news resource
@ -40,7 +40,7 @@ data class PopulatedNewsResource(
)
fun PopulatedNewsResource.asExternalModel() =
com.google.samples.apps.nowinandroid.core.domain.model.NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = entity.id,
title = entity.title,
content = entity.content,

@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.core.database.model
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.Topic
/**
* Defines a topic a user may follow.
@ -41,7 +41,7 @@ data class TopicEntity(
val imageUrl: String,
)
fun TopicEntity.asExternalModel() = com.google.samples.apps.nowinandroid.core.domain.model.Topic(
fun TopicEntity.asExternalModel() = com.google.samples.apps.nowinandroid.core.model.Topic(
id = id,
name = name,
shortDescription = shortDescription,

@ -35,7 +35,7 @@ android {
dependencies {
api(libs.androidx.dataStore.core)
api(projects.core.datastoreProto)
api(projects.core.domain)
api(projects.core.model)
implementation(projects.core.common)

@ -26,10 +26,10 @@ import com.google.samples.apps.nowinandroid.core.datastore.ThemeBrandProto.THEME
import com.google.samples.apps.nowinandroid.core.datastore.ThemeBrandProto.THEME_BRAND_DEFAULT
import com.google.samples.apps.nowinandroid.core.datastore.ThemeBrandProto.THEME_BRAND_UNSPECIFIED
import com.google.samples.apps.nowinandroid.core.datastore.ThemeBrandProto.UNRECOGNIZED
import com.google.samples.apps.nowinandroid.core.domain.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.UserData
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.map
import java.io.IOException
@ -40,7 +40,7 @@ class NiaPreferencesDataSource @Inject constructor(
) {
val userData = userPreferences.data
.map {
com.google.samples.apps.nowinandroid.core.domain.model.UserData(
com.google.samples.apps.nowinandroid.core.model.UserData(
bookmarkedNewsResources = it.bookmarkedNewsResourceIdsMap.keys,
viewedNewsResources = it.viewedNewsResourceIdsMap.keys,
followedTopics = it.followedTopicIdsMap.keys,
@ -49,9 +49,9 @@ class NiaPreferencesDataSource @Inject constructor(
THEME_BRAND_UNSPECIFIED,
UNRECOGNIZED,
THEME_BRAND_DEFAULT,
-> com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.DEFAULT
-> com.google.samples.apps.nowinandroid.core.model.ThemeBrand.DEFAULT
THEME_BRAND_ANDROID -> com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.ANDROID
THEME_BRAND_ANDROID -> com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID
},
darkThemeConfig = when (it.darkThemeConfig) {
null,
@ -59,12 +59,12 @@ class NiaPreferencesDataSource @Inject constructor(
DarkThemeConfigProto.UNRECOGNIZED,
DARK_THEME_CONFIG_FOLLOW_SYSTEM,
->
com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.FOLLOW_SYSTEM
com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.FOLLOW_SYSTEM
DARK_THEME_CONFIG_LIGHT ->
com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.LIGHT
com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.LIGHT
DARK_THEME_CONFIG_DARK -> com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.DARK
DARK_THEME_CONFIG_DARK -> com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK
},
useDynamicColor = it.useDynamicColor,
shouldHideOnboarding = it.shouldHideOnboarding,
@ -102,12 +102,12 @@ class NiaPreferencesDataSource @Inject constructor(
}
}
suspend fun setThemeBrand(themeBrand: com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand) {
suspend fun setThemeBrand(themeBrand: com.google.samples.apps.nowinandroid.core.model.ThemeBrand) {
userPreferences.updateData {
it.copy {
this.themeBrand = when (themeBrand) {
com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.DEFAULT -> ThemeBrandProto.THEME_BRAND_DEFAULT
com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.ANDROID -> ThemeBrandProto.THEME_BRAND_ANDROID
com.google.samples.apps.nowinandroid.core.model.ThemeBrand.DEFAULT -> ThemeBrandProto.THEME_BRAND_DEFAULT
com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID -> ThemeBrandProto.THEME_BRAND_ANDROID
}
}
}
@ -119,14 +119,14 @@ class NiaPreferencesDataSource @Inject constructor(
}
}
suspend fun setDarkThemeConfig(darkThemeConfig: com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig) {
suspend fun setDarkThemeConfig(darkThemeConfig: com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig) {
userPreferences.updateData {
it.copy {
this.darkThemeConfig = when (darkThemeConfig) {
com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.FOLLOW_SYSTEM ->
com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.FOLLOW_SYSTEM ->
DarkThemeConfigProto.DARK_THEME_CONFIG_FOLLOW_SYSTEM
com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.LIGHT -> DarkThemeConfigProto.DARK_THEME_CONFIG_LIGHT
com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.DARK -> DarkThemeConfigProto.DARK_THEME_CONFIG_DARK
com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.LIGHT -> DarkThemeConfigProto.DARK_THEME_CONFIG_LIGHT
com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK -> DarkThemeConfigProto.DARK_THEME_CONFIG_DARK
}
}
}
@ -168,21 +168,21 @@ class NiaPreferencesDataSource @Inject constructor(
suspend fun getChangeListVersions() = userPreferences.data
.map {
ChangeListVersions(
com.google.samples.apps.nowinandroid.core.model.ChangeListVersions(
topicVersion = it.topicChangeListVersion,
newsResourceVersion = it.newsResourceChangeListVersion,
)
}
.firstOrNull() ?: ChangeListVersions()
.firstOrNull() ?: com.google.samples.apps.nowinandroid.core.model.ChangeListVersions()
/**
* Update the [ChangeListVersions] using [update].
*/
suspend fun updateChangeListVersion(update: ChangeListVersions.() -> ChangeListVersions) {
suspend fun updateChangeListVersion(update: com.google.samples.apps.nowinandroid.core.model.ChangeListVersions.() -> com.google.samples.apps.nowinandroid.core.model.ChangeListVersions) {
try {
userPreferences.updateData { currentPreferences ->
val updatedChangeListVersions = update(
ChangeListVersions(
com.google.samples.apps.nowinandroid.core.model.ChangeListVersions(
topicVersion = currentPreferences.topicChangeListVersion,
newsResourceVersion = currentPreferences.newsResourceChangeListVersion,
),

@ -25,6 +25,7 @@ android {
dependencies {
api(libs.kotlinx.datetime)
implementation(projects.core.model)
implementation(libs.javax.inject)

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.domain.repository
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.utils.Syncable
import kotlinx.coroutines.flow.Flow
@ -46,5 +46,5 @@ interface NewsRepository : Syncable {
filterTopicIds = null,
filterNewsIds = null,
),
): Flow<List<NewsResource>>
): Flow<List<com.google.samples.apps.nowinandroid.core.model.NewsResource>>
}

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.domain.repository
import com.google.samples.apps.nowinandroid.core.domain.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery
import kotlinx.coroutines.flow.Flow
/**
@ -27,7 +27,7 @@ interface RecentSearchRepository {
/**
* Get the recent search queries up to the number of queries specified as [limit].
*/
fun getRecentSearchQueries(limit: Int): Flow<List<RecentSearchQuery>>
fun getRecentSearchQueries(limit: Int): Flow<List<com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery>>
/**
* Insert or replace the [searchQuery] as part of the recent searches.

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.domain.repository
import com.google.samples.apps.nowinandroid.core.domain.model.SearchResult
import com.google.samples.apps.nowinandroid.core.model.SearchResult
import kotlinx.coroutines.flow.Flow
/**
@ -32,7 +32,7 @@ interface SearchContentsRepository {
/**
* Query the contents matched with the [searchQuery] and returns it as a [Flow] of [SearchResult]
*/
fun searchContents(searchQuery: String): Flow<SearchResult>
fun searchContents(searchQuery: String): Flow<com.google.samples.apps.nowinandroid.core.model.SearchResult>
fun getSearchContentsCount(): Flow<Int>
}

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.domain.repository
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.utils.Syncable
import kotlinx.coroutines.flow.Flow
@ -24,10 +24,10 @@ interface TopicsRepository : Syncable {
/**
* Gets the available topics as a stream
*/
fun getTopics(): Flow<List<Topic>>
fun getTopics(): Flow<List<com.google.samples.apps.nowinandroid.core.model.Topic>>
/**
* Gets data for a specific topic
*/
fun getTopic(id: String): Flow<Topic>
fun getTopic(id: String): Flow<com.google.samples.apps.nowinandroid.core.model.Topic>
}

@ -16,9 +16,9 @@
package com.google.samples.apps.nowinandroid.core.domain.repository
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.UserData
import kotlinx.coroutines.flow.Flow
interface UserDataRepository {
@ -26,7 +26,7 @@ interface UserDataRepository {
/**
* Stream of [UserData]
*/
val userData: Flow<UserData>
val userData: Flow<com.google.samples.apps.nowinandroid.core.model.UserData>
/**
* Sets the user's currently followed topics
@ -51,12 +51,12 @@ interface UserDataRepository {
/**
* Sets the desired theme brand.
*/
suspend fun setThemeBrand(themeBrand: ThemeBrand)
suspend fun setThemeBrand(themeBrand: com.google.samples.apps.nowinandroid.core.model.ThemeBrand)
/**
* Sets the desired dark theme config.
*/
suspend fun setDarkThemeConfig(darkThemeConfig: DarkThemeConfig)
suspend fun setDarkThemeConfig(darkThemeConfig: com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig)
/**
* Sets the preferred dynamic color config.

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.domain.repository
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import kotlinx.coroutines.flow.Flow
/**
@ -31,15 +31,15 @@ interface UserNewsResourceRepository {
filterTopicIds = null,
filterNewsIds = null,
),
): Flow<List<UserNewsResource>>
): Flow<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>>
/**
* Returns available news resources for the user's followed topics as a stream.
*/
fun observeAllForFollowedTopics(): Flow<List<UserNewsResource>>
fun observeAllForFollowedTopics(): Flow<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>>
/**
* Returns the user's bookmarked news resources as a stream.
*/
fun observeAllBookmarked(): Flow<List<UserNewsResource>>
fun observeAllBookmarked(): Flow<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>>
}

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.domain.usecase
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.core.domain.usecase.TopicSortField.NAME
@ -37,13 +37,13 @@ class GetFollowableTopicsUseCase @Inject constructor(
*
* @param sortBy - the field used to sort the topics. Default NONE = no sorting.
*/
operator fun invoke(sortBy: TopicSortField = NONE): Flow<List<FollowableTopic>> = combine(
operator fun invoke(sortBy: TopicSortField = NONE): Flow<List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic>> = combine(
userDataRepository.userData,
topicsRepository.getTopics(),
) { userData, topics ->
val followedTopics = topics
.map { topic ->
FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = topic,
isFollowed = topic.id in userData.followedTopics,
)

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.domain.usecase
import com.google.samples.apps.nowinandroid.core.domain.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.domain.repository.RecentSearchRepository
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
@ -27,6 +27,6 @@ import javax.inject.Inject
class GetRecentSearchQueriesUseCase @Inject constructor(
private val recentSearchRepository: RecentSearchRepository,
) {
operator fun invoke(limit: Int = 10): Flow<List<RecentSearchQuery>> =
operator fun invoke(limit: Int = 10): Flow<List<com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery>> =
recentSearchRepository.getRecentSearchQueries(limit)
}

@ -16,11 +16,11 @@
package com.google.samples.apps.nowinandroid.core.domain.usecase
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.SearchResult
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.UserSearchResult
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.SearchResult
import com.google.samples.apps.nowinandroid.core.model.UserData
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.UserSearchResult
import com.google.samples.apps.nowinandroid.core.domain.repository.SearchContentsRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
import kotlinx.coroutines.flow.Flow
@ -37,22 +37,22 @@ class GetSearchContentsUseCase @Inject constructor(
operator fun invoke(
searchQuery: String,
): Flow<UserSearchResult> =
): Flow<com.google.samples.apps.nowinandroid.core.model.UserSearchResult> =
searchContentsRepository.searchContents(searchQuery)
.mapToUserSearchResult(userDataRepository.userData)
}
private fun Flow<SearchResult>.mapToUserSearchResult(userDataStream: Flow<UserData>): Flow<UserSearchResult> =
private fun Flow<com.google.samples.apps.nowinandroid.core.model.SearchResult>.mapToUserSearchResult(userDataStream: Flow<com.google.samples.apps.nowinandroid.core.model.UserData>): Flow<com.google.samples.apps.nowinandroid.core.model.UserSearchResult> =
combine(userDataStream) { searchResult, userData ->
UserSearchResult(
com.google.samples.apps.nowinandroid.core.model.UserSearchResult(
topics = searchResult.topics.map { topic ->
FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = topic,
isFollowed = topic.id in userData.followedTopics,
)
},
newsResources = searchResult.newsResources.map { news ->
UserNewsResource(
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = news,
userData = userData,
)

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.domain.utils
import com.google.samples.apps.nowinandroid.core.domain.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.model.ChangeListVersions
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
@ -25,9 +25,9 @@ import kotlinx.coroutines.flow.combine
* source for a [Syncable].
*/
interface Synchronizer {
suspend fun getChangeListVersions(): ChangeListVersions
suspend fun getChangeListVersions(): com.google.samples.apps.nowinandroid.core.model.ChangeListVersions
suspend fun updateChangeListVersions(update: ChangeListVersions.() -> ChangeListVersions)
suspend fun updateChangeListVersions(update: com.google.samples.apps.nowinandroid.core.model.ChangeListVersions.() -> com.google.samples.apps.nowinandroid.core.model.ChangeListVersions)
/**
* Syntactic sugar to call [Syncable.syncWith] while omitting the synchronizer argument

@ -16,8 +16,8 @@
package com.google.samples.apps.nowinandroid.core.domain
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.usecase.GetFollowableTopicsUseCase
import com.google.samples.apps.nowinandroid.core.domain.usecase.TopicSortField.NAME
import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository
@ -54,9 +54,18 @@ class GetFollowableTopicsUseCaseTest {
// Check that the order hasn't changed and that the correct topics are marked as followed.
assertEquals(
listOf(
FollowableTopic(testTopics[0], true),
FollowableTopic(testTopics[1], false),
FollowableTopic(testTopics[2], true),
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
testTopics[0],
true
),
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
testTopics[1],
false
),
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
testTopics[2],
true
),
),
followableTopics.first(),
)
@ -79,14 +88,14 @@ class GetFollowableTopicsUseCaseTest {
testTopics
.sortedBy { it.name }
.map {
FollowableTopic(it, false)
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(it, false)
},
)
}
}
private val testTopics = listOf(
Topic("1", "Headlines", "", "", "", ""),
Topic("2", "Android Studio", "", "", "", ""),
Topic("3", "Compose", "", "", "", ""),
com.google.samples.apps.nowinandroid.core.model.Topic("1", "Headlines", "", "", "", ""),
com.google.samples.apps.nowinandroid.core.model.Topic("2", "Android Studio", "", "", "", ""),
com.google.samples.apps.nowinandroid.core.model.Topic("3", "Compose", "", "", "", ""),
)

@ -1,5 +1,5 @@
/*
* Copyright 2022 The Android Open Source Project
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
/**
* Class summarizing the local version of each model for sync

@ -1,5 +1,5 @@
/*
* Copyright 2022 The Android Open Source Project
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
enum class DarkThemeConfig {
FOLLOW_SYSTEM,

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
/**
* A [topic] with the additional information for whether or not it is followed.

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
import kotlinx.datetime.Instant

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
/** An entity that holds the search result */
data class SearchResult(

@ -1,5 +1,5 @@
/*
* Copyright 2022 The Android Open Source Project
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
enum class ThemeBrand {
DEFAULT,

@ -1,5 +1,5 @@
/*
* Copyright 2022 The Android Open Source Project
* Copyright 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
/**
* External data layer representation of a NiA Topic

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
/**
* Class summarizing user interest data

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
import kotlinx.datetime.Instant

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.samples.apps.nowinandroid.core.domain.model
package com.google.samples.apps.nowinandroid.core.model
/**
* An entity of [SearchResult] with additional user information such as whether the user is

@ -41,7 +41,7 @@ secrets {
dependencies {
api(libs.kotlinx.datetime)
api(projects.core.common)
api(projects.core.domain)
api(projects.core.model)
implementation(libs.coil.kt)
implementation(libs.coil.kt.svg)

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.network.model
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.Topic
import kotlinx.serialization.Serializable
/**

@ -23,8 +23,7 @@ android {
}
dependencies {
api(projects.core.domain)
implementation(projects.core.model)
implementation(projects.core.common)
compileOnly(platform(libs.androidx.compose.bom))

@ -16,12 +16,12 @@
package com.google.samples.apps.nowinandroid.core.notifications
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import javax.inject.Inject
/**
* Implementation of [Notifier] which does nothing. Useful for tests and previews.
*/
internal class NoOpNotifier @Inject constructor() : Notifier {
override fun postNewsNotifications(newsResources: List<com.google.samples.apps.nowinandroid.core.domain.model.NewsResource>) = Unit
override fun postNewsNotifications(newsResources: List<com.google.samples.apps.nowinandroid.core.model.NewsResource>) = Unit
}

@ -16,11 +16,11 @@
package com.google.samples.apps.nowinandroid.core.notifications
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.NewsResource
/**
* Interface for creating notifications in the app
*/
interface Notifier {
fun postNewsNotifications(newsResources: List<com.google.samples.apps.nowinandroid.core.domain.model.NewsResource>)
fun postNewsNotifications(newsResources: List<com.google.samples.apps.nowinandroid.core.model.NewsResource>)
}

@ -32,7 +32,7 @@ import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.InboxStyle
import androidx.core.app.NotificationManagerCompat
import androidx.core.net.toUri
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
@ -55,7 +55,7 @@ internal class SystemTrayNotifier @Inject constructor(
) : Notifier {
override fun postNewsNotifications(
newsResources: List<com.google.samples.apps.nowinandroid.core.domain.model.NewsResource>,
newsResources: List<com.google.samples.apps.nowinandroid.core.model.NewsResource>,
) = with(context) {
if (checkSelfPermission(this, permission.POST_NOTIFICATIONS) != PERMISSION_GRANTED) {
return
@ -108,7 +108,7 @@ internal class SystemTrayNotifier @Inject constructor(
* Creates an inbox style summary notification for news updates
*/
private fun newsNotificationStyle(
newsResources: List<com.google.samples.apps.nowinandroid.core.domain.model.NewsResource>,
newsResources: List<com.google.samples.apps.nowinandroid.core.model.NewsResource>,
title: String,
): InboxStyle = newsResources
.fold(InboxStyle()) { inboxStyle, newsResource -> inboxStyle.addLine(newsResource.title) }
@ -150,7 +150,7 @@ private fun Context.ensureNotificationChannelExists() {
}
private fun Context.newsPendingIntent(
newsResource: com.google.samples.apps.nowinandroid.core.domain.model.NewsResource,
newsResource: com.google.samples.apps.nowinandroid.core.model.NewsResource,
): PendingIntent? = PendingIntent.getActivity(
this,
NEWS_NOTIFICATION_REQUEST_CODE,
@ -165,4 +165,4 @@ private fun Context.newsPendingIntent(
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
)
private fun com.google.samples.apps.nowinandroid.core.domain.model.NewsResource.newsDeepLinkUri() = "$DEEP_LINK_SCHEME_AND_HOST/$FOR_YOU_PATH/$id".toUri()
private fun com.google.samples.apps.nowinandroid.core.model.NewsResource.newsDeepLinkUri() = "$DEEP_LINK_SCHEME_AND_HOST/$FOR_YOU_PATH/$id".toUri()

@ -18,12 +18,12 @@
package com.google.samples.apps.nowinandroid.core.testing.data
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.Topic
val followableTopicTestData: List<FollowableTopic> = listOf(
FollowableTopic(
topic = Topic(
val followableTopicTestData: List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic> = listOf(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = "Headlines",
shortDescription = "News we want everyone to see",
@ -33,8 +33,8 @@ val followableTopicTestData: List<FollowableTopic> = listOf(
),
isFollowed = false,
),
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "3",
name = "UI",
shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets",
@ -44,8 +44,8 @@ val followableTopicTestData: List<FollowableTopic> = listOf(
),
isFollowed = true,
),
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "4",
name = "Testing",
shortDescription = "CI, Espresso, TestLab, etc",

@ -18,11 +18,11 @@
package com.google.samples.apps.nowinandroid.core.testing.data
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import kotlinx.datetime.Instant
val newsResourcesTestData: List<NewsResource> = listOf(
NewsResource(
val newsResourcesTestData: List<com.google.samples.apps.nowinandroid.core.model.NewsResource> = listOf(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "1",
title = "Android Basics with Compose",
content = "We released the first two units of Android Basics with Compose, our first free course that teaches Android Development with Jetpack Compose to anyone; you do not need any prior programming experience other than basic computer literacy to get started. Youll learn the fundamentals of programming in Kotlin while building Android apps using Jetpack Compose, Androids modern toolkit that simplifies and accelerates native UI development. These two units are just the beginning; more will be coming soon. Check out Android Basics with Compose to get started on your Android development journey",
@ -32,7 +32,7 @@ val newsResourcesTestData: List<NewsResource> = listOf(
type = "Codelab",
topics = listOf(topicsTestData[1]),
),
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "2",
title = "Thanks for helping us reach 1M YouTube Subscribers",
content = "Thank you everyone for following the Now in Android series and everything the " +
@ -45,7 +45,7 @@ val newsResourcesTestData: List<NewsResource> = listOf(
type = "Video 📺",
topics = listOf(topicsTestData[0], topicsTestData[1]),
),
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "3",
title = "Transformations and customisations in the Paging Library",
content = "A demonstration of different operations that can be performed " +
@ -58,7 +58,7 @@ val newsResourcesTestData: List<NewsResource> = listOf(
type = "Video 📺",
topics = listOf(topicsTestData[2]),
),
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "4",
title = "New Jetpack Release",
content = "New Jetpack release includes updates to libraries such as CameraX, Benchmark, and" +

@ -18,10 +18,10 @@
package com.google.samples.apps.nowinandroid.core.testing.data
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.Topic
val topicsTestData: List<Topic> = listOf(
Topic(
val topicsTestData: List<com.google.samples.apps.nowinandroid.core.model.Topic> = listOf(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = "Headlines",
shortDescription = "News we want everyone to see",
@ -29,7 +29,7 @@ val topicsTestData: List<Topic> = listOf(
imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_Headlines.svg?alt=media&token=506faab0-617a-4668-9e63-4a2fb996603f",
url = "",
),
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "3",
name = "UI",
shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets",
@ -37,7 +37,7 @@ val topicsTestData: List<Topic> = listOf(
imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594",
url = "",
),
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "4",
name = "Testing",
shortDescription = "CI, Espresso, TestLab, etc",

@ -18,17 +18,17 @@
package com.google.samples.apps.nowinandroid.core.testing.data
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.model.UserData
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toInstant
val userNewsResourcesTestData: List<UserNewsResource> = UserData(
val userNewsResourcesTestData: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource> = com.google.samples.apps.nowinandroid.core.model.UserData(
bookmarkedNewsResources = setOf("1", "4"),
viewedNewsResources = setOf("1", "2", "4"),
followedTopics = emptySet(),
@ -38,8 +38,8 @@ val userNewsResourcesTestData: List<UserNewsResource> = UserData(
useDynamicColor = false,
).let { userData ->
listOf(
UserNewsResource(
newsResource = NewsResource(
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "1",
title = "Android Basics with Compose",
content = "We released the first two units of Android Basics with Compose, our first free course that teaches Android Development with Jetpack Compose to anyone; you do not need any prior programming experience other than basic computer literacy to get started. Youll learn the fundamentals of programming in Kotlin while building Android apps using Jetpack Compose, Androids modern toolkit that simplifies and accelerates native UI development. These two units are just the beginning; more will be coming soon. Check out Android Basics with Compose to get started on your Android development journey",
@ -59,8 +59,8 @@ val userNewsResourcesTestData: List<UserNewsResource> = UserData(
),
userData = userData,
),
UserNewsResource(
newsResource = NewsResource(
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "2",
title = "Thanks for helping us reach 1M YouTube Subscribers",
content = "Thank you everyone for following the Now in Android series and everything the " +
@ -75,8 +75,8 @@ val userNewsResourcesTestData: List<UserNewsResource> = UserData(
),
userData = userData,
),
UserNewsResource(
newsResource = NewsResource(
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "3",
title = "Transformations and customisations in the Paging Library",
content = "A demonstration of different operations that can be performed " +
@ -91,8 +91,8 @@ val userNewsResourcesTestData: List<UserNewsResource> = UserData(
),
userData = userData,
),
UserNewsResource(
newsResource = NewsResource(
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "4",
title = "New Jetpack Release",
content = "New Jetpack release includes updates to libraries such as CameraX, Benchmark, and" +

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.testing.notifications
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.notifications.Notifier
/**
@ -24,11 +24,11 @@ import com.google.samples.apps.nowinandroid.core.notifications.Notifier
*/
class TestNotifier : Notifier {
private val mutableAddedNewResources = mutableListOf<List<NewsResource>>()
private val mutableAddedNewResources = mutableListOf<List<com.google.samples.apps.nowinandroid.core.model.NewsResource>>()
val addedNewsResources: List<List<NewsResource>> = mutableAddedNewResources
val addedNewsResources: List<List<com.google.samples.apps.nowinandroid.core.model.NewsResource>> = mutableAddedNewResources
override fun postNewsNotifications(newsResources: List<NewsResource>) {
override fun postNewsNotifications(newsResources: List<com.google.samples.apps.nowinandroid.core.model.NewsResource>) {
mutableAddedNewResources.add(newsResources)
}
}

@ -16,8 +16,8 @@
package com.google.samples.apps.nowinandroid.core.testing.repository
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
@ -31,15 +31,15 @@ class TestNewsRepository : NewsRepository {
/**
* The backing hot flow for the list of topics ids for testing.
*/
private val newsResourcesFlow: MutableSharedFlow<List<NewsResource>> =
private val newsResourcesFlow: MutableSharedFlow<List<com.google.samples.apps.nowinandroid.core.model.NewsResource>> =
MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
override fun getNewsResources(query: NewsResourceQuery): Flow<List<NewsResource>> =
override fun getNewsResources(query: NewsResourceQuery): Flow<List<com.google.samples.apps.nowinandroid.core.model.NewsResource>> =
newsResourcesFlow.map { newsResources ->
var result = newsResources
query.filterTopicIds?.let { filterTopicIds ->
result = newsResources.filter {
it.topics.map(Topic::id).intersect(filterTopicIds).isNotEmpty()
it.topics.map(com.google.samples.apps.nowinandroid.core.model.Topic::id).intersect(filterTopicIds).isNotEmpty()
}
}
query.filterNewsIds?.let { filterNewsIds ->
@ -51,7 +51,7 @@ class TestNewsRepository : NewsRepository {
/**
* A test-only API to allow controlling the list of news resources from tests.
*/
fun sendNewsResources(newsResources: List<NewsResource>) {
fun sendNewsResources(newsResources: List<com.google.samples.apps.nowinandroid.core.model.NewsResource>) {
newsResourcesFlow.tryEmit(newsResources)
}

@ -16,21 +16,21 @@
package com.google.samples.apps.nowinandroid.core.testing.repository
import com.google.samples.apps.nowinandroid.core.domain.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.domain.repository.RecentSearchRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
class TestRecentSearchRepository : RecentSearchRepository {
private val cachedRecentSearches: MutableList<RecentSearchQuery> = mutableListOf()
private val cachedRecentSearches: MutableList<com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery> = mutableListOf()
override fun getRecentSearchQueries(limit: Int): Flow<List<RecentSearchQuery>> =
override fun getRecentSearchQueries(limit: Int): Flow<List<com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery>> =
flowOf(cachedRecentSearches.sortedByDescending { it.queriedDate }.take(limit))
override suspend fun insertOrReplaceRecentSearch(searchQuery: String) {
cachedRecentSearches.add(
RecentSearchQuery(
com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery(
searchQuery,
),
)

@ -16,9 +16,9 @@
package com.google.samples.apps.nowinandroid.core.testing.repository
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.SearchResult
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.SearchResult
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.repository.SearchContentsRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@ -28,14 +28,14 @@ import org.jetbrains.annotations.TestOnly
class TestSearchContentsRepository : SearchContentsRepository {
private val cachedTopics = MutableStateFlow(emptyList<Topic>())
private val cachedNewsResources = MutableStateFlow(emptyList<NewsResource>())
private val cachedTopics = MutableStateFlow(emptyList<com.google.samples.apps.nowinandroid.core.model.Topic>())
private val cachedNewsResources = MutableStateFlow(emptyList<com.google.samples.apps.nowinandroid.core.model.NewsResource>())
override suspend fun populateFtsData() = Unit
override fun searchContents(searchQuery: String): Flow<SearchResult> =
override fun searchContents(searchQuery: String): Flow<com.google.samples.apps.nowinandroid.core.model.SearchResult> =
combine(cachedTopics, cachedNewsResources) { topics, news ->
SearchResult(
com.google.samples.apps.nowinandroid.core.model.SearchResult(
topics = topics.filter {
searchQuery in it.name || searchQuery in it.shortDescription || searchQuery in it.longDescription
},
@ -48,9 +48,9 @@ class TestSearchContentsRepository : SearchContentsRepository {
override fun getSearchContentsCount(): Flow<Int> = combine(cachedTopics, cachedNewsResources) { topics, news -> topics.size + news.size }
@TestOnly
fun addTopics(topics: List<Topic>) = cachedTopics.update { it + topics }
fun addTopics(topics: List<com.google.samples.apps.nowinandroid.core.model.Topic>) = cachedTopics.update { it + topics }
@TestOnly
fun addNewsResources(newsResources: List<NewsResource>) =
fun addNewsResources(newsResources: List<com.google.samples.apps.nowinandroid.core.model.NewsResource>) =
cachedNewsResources.update { it + newsResources }
}

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.core.testing.repository
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.domain.utils.Synchronizer
import kotlinx.coroutines.channels.BufferOverflow
@ -28,18 +28,18 @@ class TestTopicsRepository : TopicsRepository {
/**
* The backing hot flow for the list of topics ids for testing.
*/
private val topicsFlow: MutableSharedFlow<List<Topic>> =
private val topicsFlow: MutableSharedFlow<List<com.google.samples.apps.nowinandroid.core.model.Topic>> =
MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
override fun getTopics(): Flow<List<Topic>> = topicsFlow
override fun getTopics(): Flow<List<com.google.samples.apps.nowinandroid.core.model.Topic>> = topicsFlow
override fun getTopic(id: String): Flow<Topic> =
override fun getTopic(id: String): Flow<com.google.samples.apps.nowinandroid.core.model.Topic> =
topicsFlow.map { topics -> topics.find { it.id == id }!! }
/**
* A test-only API to allow controlling the list of topics from tests.
*/
fun sendTopics(topics: List<Topic>) {
fun sendTopics(topics: List<com.google.samples.apps.nowinandroid.core.model.Topic>) {
topicsFlow.tryEmit(topics)
}

@ -16,18 +16,18 @@
package com.google.samples.apps.nowinandroid.core.testing.repository
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.FOLLOW_SYSTEM
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.FOLLOW_SYSTEM
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.core.model.UserData
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
import kotlinx.coroutines.channels.BufferOverflow.DROP_OLDEST
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.filterNotNull
val emptyUserData = UserData(
val emptyUserData = com.google.samples.apps.nowinandroid.core.model.UserData(
bookmarkedNewsResources = emptySet(),
viewedNewsResources = emptySet(),
followedTopics = emptySet(),
@ -41,11 +41,11 @@ class TestUserDataRepository : UserDataRepository {
/**
* The backing hot flow for the list of followed topic ids for testing.
*/
private val _userData = MutableSharedFlow<UserData>(replay = 1, onBufferOverflow = DROP_OLDEST)
private val _userData = MutableSharedFlow<com.google.samples.apps.nowinandroid.core.model.UserData>(replay = 1, onBufferOverflow = DROP_OLDEST)
private val currentUserData get() = _userData.replayCache.firstOrNull() ?: emptyUserData
override val userData: Flow<UserData> = _userData.filterNotNull()
override val userData: Flow<com.google.samples.apps.nowinandroid.core.model.UserData> = _userData.filterNotNull()
override suspend fun setFollowedTopicIds(followedTopicIds: Set<String>) {
_userData.tryEmit(currentUserData.copy(followedTopics = followedTopicIds))
@ -90,13 +90,13 @@ class TestUserDataRepository : UserDataRepository {
}
}
override suspend fun setThemeBrand(themeBrand: ThemeBrand) {
override suspend fun setThemeBrand(themeBrand: com.google.samples.apps.nowinandroid.core.model.ThemeBrand) {
currentUserData.let { current ->
_userData.tryEmit(current.copy(themeBrand = themeBrand))
}
}
override suspend fun setDarkThemeConfig(darkThemeConfig: DarkThemeConfig) {
override suspend fun setDarkThemeConfig(darkThemeConfig: com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig) {
currentUserData.let { current ->
_userData.tryEmit(current.copy(darkThemeConfig = darkThemeConfig))
}
@ -117,7 +117,7 @@ class TestUserDataRepository : UserDataRepository {
/**
* A test-only API to allow setting of user data directly.
*/
fun setUserData(userData: UserData) {
fun setUserData(userData: com.google.samples.apps.nowinandroid.core.model.UserData) {
_userData.tryEmit(userData)
}
}

@ -30,7 +30,7 @@ dependencies {
api(libs.androidx.metrics)
api(projects.core.analytics)
api(projects.core.designsystem)
api(projects.core.domain)
api(projects.core.model)
implementation(libs.androidx.browser)
implementation(libs.coil.kt)

@ -19,19 +19,19 @@
package com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.Topic
/**
* This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider)
* provides list of [FollowableTopic] for Composable previews.
*/
class FollowableTopicPreviewParameterProvider : PreviewParameterProvider<List<com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic>> {
override val values: Sequence<List<com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic>>
class FollowableTopicPreviewParameterProvider : PreviewParameterProvider<List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic>> {
override val values: Sequence<List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic>>
get() = sequenceOf(
listOf(
com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.domain.model.Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = "Headlines",
shortDescription = "News we want everyone to see",
@ -41,8 +41,8 @@ class FollowableTopicPreviewParameterProvider : PreviewParameterProvider<List<co
),
isFollowed = false,
),
com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.domain.model.Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "3",
name = "UI",
shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets",
@ -52,8 +52,8 @@ class FollowableTopicPreviewParameterProvider : PreviewParameterProvider<List<co
),
isFollowed = true,
),
com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.domain.model.Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "4",
name = "Testing",
shortDescription = "CI, Espresso, TestLab, etc",

@ -39,7 +39,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.analytics.LocalAnalyticsHelper
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
/**
* An extension on [LazyListScope] defining a feed with news resources.
@ -120,7 +120,7 @@ sealed interface NewsFeedUiState {
/**
* The list of news resources contained in this feed.
*/
val feed: List<com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource>,
val feed: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
) : NewsFeedUiState
}
@ -144,7 +144,7 @@ private fun NewsFeedLoadingPreview() {
@Composable
private fun NewsFeedContentPreview(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource>,
userNewsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
) {
NiaTheme {
LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Adaptive(300.dp)) {

@ -64,9 +64,9 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconT
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import kotlinx.datetime.Instant
import kotlinx.datetime.toJavaInstant
import kotlinx.datetime.toJavaZoneId
@ -81,7 +81,7 @@ import java.util.Locale
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NewsResourceCardExpanded(
userNewsResource: com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource,
userNewsResource: com.google.samples.apps.nowinandroid.core.model.UserNewsResource,
isBookmarked: Boolean,
hasBeenViewed: Boolean,
onToggleBookmark: () -> Unit,
@ -273,7 +273,7 @@ fun NewsResourceShortDescription(
@Composable
fun NewsResourceTopics(
topics: List<com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic>,
topics: List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic>,
onTopicClick: (String) -> Unit,
modifier: Modifier = Modifier,
) {
@ -334,7 +334,7 @@ private fun BookmarkButtonBookmarkedPreview() {
@Composable
private fun ExpandedNewsResourcePreview(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource>,
userNewsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
) {
CompositionLocalProvider(
LocalInspectionMode provides true,

@ -24,7 +24,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import com.google.samples.apps.nowinandroid.core.analytics.LocalAnalyticsHelper
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
/**
* Extension function for displaying a [List] of [NewsResourceCardExpanded] backed by a list of
@ -34,8 +34,8 @@ import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
* When a news resource card is tapped it will open the news resource URL in a Chrome Custom Tab.
*/
fun LazyListScope.userNewsResourceCardItems(
items: List<com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource>,
onToggleBookmark: (item: com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource) -> Unit,
items: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
onToggleBookmark: (item: com.google.samples.apps.nowinandroid.core.model.UserNewsResource) -> Unit,
onNewsResourceViewed: (String) -> Unit,
onTopicClick: (String) -> Unit,
itemModifier: Modifier = Modifier,

@ -19,12 +19,12 @@
package com.google.samples.apps.nowinandroid.core.ui
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.model.UserData
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.newsResources
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDateTime
@ -35,26 +35,26 @@ import kotlinx.datetime.toInstant
* This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider)
* provides list of [UserNewsResource] for Composable previews.
*/
class UserNewsResourcePreviewParameterProvider : PreviewParameterProvider<List<com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource>> {
class UserNewsResourcePreviewParameterProvider : PreviewParameterProvider<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>> {
override val values: Sequence<List<com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource>> = sequenceOf(newsResources)
override val values: Sequence<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>> = sequenceOf(newsResources)
}
object PreviewParameterData {
private val userData: com.google.samples.apps.nowinandroid.core.domain.model.UserData =
com.google.samples.apps.nowinandroid.core.domain.model.UserData(
private val userData: com.google.samples.apps.nowinandroid.core.model.UserData =
com.google.samples.apps.nowinandroid.core.model.UserData(
bookmarkedNewsResources = setOf("1", "3"),
viewedNewsResources = setOf("1", "2", "4"),
followedTopics = emptySet(),
themeBrand = com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.ANDROID,
darkThemeConfig = com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.DARK,
themeBrand = com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID,
darkThemeConfig = com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK,
shouldHideOnboarding = true,
useDynamicColor = false,
)
val topics = listOf(
com.google.samples.apps.nowinandroid.core.domain.model.Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = "Headlines",
shortDescription = "News we want everyone to see",
@ -62,7 +62,7 @@ object PreviewParameterData {
imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_Headlines.svg?alt=media&token=506faab0-617a-4668-9e63-4a2fb996603f",
url = "",
),
com.google.samples.apps.nowinandroid.core.domain.model.Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "3",
name = "UI",
shortDescription = "Material Design, Navigation, Text, Paging, Accessibility (a11y), Internationalization (i18n), Localization (l10n), Animations, Large Screens, Widgets",
@ -70,7 +70,7 @@ object PreviewParameterData {
imageUrl = "https://firebasestorage.googleapis.com/v0/b/now-in-android.appspot.com/o/img%2Fic_topic_UI.svg?alt=media&token=0ee1842b-12e8-435f-87ba-a5bb02c47594",
url = "",
),
com.google.samples.apps.nowinandroid.core.domain.model.Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "4",
name = "Testing",
shortDescription = "CI, Espresso, TestLab, etc",
@ -81,8 +81,8 @@ object PreviewParameterData {
)
val newsResources = listOf(
com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.domain.model.NewsResource(
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "1",
title = "Android Basics with Compose",
content = "We released the first two units of Android Basics with Compose, our first free course that teaches Android Development with Jetpack Compose to anyone; you do not need any prior programming experience other than basic computer literacy to get started. Youll learn the fundamentals of programming in Kotlin while building Android apps using Jetpack Compose, Androids modern toolkit that simplifies and accelerates native UI development. These two units are just the beginning; more will be coming soon. Check out Android Basics with Compose to get started on your Android development journey",
@ -102,8 +102,8 @@ object PreviewParameterData {
),
userData = userData,
),
com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.domain.model.NewsResource(
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "2",
title = "Thanks for helping us reach 1M YouTube Subscribers",
content = "Thank you everyone for following the Now in Android series and everything the " +
@ -118,8 +118,8 @@ object PreviewParameterData {
),
userData = userData,
),
com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.domain.model.NewsResource(
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "3",
title = "Transformations and customisations in the Paging Library",
content = "A demonstration of different operations that can be performed " +

@ -66,7 +66,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollba
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.scrollbarState
import com.google.samples.apps.nowinandroid.core.designsystem.theme.LocalTintTheme
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Loading
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success
@ -266,7 +266,7 @@ private fun LoadingStatePreview() {
@Composable
private fun BookmarksGridPreview(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
userNewsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
) {
NiaTheme {
BookmarksGrid(

@ -21,7 +21,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.UserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
@ -46,7 +46,7 @@ class BookmarksViewModel @Inject constructor(
val feedUiState: StateFlow<NewsFeedUiState> =
userNewsResourceRepository.observeAllBookmarked()
.map<List<UserNewsResource>, NewsFeedUiState>(NewsFeedUiState::Success)
.map<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>, NewsFeedUiState>(NewsFeedUiState::Success)
.onStart { emit(Loading) }
.stateIn(
scope = viewModelScope,

@ -96,7 +96,7 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollba
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.scrollbarState
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import com.google.samples.apps.nowinandroid.core.ui.TrackScreenViewEvent
@ -136,7 +136,7 @@ internal fun ForYouScreen(
isSyncing: Boolean,
onboardingUiState: OnboardingUiState,
feedState: NewsFeedUiState,
deepLinkedUserNewsResource: UserNewsResource?,
deepLinkedUserNewsResource: com.google.samples.apps.nowinandroid.core.model.UserNewsResource?,
onTopicCheckedChanged: (String, Boolean) -> Unit,
onTopicClick: (String) -> Unit,
onDeepLinkOpened: (String) -> Unit,
@ -464,7 +464,7 @@ private fun NotificationPermissionEffect() {
@Composable
private fun DeepLinkEffect(
userNewsResource: UserNewsResource?,
userNewsResource: com.google.samples.apps.nowinandroid.core.model.UserNewsResource?,
onDeepLinkOpened: (String) -> Unit,
) {
val context = LocalContext.current
@ -505,7 +505,7 @@ private fun feedItemsSize(
@Composable
fun ForYouScreenPopulatedFeed(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
userNewsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
) {
NiaTheme {
ForYouScreen(
@ -529,7 +529,7 @@ fun ForYouScreenPopulatedFeed(
@Composable
fun ForYouScreenOfflinePopulatedFeed(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
userNewsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
) {
NiaTheme {
ForYouScreen(
@ -553,7 +553,7 @@ fun ForYouScreenOfflinePopulatedFeed(
@Composable
fun ForYouScreenTopicSelection(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
userNewsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
) {
NiaTheme {
ForYouScreen(
@ -599,7 +599,7 @@ fun ForYouScreenLoading() {
@Composable
fun ForYouScreenPopulatedAndLoading(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
userNewsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
) {
NiaTheme {
ForYouScreen(

@ -16,7 +16,7 @@
package com.google.samples.apps.nowinandroid.feature.foryou
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
/**
* A sealed hierarchy describing the onboarding state for the for you screen.
@ -41,7 +41,7 @@ sealed interface OnboardingUiState {
* There is a onboarding state, with the given lists of topics.
*/
data class Shown(
val topics: List<FollowableTopic>,
val topics: List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic>,
) : OnboardingUiState {
/**
* True if the onboarding can be dismissed.

@ -20,11 +20,11 @@ import androidx.lifecycle.SavedStateHandle
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param
import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.mapToUserNewsResources
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.mapToUserNewsResources
import com.google.samples.apps.nowinandroid.core.domain.usecase.GetFollowableTopicsUseCase
import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository
import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository
@ -157,8 +157,8 @@ class ForYouViewModelTest {
assertEquals(
OnboardingUiState.Shown(
topics = listOf(
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = "Headlines",
shortDescription = "",
@ -168,8 +168,8 @@ class ForYouViewModelTest {
),
isFollowed = false,
),
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = "UI",
shortDescription = "",
@ -179,8 +179,8 @@ class ForYouViewModelTest {
),
isFollowed = false,
),
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = "Tools",
shortDescription = "",
@ -218,8 +218,8 @@ class ForYouViewModelTest {
assertEquals(
OnboardingUiState.Shown(
topics = listOf(
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = "Headlines",
shortDescription = "",
@ -229,8 +229,8 @@ class ForYouViewModelTest {
),
isFollowed = false,
),
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = "UI",
shortDescription = "",
@ -240,8 +240,8 @@ class ForYouViewModelTest {
),
isFollowed = false,
),
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = "Tools",
shortDescription = "",
@ -315,7 +315,7 @@ class ForYouViewModelTest {
assertEquals(
OnboardingUiState.Shown(
topics = sampleTopics.map {
FollowableTopic(it, false)
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(it, false)
},
),
viewModel.onboardingUiState.value,
@ -333,7 +333,10 @@ class ForYouViewModelTest {
assertEquals(
OnboardingUiState.Shown(
topics = sampleTopics.map {
FollowableTopic(it, it.id == followedTopicId)
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
it,
it.id == followedTopicId
)
},
),
viewModel.onboardingUiState.value,
@ -344,8 +347,14 @@ class ForYouViewModelTest {
assertEquals(
NewsFeedUiState.Success(
feed = listOf(
UserNewsResource(sampleNewsResources[1], userData),
UserNewsResource(sampleNewsResources[2], userData),
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
sampleNewsResources[1],
userData
),
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
sampleNewsResources[2],
userData
),
),
),
viewModel.feedState.value,
@ -371,8 +380,8 @@ class ForYouViewModelTest {
assertEquals(
OnboardingUiState.Shown(
topics = listOf(
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = "Headlines",
shortDescription = "",
@ -382,8 +391,8 @@ class ForYouViewModelTest {
),
isFollowed = false,
),
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = "UI",
shortDescription = "",
@ -393,8 +402,8 @@ class ForYouViewModelTest {
),
isFollowed = false,
),
FollowableTopic(
topic = Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = "Tools",
shortDescription = "",
@ -452,8 +461,14 @@ class ForYouViewModelTest {
assertEquals(
NewsFeedUiState.Success(
feed = listOf(
UserNewsResource(newsResource = sampleNewsResources[1], userDataExpected),
UserNewsResource(newsResource = sampleNewsResources[2], userDataExpected),
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = sampleNewsResources[1],
userDataExpected
),
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = sampleNewsResources[2],
userDataExpected
),
),
),
viewModel.feedState.value,
@ -473,7 +488,7 @@ class ForYouViewModelTest {
savedStateHandle[LINKED_NEWS_RESOURCE_ID] = sampleNewsResources.first().id
assertEquals(
expected = UserNewsResource(
expected = com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = sampleNewsResources.first(),
userData = emptyUserData,
),
@ -507,7 +522,7 @@ class ForYouViewModelTest {
}
private val sampleTopics = listOf(
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = "Headlines",
shortDescription = "",
@ -515,7 +530,7 @@ private val sampleTopics = listOf(
url = "URL",
imageUrl = "image URL",
),
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = "UI",
shortDescription = "",
@ -523,7 +538,7 @@ private val sampleTopics = listOf(
url = "URL",
imageUrl = "image URL",
),
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = "Tools",
shortDescription = "",
@ -534,7 +549,7 @@ private val sampleTopics = listOf(
)
private val sampleNewsResources = listOf(
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "1",
title = "Thanks for helping us reach 1M YouTube Subscribers",
content = "Thank you everyone for following the Now in Android series and everything the " +
@ -546,7 +561,7 @@ private val sampleNewsResources = listOf(
publishDate = Instant.parse("2021-11-09T00:00:00.000Z"),
type = "Video 📺",
topics = listOf(
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = "Headlines",
shortDescription = "",
@ -556,7 +571,7 @@ private val sampleNewsResources = listOf(
),
),
),
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "2",
title = "Transformations and customisations in the Paging Library",
content = "A demonstration of different operations that can be performed with Paging. " +
@ -567,7 +582,7 @@ private val sampleNewsResources = listOf(
publishDate = Instant.parse("2021-11-01T00:00:00.000Z"),
type = "Video 📺",
topics = listOf(
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = "UI",
shortDescription = "",
@ -577,7 +592,7 @@ private val sampleNewsResources = listOf(
),
),
),
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "3",
title = "Community tip on Paging",
content = "Tips for using the Paging library from the developer community",
@ -586,7 +601,7 @@ private val sampleNewsResources = listOf(
publishDate = Instant.parse("2021-11-08T00:00:00.000Z"),
type = "Video 📺",
topics = listOf(
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = "UI",
shortDescription = "",

@ -29,7 +29,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews
import com.google.samples.apps.nowinandroid.core.ui.FollowableTopicPreviewParameterProvider
import com.google.samples.apps.nowinandroid.core.ui.TrackScreenViewEvent
@ -99,7 +99,7 @@ private fun InterestsEmptyScreen() {
@Composable
fun InterestsScreenPopulated(
@PreviewParameter(FollowableTopicPreviewParameterProvider::class)
followableTopics: List<FollowableTopic>,
followableTopics: List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic>,
) {
NiaTheme {
NiaBackground {

@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.feature.interests
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.core.domain.usecase.GetFollowableTopicsUseCase
import com.google.samples.apps.nowinandroid.core.domain.usecase.TopicSortField
@ -67,7 +67,7 @@ sealed interface InterestsUiState {
data class Interests(
val selectedTopicId: String?,
val topics: List<FollowableTopic>,
val topics: List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic>,
) : InterestsUiState
data object Empty : InterestsUiState

@ -38,11 +38,11 @@ import androidx.compose.ui.unit.dp
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.DraggableScrollbar
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.rememberDraggableScroller
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.scrollbarState
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
@Composable
fun TopicsTabContent(
topics: List<FollowableTopic>,
topics: List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic>,
onTopicClick: (String) -> Unit,
onFollowButtonClick: (String, Boolean) -> Unit,
modifier: Modifier = Modifier,

@ -17,8 +17,8 @@
package com.google.samples.apps.nowinandroid.interests
import androidx.lifecycle.SavedStateHandle
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.usecase.GetFollowableTopicsUseCase
import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository
import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository
@ -149,8 +149,8 @@ private const val TOPIC_URL = "URL"
private const val TOPIC_IMAGE_URL = "Image URL"
private val testInputTopics = listOf(
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = TOPIC_1_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -160,8 +160,8 @@ private val testInputTopics = listOf(
),
isFollowed = true,
),
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = TOPIC_2_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -171,8 +171,8 @@ private val testInputTopics = listOf(
),
isFollowed = false,
),
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = TOPIC_3_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -185,8 +185,8 @@ private val testInputTopics = listOf(
)
private val testOutputTopics = listOf(
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = TOPIC_1_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -196,8 +196,8 @@ private val testOutputTopics = listOf(
),
isFollowed = true,
),
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = TOPIC_2_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -207,8 +207,8 @@ private val testOutputTopics = listOf(
),
isFollowed = true,
),
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = TOPIC_3_NAME,
shortDescription = TOPIC_SHORT_DESC,

@ -28,11 +28,11 @@ import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performScrollToIndex
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.domain.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.domain.model.UserData
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.model.UserData
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.testing.data.followableTopicTestData
import com.google.samples.apps.nowinandroid.core.testing.data.newsResourcesTestData
import org.junit.Before
@ -57,15 +57,16 @@ class SearchScreenTest {
private lateinit var tryAnotherSearchString: String
private lateinit var searchNotReadyString: String
private val userData: UserData = UserData(
bookmarkedNewsResources = setOf("1", "3"),
viewedNewsResources = setOf("1", "2", "4"),
followedTopics = emptySet(),
themeBrand = ANDROID,
darkThemeConfig = DARK,
shouldHideOnboarding = true,
useDynamicColor = false,
)
private val userData: com.google.samples.apps.nowinandroid.core.model.UserData =
com.google.samples.apps.nowinandroid.core.model.UserData(
bookmarkedNewsResources = setOf("1", "3"),
viewedNewsResources = setOf("1", "2", "4"),
followedTopics = emptySet(),
themeBrand = ANDROID,
darkThemeConfig = DARK,
shouldHideOnboarding = true,
useDynamicColor = false,
)
@Before
fun setup() {
@ -169,7 +170,7 @@ class SearchScreenTest {
SearchScreen(
searchResultUiState = SearchResultUiState.Success(
newsResources = newsResourcesTestData.map {
UserNewsResource(
com.google.samples.apps.nowinandroid.core.model.UserNewsResource(
newsResource = it,
userData = userData,
)

@ -16,12 +16,12 @@
package com.google.samples.apps.nowinandroid.feature.search
import com.google.samples.apps.nowinandroid.core.domain.model.RecentSearchQuery
import com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery
sealed interface RecentSearchQueriesUiState {
data object Loading : RecentSearchQueriesUiState
data class Success(
val recentQueries: List<RecentSearchQuery> = emptyList(),
val recentQueries: List<com.google.samples.apps.nowinandroid.core.model.RecentSearchQuery> = emptyList(),
) : RecentSearchQueriesUiState
}

@ -16,8 +16,8 @@
package com.google.samples.apps.nowinandroid.feature.search
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
sealed interface SearchResultUiState {
data object Loading : SearchResultUiState
@ -32,8 +32,8 @@ sealed interface SearchResultUiState {
data object LoadFailed : SearchResultUiState
data class Success(
val topics: List<FollowableTopic> = emptyList(),
val newsResources: List<UserNewsResource> = emptyList(),
val topics: List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic> = emptyList(),
val newsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource> = emptyList(),
) : SearchResultUiState {
fun isEmpty(): Boolean = topics.isEmpty() && newsResources.isEmpty()
}

@ -85,8 +85,8 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollba
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.scrollbarState
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success
import com.google.samples.apps.nowinandroid.core.ui.R.string
@ -287,8 +287,8 @@ private fun SearchNotReadyBody() {
@Composable
private fun SearchResultBody(
searchQuery: String,
topics: List<FollowableTopic>,
newsResources: List<UserNewsResource>,
topics: List<com.google.samples.apps.nowinandroid.core.model.FollowableTopic>,
newsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
onSearchTriggered: (String) -> Unit,
onTopicClick: (String) -> Unit,
onNewsResourcesCheckedChanged: (String, Boolean) -> Unit,

@ -19,7 +19,7 @@
package com.google.samples.apps.nowinandroid.feature.search
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.newsResources
import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.topics
@ -31,7 +31,10 @@ class SearchUiStatePreviewParameterProvider : PreviewParameterProvider<SearchRes
override val values: Sequence<SearchResultUiState> = sequenceOf(
SearchResultUiState.Success(
topics = topics.mapIndexed { i, topic ->
FollowableTopic(topic = topic, isFollowed = i % 2 == 0)
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = topic,
isFollowed = i % 2 == 0
)
},
newsResources = newsResources,
),

@ -22,7 +22,7 @@ import androidx.lifecycle.viewModelScope
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsEvent.Param
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
import com.google.samples.apps.nowinandroid.core.domain.model.UserSearchResult
import com.google.samples.apps.nowinandroid.core.model.UserSearchResult
import com.google.samples.apps.nowinandroid.core.domain.repository.RecentSearchRepository
import com.google.samples.apps.nowinandroid.core.domain.usecase.GetRecentSearchQueriesUseCase
import com.google.samples.apps.nowinandroid.core.domain.usecase.GetSearchContentsCountUseCase
@ -63,7 +63,7 @@ class SearchViewModel @Inject constructor(
getSearchContentsUseCase(query)
// Not using .asResult() here, because it emits Loading state every
// time the user types a letter in the search box, which flickers the screen.
.map<UserSearchResult, SearchResultUiState> { data ->
.map<com.google.samples.apps.nowinandroid.core.model.UserSearchResult, SearchResultUiState> { data ->
SearchResultUiState.Success(
topics = data.topics,
newsResources = data.newsResources,

@ -20,9 +20,9 @@ import androidx.activity.ComponentActivity
import androidx.compose.ui.test.assertIsSelected
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.feature.settings.SettingsUiState.Loading
import com.google.samples.apps.nowinandroid.feature.settings.SettingsUiState.Success
import org.junit.Rule

@ -59,13 +59,13 @@ import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTextButton
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.designsystem.theme.supportsDynamicTheming
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.FOLLOW_SYSTEM
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.LIGHT
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.FOLLOW_SYSTEM
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.LIGHT
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.DEFAULT
import com.google.samples.apps.nowinandroid.core.ui.TrackScreenViewEvent
import com.google.samples.apps.nowinandroid.feature.settings.R.string
import com.google.samples.apps.nowinandroid.feature.settings.SettingsUiState.Loading
@ -91,9 +91,9 @@ fun SettingsDialog(
settingsUiState: SettingsUiState,
supportDynamicColor: Boolean = supportsDynamicTheming(),
onDismiss: () -> Unit,
onChangeThemeBrand: (themeBrand: ThemeBrand) -> Unit,
onChangeThemeBrand: (themeBrand: com.google.samples.apps.nowinandroid.core.model.ThemeBrand) -> Unit,
onChangeDynamicColorPreference: (useDynamicColor: Boolean) -> Unit,
onChangeDarkThemeConfig: (darkThemeConfig: DarkThemeConfig) -> Unit,
onChangeDarkThemeConfig: (darkThemeConfig: com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig) -> Unit,
) {
val configuration = LocalConfiguration.current
@ -158,9 +158,9 @@ fun SettingsDialog(
private fun ColumnScope.SettingsPanel(
settings: UserEditableSettings,
supportDynamicColor: Boolean,
onChangeThemeBrand: (themeBrand: ThemeBrand) -> Unit,
onChangeThemeBrand: (themeBrand: com.google.samples.apps.nowinandroid.core.model.ThemeBrand) -> Unit,
onChangeDynamicColorPreference: (useDynamicColor: Boolean) -> Unit,
onChangeDarkThemeConfig: (darkThemeConfig: DarkThemeConfig) -> Unit,
onChangeDarkThemeConfig: (darkThemeConfig: com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig) -> Unit,
) {
SettingsDialogSectionTitle(text = stringResource(string.feature_settings_theme))
Column(Modifier.selectableGroup()) {

@ -18,8 +18,8 @@ package com.google.samples.apps.nowinandroid.feature.settings
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.feature.settings.SettingsUiState.Loading
import com.google.samples.apps.nowinandroid.feature.settings.SettingsUiState.Success
@ -53,13 +53,13 @@ class SettingsViewModel @Inject constructor(
initialValue = Loading,
)
fun updateThemeBrand(themeBrand: ThemeBrand) {
fun updateThemeBrand(themeBrand: com.google.samples.apps.nowinandroid.core.model.ThemeBrand) {
viewModelScope.launch {
userDataRepository.setThemeBrand(themeBrand)
}
}
fun updateDarkThemeConfig(darkThemeConfig: DarkThemeConfig) {
fun updateDarkThemeConfig(darkThemeConfig: com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig) {
viewModelScope.launch {
userDataRepository.setDarkThemeConfig(darkThemeConfig)
}
@ -76,9 +76,9 @@ class SettingsViewModel @Inject constructor(
* Represents the settings which the user can edit within the app.
*/
data class UserEditableSettings(
val brand: ThemeBrand,
val brand: com.google.samples.apps.nowinandroid.core.model.ThemeBrand,
val useDynamicColor: Boolean,
val darkThemeConfig: DarkThemeConfig,
val darkThemeConfig: com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig,
)
sealed interface SettingsUiState {

@ -16,8 +16,8 @@
package com.google.samples.apps.nowinandroid.feature.settings
import com.google.samples.apps.nowinandroid.core.domain.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.domain.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.model.DarkThemeConfig.DARK
import com.google.samples.apps.nowinandroid.core.model.ThemeBrand.ANDROID
import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository
import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule
import com.google.samples.apps.nowinandroid.feature.settings.SettingsUiState.Loading

@ -61,8 +61,8 @@ import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollba
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.scrollbarState
import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons
import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews
import com.google.samples.apps.nowinandroid.core.ui.TrackScreenViewEvent
import com.google.samples.apps.nowinandroid.core.ui.TrackScrollJank
@ -274,7 +274,7 @@ private fun TopicBodyPreview() {
@Composable
private fun TopicToolbar(
uiState: FollowableTopic,
uiState: com.google.samples.apps.nowinandroid.core.model.FollowableTopic,
modifier: Modifier = Modifier,
showBackButton: Boolean = true,
onBackClick: () -> Unit = {},
@ -319,7 +319,7 @@ private fun TopicToolbar(
@Composable
fun TopicScreenPopulated(
@PreviewParameter(UserNewsResourcePreviewParameterProvider::class)
userNewsResources: List<UserNewsResource>,
userNewsResources: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>,
) {
NiaTheme {
NiaBackground {

@ -19,9 +19,9 @@ package com.google.samples.apps.nowinandroid.feature.topic
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.domain.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.model.UserNewsResource
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsResourceQuery
import com.google.samples.apps.nowinandroid.core.domain.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.UserDataRepository
@ -103,7 +103,7 @@ private fun topicUiState(
.map { it.followedTopics }
// Observe topic information
val topicStream: Flow<Topic> = topicsRepository.getTopic(
val topicStream: Flow<com.google.samples.apps.nowinandroid.core.model.Topic> = topicsRepository.getTopic(
id = topicId,
)
@ -118,7 +118,7 @@ private fun topicUiState(
is Result.Success -> {
val (followedTopics, topic) = followedTopicToTopicResult.data
TopicUiState.Success(
followableTopic = FollowableTopic(
followableTopic = com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
topic = topic,
isFollowed = topicId in followedTopics,
),
@ -137,7 +137,7 @@ private fun newsUiState(
userDataRepository: UserDataRepository,
): Flow<NewsUiState> {
// Observe news
val newsStream: Flow<List<UserNewsResource>> = userNewsResourceRepository.observeAll(
val newsStream: Flow<List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>> = userNewsResourceRepository.observeAll(
NewsResourceQuery(filterTopicIds = setOf(element = topicId)),
)
@ -157,13 +157,13 @@ private fun newsUiState(
}
sealed interface TopicUiState {
data class Success(val followableTopic: FollowableTopic) : TopicUiState
data class Success(val followableTopic: com.google.samples.apps.nowinandroid.core.model.FollowableTopic) : TopicUiState
data object Error : TopicUiState
data object Loading : TopicUiState
}
sealed interface NewsUiState {
data class Success(val news: List<UserNewsResource>) : NewsUiState
data class Success(val news: List<com.google.samples.apps.nowinandroid.core.model.UserNewsResource>) : NewsUiState
data object Error : NewsUiState
data object Loading : NewsUiState
}

@ -18,9 +18,9 @@ package com.google.samples.apps.nowinandroid.feature.topic
import androidx.lifecycle.SavedStateHandle
import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.domain.model.NewsResource
import com.google.samples.apps.nowinandroid.core.domain.model.Topic
import com.google.samples.apps.nowinandroid.core.model.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.NewsResource
import com.google.samples.apps.nowinandroid.core.model.Topic
import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository
import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository
import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository
@ -75,7 +75,7 @@ class TopicViewModelTest {
fun uiStateTopic_whenSuccess_matchesTopicFromRepository() = runTest {
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.topicUiState.collect() }
topicsRepository.sendTopics(testInputTopics.map(FollowableTopic::topic))
topicsRepository.sendTopics(testInputTopics.map(com.google.samples.apps.nowinandroid.core.model.FollowableTopic::topic))
userDataRepository.setFollowedTopicIds(setOf(testInputTopics[1].topic.id))
val item = viewModel.topicUiState.value
assertIs<TopicUiState.Success>(item)
@ -175,8 +175,8 @@ private const val TOPIC_URL = "URL"
private const val TOPIC_IMAGE_URL = "Image URL"
private val testInputTopics = listOf(
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = TOPIC_1_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -186,8 +186,8 @@ private val testInputTopics = listOf(
),
isFollowed = true,
),
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = TOPIC_2_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -197,8 +197,8 @@ private val testInputTopics = listOf(
),
isFollowed = false,
),
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = TOPIC_3_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -211,8 +211,8 @@ private val testInputTopics = listOf(
)
private val testOutputTopics = listOf(
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = TOPIC_1_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -222,8 +222,8 @@ private val testOutputTopics = listOf(
),
isFollowed = true,
),
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "1",
name = TOPIC_2_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -233,8 +233,8 @@ private val testOutputTopics = listOf(
),
isFollowed = true,
),
FollowableTopic(
Topic(
com.google.samples.apps.nowinandroid.core.model.FollowableTopic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "2",
name = TOPIC_3_NAME,
shortDescription = TOPIC_SHORT_DESC,
@ -247,7 +247,7 @@ private val testOutputTopics = listOf(
)
private val sampleNewsResources = listOf(
NewsResource(
com.google.samples.apps.nowinandroid.core.model.NewsResource(
id = "1",
title = "Thanks for helping us reach 1M YouTube Subscribers",
content = "Thank you everyone for following the Now in Android series and everything the " +
@ -259,7 +259,7 @@ private val sampleNewsResources = listOf(
publishDate = Instant.parse("2021-11-09T00:00:00.000Z"),
type = "Video 📺",
topics = listOf(
Topic(
com.google.samples.apps.nowinandroid.core.model.Topic(
id = "0",
name = "Headlines",
shortDescription = "",

@ -26,7 +26,7 @@ import androidx.work.OutOfQuotaPolicy
import androidx.work.WorkerParameters
import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper
import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource
import com.google.samples.apps.nowinandroid.core.domain.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.model.ChangeListVersions
import com.google.samples.apps.nowinandroid.core.domain.repository.NewsRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.SearchContentsRepository
import com.google.samples.apps.nowinandroid.core.domain.repository.TopicsRepository
@ -86,11 +86,11 @@ internal class SyncWorker @AssistedInject constructor(
}
}
override suspend fun getChangeListVersions(): ChangeListVersions =
override suspend fun getChangeListVersions(): com.google.samples.apps.nowinandroid.core.model.ChangeListVersions =
niaPreferences.getChangeListVersions()
override suspend fun updateChangeListVersions(
update: ChangeListVersions.() -> ChangeListVersions,
update: com.google.samples.apps.nowinandroid.core.model.ChangeListVersions.() -> com.google.samples.apps.nowinandroid.core.model.ChangeListVersions,
) = niaPreferences.updateChangeListVersion(update)
companion object {

Loading…
Cancel
Save