Skip to content

Commit b6cd7a1

Browse files
authored
Merge pull request #342 from android/oct18-merge
Oct18 merge
2 parents 7e6cb46 + 9435c1c commit b6cd7a1

File tree

42 files changed

+1050
-301
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1050
-301
lines changed

build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class AndroidFeatureConventionPlugin : Plugin<Project> {
4545
add("implementation", project(":core:data"))
4646
add("implementation", project(":core:common"))
4747
add("implementation", project(":core:navigation"))
48+
add("implementation", project(":core:domain"))
4849

4950
add("testImplementation", project(":core:testing"))
5051
add("androidTestImplementation", project(":core:testing"))

core/domain/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

core/domain/build.gradle.kts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2022 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
plugins {
17+
id("nowinandroid.android.library")
18+
id("nowinandroid.android.library.jacoco")
19+
kotlin("kapt")
20+
}
21+
22+
dependencies {
23+
24+
implementation(project(":core:data"))
25+
implementation(project(":core:model"))
26+
27+
testImplementation(project(":core:testing"))
28+
29+
implementation(libs.kotlinx.coroutines.android)
30+
implementation(libs.kotlinx.datetime)
31+
32+
implementation(libs.hilt.android)
33+
kapt(libs.hilt.compiler)
34+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright 2022 The Android Open Source Project
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
<manifest package="com.google.samples.apps.nowinandroid.core.domain" />
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright 2022 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.samples.apps.nowinandroid.core.domain
18+
19+
import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository
20+
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
21+
import com.google.samples.apps.nowinandroid.core.domain.TopicSortField.NAME
22+
import com.google.samples.apps.nowinandroid.core.domain.TopicSortField.NONE
23+
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableTopic
24+
import javax.inject.Inject
25+
import kotlinx.coroutines.flow.Flow
26+
import kotlinx.coroutines.flow.combine
27+
import kotlinx.coroutines.flow.map
28+
29+
/**
30+
* A use case which obtains a list of topics with their followed state.
31+
*/
32+
class GetFollowableTopicsStreamUseCase @Inject constructor(
33+
private val topicsRepository: TopicsRepository,
34+
private val userDataRepository: UserDataRepository
35+
) {
36+
/**
37+
* Returns a list of topics with their associated followed state.
38+
*
39+
* @param followedTopicIdsStream - the set of topic ids which are currently being followed. By
40+
* default the followed topic ids are supplied from the user data repository, but in certain
41+
* scenarios, such as when creating a temporary set of followed topics, you may wish to override
42+
* this parameter to supply your own list of topic ids. @see ForYouViewModel for an example of
43+
* this.
44+
* @param sortBy - the field used to sort the topics. Default NONE = no sorting.
45+
*/
46+
operator fun invoke(
47+
followedTopicIdsStream: Flow<Set<String>> =
48+
userDataRepository.userDataStream.map { userdata ->
49+
userdata.followedTopics
50+
},
51+
sortBy: TopicSortField = NONE
52+
): Flow<List<FollowableTopic>> {
53+
return combine(
54+
followedTopicIdsStream,
55+
topicsRepository.getTopicsStream()
56+
) { followedIds, topics ->
57+
val followedTopics = topics
58+
.map { topic ->
59+
FollowableTopic(
60+
topic = topic,
61+
isFollowed = topic.id in followedIds
62+
)
63+
}
64+
if (sortBy == NAME) {
65+
followedTopics.sortedBy { it.topic.name }
66+
} else {
67+
followedTopics
68+
}
69+
}
70+
}
71+
}
72+
73+
enum class TopicSortField {
74+
NONE,
75+
NAME,
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2022 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.samples.apps.nowinandroid.core.domain
18+
19+
import com.google.samples.apps.nowinandroid.core.data.repository.AuthorsRepository
20+
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
21+
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableAuthor
22+
import javax.inject.Inject
23+
import kotlinx.coroutines.flow.Flow
24+
import kotlinx.coroutines.flow.flatMapLatest
25+
import kotlinx.coroutines.flow.map
26+
27+
/**
28+
* A use case which obtains a sorted list of authors with their followed state obtained from user
29+
* data.
30+
*/
31+
class GetPersistentSortedFollowableAuthorsStreamUseCase @Inject constructor(
32+
authorsRepository: AuthorsRepository,
33+
private val userDataRepository: UserDataRepository
34+
) {
35+
private val getSortedFollowableAuthorsStream =
36+
GetSortedFollowableAuthorsStreamUseCase(authorsRepository)
37+
38+
/**
39+
* Returns a list of authors with their associated followed state sorted alphabetically by name.
40+
*/
41+
operator fun invoke(): Flow<List<FollowableAuthor>> {
42+
return userDataRepository.userDataStream.map { userdata ->
43+
userdata.followedAuthors
44+
}.flatMapLatest {
45+
getSortedFollowableAuthorsStream(it)
46+
}
47+
}
48+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2022 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.samples.apps.nowinandroid.core.domain
18+
19+
import com.google.samples.apps.nowinandroid.core.data.repository.NewsRepository
20+
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
21+
import com.google.samples.apps.nowinandroid.core.domain.model.SaveableNewsResource
22+
import com.google.samples.apps.nowinandroid.core.model.data.NewsResource
23+
import javax.inject.Inject
24+
import kotlinx.coroutines.flow.Flow
25+
import kotlinx.coroutines.flow.combine
26+
import kotlinx.coroutines.flow.filterNot
27+
import kotlinx.coroutines.flow.map
28+
29+
/**
30+
* A use case responsible for obtaining news resources with their associated bookmarked (also known
31+
* as "saved") state.
32+
*/
33+
class GetSaveableNewsResourcesStreamUseCase @Inject constructor(
34+
private val newsRepository: NewsRepository,
35+
userDataRepository: UserDataRepository
36+
) {
37+
38+
private val bookmarkedNewsResourcesStream = userDataRepository.userDataStream.map {
39+
it.bookmarkedNewsResources
40+
}
41+
42+
/**
43+
* Returns a list of SaveableNewsResources which match the supplied set of topic ids or author
44+
* ids.
45+
*
46+
* @param filterTopicIds - A set of topic ids used to filter the list of news resources. If
47+
* this is empty AND filterAuthorIds is empty the list of news resources will not be filtered.
48+
* @param filterAuthorIds - A set of author ids used to filter the list of news resources. If
49+
* this is empty AND filterTopicIds is empty the list of news resources will not be filtered.
50+
*
51+
*/
52+
operator fun invoke(
53+
filterTopicIds: Set<String> = emptySet(),
54+
filterAuthorIds: Set<String> = emptySet()
55+
): Flow<List<SaveableNewsResource>> =
56+
if (filterTopicIds.isEmpty() && filterAuthorIds.isEmpty()) {
57+
newsRepository.getNewsResourcesStream()
58+
} else {
59+
newsRepository.getNewsResourcesStream(
60+
filterTopicIds = filterTopicIds,
61+
filterAuthorIds = filterAuthorIds
62+
)
63+
}.mapToSaveableNewsResources(bookmarkedNewsResourcesStream)
64+
}
65+
66+
private fun Flow<List<NewsResource>>.mapToSaveableNewsResources(
67+
savedNewsResourceIdsStream: Flow<Set<String>>
68+
): Flow<List<SaveableNewsResource>> =
69+
filterNot { it.isEmpty() }
70+
.combine(savedNewsResourceIdsStream) { newsResources, savedNewsResourceIds ->
71+
newsResources.map { newsResource ->
72+
SaveableNewsResource(
73+
newsResource = newsResource,
74+
isSaved = savedNewsResourceIds.contains(newsResource.id)
75+
)
76+
}
77+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2022 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.samples.apps.nowinandroid.core.domain
18+
19+
import com.google.samples.apps.nowinandroid.core.data.repository.AuthorsRepository
20+
import com.google.samples.apps.nowinandroid.core.domain.model.FollowableAuthor
21+
import javax.inject.Inject
22+
import kotlinx.coroutines.flow.Flow
23+
import kotlinx.coroutines.flow.map
24+
25+
/**
26+
* A use case which obtains a list of authors sorted alphabetically by name with their followed
27+
* state.
28+
*/
29+
class GetSortedFollowableAuthorsStreamUseCase @Inject constructor(
30+
private val authorsRepository: AuthorsRepository
31+
) {
32+
/**
33+
* Returns a list of authors with their associated followed state sorted alphabetically by name.
34+
*
35+
* @param followedTopicIds - the set of topic ids which are currently being followed.
36+
*/
37+
operator fun invoke(followedAuthorIds: Set<String>): Flow<List<FollowableAuthor>> {
38+
return authorsRepository.getAuthorsStream().map { authors ->
39+
authors
40+
.map { author ->
41+
FollowableAuthor(
42+
author = author,
43+
isFollowed = author.id in followedAuthorIds
44+
)
45+
}
46+
.sortedBy { it.author.name }
47+
}
48+
}
49+
}

core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/FollowableAuthor.kt renamed to core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableAuthor.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.google.samples.apps.nowinandroid.core.model.data
17+
package com.google.samples.apps.nowinandroid.core.domain.model
18+
19+
import com.google.samples.apps.nowinandroid.core.model.data.Author
1820

1921
/**
2022
* An [author] with the additional information for whether or not it is followed.

core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/FollowableTopic.kt renamed to core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/model/FollowableTopic.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.google.samples.apps.nowinandroid.core.model.data
17+
package com.google.samples.apps.nowinandroid.core.domain.model
18+
19+
import com.google.samples.apps.nowinandroid.core.model.data.Topic
1820

1921
/**
2022
* A [topic] with the additional information for whether or not it is followed.

0 commit comments

Comments
 (0)