From 6d1527ffb934f34efdd92173bfeef1d3b73d4dc7 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Tue, 5 Mar 2024 21:36:56 +0100 Subject: [PATCH 1/6] fix: updating client (v0.1.1) --- android/build.gradle.kts | 20 +++++++++---------- .../extopy/features/settings/AccountView.kt | 2 +- .../extopy/features/settings/SettingsView.kt | 6 +++--- ios/Extopy.xcodeproj/project.pbxproj | 8 ++++---- shared/build.gradle.kts | 4 ++-- .../usecases/posts/CreatePostUseCase.kt | 5 ++--- .../usecases/posts/FetchPostRepliesUseCase.kt | 6 +++--- .../extopy/usecases/posts/FetchPostUseCase.kt | 5 ++--- .../posts/IFetchPostRepliesUseCase.kt | 5 +++-- .../timelines/FetchTimelinePostsUseCase.kt | 6 +++--- .../timelines/FetchTimelineUseCase.kt | 4 +--- .../timelines/IFetchTimelinePostsUseCase.kt | 5 +++-- .../usecases/users/FetchUserPostsUseCase.kt | 6 +++--- .../extopy/usecases/users/FetchUserUseCase.kt | 5 ++--- .../usecases/users/IFetchUserPostsUseCase.kt | 5 +++-- .../extopy/viewmodels/posts/PostViewModel.kt | 5 +++-- .../viewmodels/timelines/TimelineViewModel.kt | 5 +++-- .../viewmodels/users/ProfileViewModel.kt | 5 +++-- 18 files changed, 54 insertions(+), 53 deletions(-) diff --git a/android/build.gradle.kts b/android/build.gradle.kts index 1a63388..53ce43f 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "me.nathanfallet.extopy" minSdk = 21 targetSdk = 34 - versionCode = 4 - versionName = "0.1.0" + versionCode = 5 + versionName = "0.1.1" } buildFeatures { buildConfig = true @@ -53,12 +53,12 @@ android { dependencies { implementation(project(":shared")) - implementation("androidx.compose.ui:ui:1.5.4") - implementation("androidx.compose.ui:ui-tooling:1.5.4") - implementation("androidx.compose.ui:ui-tooling-preview:1.5.4") - implementation("androidx.compose.foundation:foundation:1.5.4") - implementation("androidx.compose.material3:material3:1.1.2") - implementation("androidx.compose.runtime:runtime-livedata:1.5.4") + implementation("androidx.compose.ui:ui:1.6.2") + implementation("androidx.compose.ui:ui-tooling:1.6.2") + implementation("androidx.compose.ui:ui-tooling-preview:1.6.2") + implementation("androidx.compose.foundation:foundation:1.6.2") + implementation("androidx.compose.material3:material3:1.2.0") + implementation("androidx.compose.runtime:runtime-livedata:1.6.2") implementation("io.insert-koin:koin-core:3.5.3") implementation("io.insert-koin:koin-android:3.5.3") @@ -66,13 +66,13 @@ dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0") implementation("androidx.activity:activity-compose:1.8.2") - implementation("androidx.navigation:navigation-compose:2.7.6") + implementation("androidx.navigation:navigation-compose:2.7.7") implementation("androidx.datastore:datastore-preferences:1.0.0") implementation("com.google.android.material:material:1.11.0") implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0") implementation("io.coil-kt:coil-compose:2.4.0") - implementation("com.github.JamalMulla:ComposePrefs:1.0.6") + implementation("com.github.JamalMulla:ComposePrefs3:1.0.4") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") } diff --git a/android/src/main/java/me/nathanfallet/extopy/features/settings/AccountView.kt b/android/src/main/java/me/nathanfallet/extopy/features/settings/AccountView.kt index 5492a2a..21c1ab6 100644 --- a/android/src/main/java/me/nathanfallet/extopy/features/settings/AccountView.kt +++ b/android/src/main/java/me/nathanfallet/extopy/features/settings/AccountView.kt @@ -2,7 +2,7 @@ package me.nathanfallet.extopy.features.settings import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.jamal.composeprefs.ui.prefs.TextPref +import com.jamal.composeprefs3.ui.prefs.TextPref import me.nathanfallet.extopy.models.users.User @Composable diff --git a/android/src/main/java/me/nathanfallet/extopy/features/settings/SettingsView.kt b/android/src/main/java/me/nathanfallet/extopy/features/settings/SettingsView.kt index 0df3a8b..5d265c0 100644 --- a/android/src/main/java/me/nathanfallet/extopy/features/settings/SettingsView.kt +++ b/android/src/main/java/me/nathanfallet/extopy/features/settings/SettingsView.kt @@ -15,9 +15,9 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.core.content.ContextCompat.startActivity import androidx.lifecycle.viewmodel.compose.viewModel -import com.jamal.composeprefs.ui.GroupHeader -import com.jamal.composeprefs.ui.PrefsScreen -import com.jamal.composeprefs.ui.prefs.TextPref +import com.jamal.composeprefs3.ui.GroupHeader +import com.jamal.composeprefs3.ui.PrefsScreen +import com.jamal.composeprefs3.ui.prefs.TextPref import me.nathanfallet.extopy.R import me.nathanfallet.extopy.extensions.dataStore diff --git a/ios/Extopy.xcodeproj/project.pbxproj b/ios/Extopy.xcodeproj/project.pbxproj index 174995b..69cfdd3 100644 --- a/ios/Extopy.xcodeproj/project.pbxproj +++ b/ios/Extopy.xcodeproj/project.pbxproj @@ -493,7 +493,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 15.0; KOTLIN_FRAMEWORK_BUILD_TYPE = Debug; LD_RUNPATH_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 0.1.0; + MARKETING_VERSION = 0.1.1; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = me.nathanfallet.Extopy; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -528,7 +528,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 15.0; KOTLIN_FRAMEWORK_BUILD_TYPE = Release; LD_RUNPATH_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 0.1.0; + MARKETING_VERSION = 0.1.1; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = me.nathanfallet.Extopy; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -637,7 +637,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 15.0; KOTLIN_FRAMEWORK_BUILD_TYPE = Debug; LD_RUNPATH_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 0.1.0; + MARKETING_VERSION = 0.1.1; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = me.nathanfallet.Extopy.dev; PRODUCT_NAME = "$(TARGET_NAME) Dev"; @@ -739,7 +739,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 15.0; KOTLIN_FRAMEWORK_BUILD_TYPE = Release; LD_RUNPATH_SEARCH_PATHS = "$(inherited)"; - MARKETING_VERSION = 0.1.0; + MARKETING_VERSION = 0.1.1; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = me.nathanfallet.Extopy.dev; PRODUCT_NAME = "$(TARGET_NAME) Dev"; diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index c122730..03fc6f8 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -51,8 +51,8 @@ kotlin { api("com.rickclephas.kmm:kmm-viewmodel-core:1.0.0-ALPHA-16") api("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0") - api("me.nathanfallet.usecases:usecases:1.5.5") - api("me.nathanfallet.extopy:extopy-commons:0.1.0") + api("me.nathanfallet.usecases:usecases:1.6.0") + api("me.nathanfallet.extopy:extopy-commons:0.1.1") } } val commonTest by getting diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/CreatePostUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/CreatePostUseCase.kt index 1549bcd..e9b061f 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/CreatePostUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/CreatePostUseCase.kt @@ -14,13 +14,12 @@ class CreatePostUseCase( private val postsRepository: IPostsRepository, ) : ICreatePostUseCase { - override suspend fun invoke(input: PostPayload): Post? { - return client.posts.create(input)?.also { + override suspend fun invoke(input: PostPayload): Post? = + client.posts.create(input)?.also { postsRepository.save( it, Clock.System.now().plus(60, DateTimeUnit.SECOND, TimeZone.currentSystemDefault()) ) } - } } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostRepliesUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostRepliesUseCase.kt index a5d26a8..3a8baae 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostRepliesUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostRepliesUseCase.kt @@ -7,19 +7,19 @@ import kotlinx.datetime.plus import me.nathanfallet.extopy.client.IExtopyClient import me.nathanfallet.extopy.models.posts.Post import me.nathanfallet.extopy.repositories.posts.IPostsRepository +import me.nathanfallet.usecases.pagination.Pagination class FetchPostRepliesUseCase( private val client: IExtopyClient, private val postsRepository: IPostsRepository, ) : IFetchPostRepliesUseCase { - override suspend fun invoke(input1: String, input2: Long, input3: Long): List { - return client.posts.getReplies(input1, input2, input3).onEach { + override suspend fun invoke(input1: String, input2: Pagination): List = + client.posts.getReplies(input1, input2).onEach { postsRepository.save( it, Clock.System.now().plus(60, DateTimeUnit.SECOND, TimeZone.currentSystemDefault()) ) } - } } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostUseCase.kt index 1137644..c54f2a2 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostUseCase.kt @@ -13,13 +13,12 @@ class FetchPostUseCase( private val postsRepository: IPostsRepository, ) : IFetchPostUseCase { - override suspend fun invoke(input: String): Post? { - return postsRepository.get(input) ?: client.posts.get(input)?.also { + override suspend fun invoke(input: String): Post? = + postsRepository.get(input) ?: client.posts.get(input)?.also { postsRepository.save( it, Clock.System.now().plus(60, DateTimeUnit.SECOND, TimeZone.currentSystemDefault()) ) } - } } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/IFetchPostRepliesUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/IFetchPostRepliesUseCase.kt index bdb5ce4..a3dd028 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/IFetchPostRepliesUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/IFetchPostRepliesUseCase.kt @@ -1,6 +1,7 @@ package me.nathanfallet.extopy.usecases.posts import me.nathanfallet.extopy.models.posts.Post -import me.nathanfallet.usecases.base.ITripleSuspendUseCase +import me.nathanfallet.usecases.base.IPairSuspendUseCase +import me.nathanfallet.usecases.pagination.Pagination -interface IFetchPostRepliesUseCase : ITripleSuspendUseCase> +interface IFetchPostRepliesUseCase : IPairSuspendUseCase> diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/FetchTimelinePostsUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/FetchTimelinePostsUseCase.kt index 1442bc6..95d6e6e 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/FetchTimelinePostsUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/FetchTimelinePostsUseCase.kt @@ -2,13 +2,13 @@ package me.nathanfallet.extopy.usecases.timelines import me.nathanfallet.extopy.client.IExtopyClient import me.nathanfallet.extopy.models.posts.Post +import me.nathanfallet.usecases.pagination.Pagination class FetchTimelinePostsUseCase( private val client: IExtopyClient, ) : IFetchTimelinePostsUseCase { - override suspend fun invoke(input1: String, input2: Long, input3: Long): List { - return client.timelines.getPosts(input1, input2, input3) - } + override suspend fun invoke(input1: String, input2: Pagination): List = + client.timelines.getPosts(input1, input2) } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/FetchTimelineUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/FetchTimelineUseCase.kt index 6bc6e66..8887327 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/FetchTimelineUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/FetchTimelineUseCase.kt @@ -7,8 +7,6 @@ class FetchTimelineUseCase( private val client: IExtopyClient, ) : IFetchTimelineUseCase { - override suspend fun invoke(input: String): Timeline? { - return client.timelines.get(input) - } + override suspend fun invoke(input: String): Timeline? = client.timelines.get(input) } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/IFetchTimelinePostsUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/IFetchTimelinePostsUseCase.kt index 2fb6793..6a259d8 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/IFetchTimelinePostsUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/timelines/IFetchTimelinePostsUseCase.kt @@ -1,6 +1,7 @@ package me.nathanfallet.extopy.usecases.timelines import me.nathanfallet.extopy.models.posts.Post -import me.nathanfallet.usecases.base.ITripleSuspendUseCase +import me.nathanfallet.usecases.base.IPairSuspendUseCase +import me.nathanfallet.usecases.pagination.Pagination -interface IFetchTimelinePostsUseCase : ITripleSuspendUseCase> +interface IFetchTimelinePostsUseCase : IPairSuspendUseCase> diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUserPostsUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUserPostsUseCase.kt index c766a6f..fdc86e5 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUserPostsUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUserPostsUseCase.kt @@ -7,19 +7,19 @@ import kotlinx.datetime.plus import me.nathanfallet.extopy.client.IExtopyClient import me.nathanfallet.extopy.models.posts.Post import me.nathanfallet.extopy.repositories.posts.IPostsRepository +import me.nathanfallet.usecases.pagination.Pagination class FetchUserPostsUseCase( private val client: IExtopyClient, private val postsRepository: IPostsRepository, ) : IFetchUserPostsUseCase { - override suspend fun invoke(input1: String, input2: Long, input3: Long): List { - return client.users.getPosts(input1, input2, input3).onEach { + override suspend fun invoke(input1: String, input2: Pagination): List = + client.users.getPosts(input1, input2).onEach { postsRepository.save( it, Clock.System.now().plus(60, DateTimeUnit.SECOND, TimeZone.currentSystemDefault()) ) } - } } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUserUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUserUseCase.kt index a39b668..c6c91f8 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUserUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUserUseCase.kt @@ -13,13 +13,12 @@ class FetchUserUseCase( private val usersRepository: IUsersRepository, ) : IFetchUserUseCase { - override suspend fun invoke(input: String): User? { - return usersRepository.get(input) ?: client.users.get(input)?.also { + override suspend fun invoke(input: String): User? = + usersRepository.get(input) ?: client.users.get(input)?.also { usersRepository.save( it, Clock.System.now().plus(60, DateTimeUnit.SECOND, TimeZone.currentSystemDefault()) ) } - } } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/IFetchUserPostsUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/IFetchUserPostsUseCase.kt index 8ad7ee2..494e49b 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/IFetchUserPostsUseCase.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/IFetchUserPostsUseCase.kt @@ -1,6 +1,7 @@ package me.nathanfallet.extopy.usecases.users import me.nathanfallet.extopy.models.posts.Post -import me.nathanfallet.usecases.base.ITripleSuspendUseCase +import me.nathanfallet.usecases.base.IPairSuspendUseCase +import me.nathanfallet.usecases.pagination.Pagination -interface IFetchUserPostsUseCase : ITripleSuspendUseCase> +interface IFetchUserPostsUseCase : IPairSuspendUseCase> diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/posts/PostViewModel.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/posts/PostViewModel.kt index 0bd3d67..db93698 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/posts/PostViewModel.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/posts/PostViewModel.kt @@ -11,6 +11,7 @@ import me.nathanfallet.extopy.models.posts.Post import me.nathanfallet.extopy.usecases.posts.IFetchPostRepliesUseCase import me.nathanfallet.extopy.usecases.posts.IFetchPostUseCase import me.nathanfallet.extopy.usecases.posts.IUpdateLikeInPostUseCase +import me.nathanfallet.usecases.pagination.Pagination class PostViewModel( private val id: String, @@ -42,10 +43,10 @@ class PostViewModel( @NativeCoroutines suspend fun fetchReplies(reset: Boolean = false) { - _posts.value = if (reset) fetchPostRepliesUseCase(id, 25, 0).also { + _posts.value = if (reset) fetchPostRepliesUseCase(id, Pagination(25, 0)).also { hasMore = it.isNotEmpty() } else (_posts.value ?: emptyList()) + fetchPostRepliesUseCase( - id, 25, posts.value?.size?.toLong() ?: 0 + id, Pagination(25, posts.value?.size?.toLong() ?: 0) ).also { hasMore = it.isNotEmpty() } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/TimelineViewModel.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/TimelineViewModel.kt index 014c7a3..3a85333 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/TimelineViewModel.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/TimelineViewModel.kt @@ -14,6 +14,7 @@ import me.nathanfallet.extopy.usecases.posts.IUpdateLikeInPostUseCase import me.nathanfallet.extopy.usecases.timelines.IFetchTimelinePostsUseCase import me.nathanfallet.extopy.usecases.timelines.IFetchTimelineUseCase import me.nathanfallet.extopy.usecases.users.IUpdateFollowInUserUseCase +import me.nathanfallet.usecases.pagination.Pagination class TimelineViewModel( private val id: String, @@ -54,10 +55,10 @@ class TimelineViewModel( @NativeCoroutines suspend fun fetchPosts(reset: Boolean = false) { - _posts.value = if (reset) fetchTimelinePostsUseCase(id, 25, 0).also { + _posts.value = if (reset) fetchTimelinePostsUseCase(id, Pagination(25, 0)).also { hasMore = it.isNotEmpty() } else (_posts.value ?: emptyList()) + fetchTimelinePostsUseCase( - id, 25, posts.value?.size?.toLong() ?: 0 + id, Pagination(25, posts.value?.size?.toLong() ?: 0) ).also { hasMore = it.isNotEmpty() } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/users/ProfileViewModel.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/users/ProfileViewModel.kt index 85ed4f3..e90571d 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/users/ProfileViewModel.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/users/ProfileViewModel.kt @@ -13,6 +13,7 @@ import me.nathanfallet.extopy.usecases.posts.IUpdateLikeInPostUseCase import me.nathanfallet.extopy.usecases.users.IFetchUserPostsUseCase import me.nathanfallet.extopy.usecases.users.IFetchUserUseCase import me.nathanfallet.extopy.usecases.users.IUpdateFollowInUserUseCase +import me.nathanfallet.usecases.pagination.Pagination class ProfileViewModel( private val id: String, @@ -45,10 +46,10 @@ class ProfileViewModel( @NativeCoroutines suspend fun fetchPosts(reset: Boolean = false) { - _posts.value = if (reset) fetchUserPostsUseCase(id, 25, 0).also { + _posts.value = if (reset) fetchUserPostsUseCase(id, Pagination(25, 0)).also { hasMore = it.isNotEmpty() } else (_posts.value ?: emptyList()) + fetchUserPostsUseCase( - id, 25, posts.value?.size?.toLong() ?: 0 + id, Pagination(25, posts.value?.size?.toLong() ?: 0) ).also { hasMore = it.isNotEmpty() } From 0a6f8a23e2695e8f9c0bd4023d1f3d3bb0c7b65a Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Tue, 12 Mar 2024 13:29:14 +0100 Subject: [PATCH 2/6] setup search + fix auth link --- .../extopy/viewmodels/auth/AuthViewModel.kt | 2 +- .../viewmodels/timelines/SearchViewModel.kt | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/auth/AuthViewModel.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/auth/AuthViewModel.kt index f760569..fc31149 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/auth/AuthViewModel.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/auth/AuthViewModel.kt @@ -17,7 +17,7 @@ class AuthViewModel( private val fetchUserUseCase: IFetchUserUseCase, ) : KMMViewModel() { - val url = environment.baseUrl + "/auth/authorize?client_id=extopy" + val url = environment.baseUrl + "/auth/authorize?clientId=extopy" @NativeCoroutines suspend fun authenticate(code: String, onUserLogged: () -> Unit) { diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt new file mode 100644 index 0000000..20f1f91 --- /dev/null +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt @@ -0,0 +1,26 @@ +package me.nathanfallet.extopy.viewmodels.timelines + +import com.rickclephas.kmm.viewmodel.KMMViewModel +import com.rickclephas.kmm.viewmodel.MutableStateFlow +import com.rickclephas.kmp.nativecoroutines.NativeCoroutinesState +import kotlinx.coroutines.flow.asStateFlow + +class SearchViewModel( + +) : KMMViewModel() { + + // Properties + + private val _search = MutableStateFlow(viewModelScope, "") + + @NativeCoroutinesState + val search = _search.asStateFlow() + + // Methods + + fun updateSearch(value: String) { + _search.value = value + } + + +} From 185ffca34fcc3be71b59d7812b22a96b85ebc790 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Tue, 12 Mar 2024 18:58:22 +0100 Subject: [PATCH 3/6] feat: search vm + android view impl --- .../extopy/features/timelines/TimelineView.kt | 88 +++++++------------ .../me/nathanfallet/extopy/di/SharedModule.kt | 4 + .../usecases/posts/FetchPostsUseCase.kt | 13 +++ .../usecases/posts/IFetchPostsUseCase.kt | 7 ++ .../usecases/users/FetchUsersUseCase.kt | 13 +++ .../usecases/users/IFetchUsersUseCase.kt | 7 ++ .../viewmodels/timelines/SearchViewModel.kt | 84 +++++++++++++++++- .../viewmodels/timelines/TimelineViewModel.kt | 13 --- .../kotlin/me/nathanfallet/extopy/di/Koin.kt | 3 + 9 files changed, 161 insertions(+), 71 deletions(-) create mode 100644 shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostsUseCase.kt create mode 100644 shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/IFetchPostsUseCase.kt create mode 100644 shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUsersUseCase.kt create mode 100644 shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/IFetchUsersUseCase.kt diff --git a/android/src/main/java/me/nathanfallet/extopy/features/timelines/TimelineView.kt b/android/src/main/java/me/nathanfallet/extopy/features/timelines/TimelineView.kt index ee23d49..f23e46c 100644 --- a/android/src/main/java/me/nathanfallet/extopy/features/timelines/TimelineView.kt +++ b/android/src/main/java/me/nathanfallet/extopy/features/timelines/TimelineView.kt @@ -1,10 +1,11 @@ package me.nathanfallet.extopy.features.timelines import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.* import androidx.compose.runtime.Composable @@ -23,6 +24,7 @@ import me.nathanfallet.extopy.R import me.nathanfallet.extopy.models.users.User import me.nathanfallet.extopy.ui.components.posts.PostCard import me.nathanfallet.extopy.ui.components.users.UserCard +import me.nathanfallet.extopy.viewmodels.timelines.SearchViewModel import me.nathanfallet.extopy.viewmodels.timelines.TimelineViewModel import org.koin.androidx.compose.koinViewModel import org.koin.core.parameter.parametersOf @@ -39,6 +41,7 @@ fun TimelineView( val viewModel = koinViewModel( parameters = { parametersOf(id) } ) + val searchViewModel = koinViewModel() LaunchedEffect(id) { viewModel.fetchTimeline() @@ -47,69 +50,24 @@ fun TimelineView( val timeline by viewModel.timeline.collectAsState() val users by viewModel.users.collectAsState() val posts by viewModel.posts.collectAsState() - val search by viewModel.search.collectAsState() + + val search by searchViewModel.search.collectAsState() + val searchUsers by searchViewModel.users.collectAsState() + val searchPosts by searchViewModel.posts.collectAsState() LazyColumn( modifier ) { item { TopAppBar( - title = { - search?.let { search -> - TextField( - value = search, - onValueChange = viewModel::updateSearch, - placeholder = { - Text( - text = stringResource(id = R.string.timeline_search_field), - color = Color.LightGray - ) - }, - keyboardOptions = KeyboardOptions( - imeAction = ImeAction.Search - ), - keyboardActions = KeyboardActions( - onSearch = { - viewModel.viewModelScope.coroutineScope.launch { - viewModel.doSearch() - } - } - ) - ) - } ?: run { - Text(stringResource(R.string.timeline_title)) - } - }, + title = { Text(stringResource(R.string.timeline_title)) }, actions = { - if (search != null) { - IconButton( - onClick = { viewModel.updateSearch(null) } - ) { - Icon( - painter = painterResource(id = R.drawable.ic_baseline_close_24), - contentDescription = stringResource(id = R.string.timeline_search_cancel) - ) - } - } else { - IconButton( - onClick = { navigate("timelines/compose") } - ) { - Icon( - painter = painterResource(id = R.drawable.ic_baseline_create_24), - contentDescription = stringResource(id = R.string.timeline_compose_title) - ) - } - } IconButton( - onClick = { - viewModel.viewModelScope.coroutineScope.launch { - viewModel.doSearch() - } - } + onClick = { navigate("timelines/compose") } ) { Icon( - painter = painterResource(id = R.drawable.ic_baseline_search_24), - contentDescription = stringResource(id = R.string.timeline_search_title) + painter = painterResource(id = R.drawable.ic_baseline_create_24), + contentDescription = stringResource(id = R.string.timeline_compose_title) ) } } @@ -118,7 +76,25 @@ fun TimelineView( item { Spacer(modifier = Modifier.height(12.dp)) } - items(users ?: listOf()) { + item { + TextField( + value = search, + onValueChange = searchViewModel::updateSearch, + placeholder = { + Text( + text = stringResource(id = R.string.timeline_search_field), + color = Color.LightGray + ) + }, + keyboardOptions = KeyboardOptions( + imeAction = ImeAction.Search + ), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) + } + items(searchUsers?.takeIf { it.isNotEmpty() } ?: users ?: listOf()) { UserCard( user = it, viewedBy = viewedBy, @@ -148,7 +124,7 @@ fun TimelineView( } ) } - items(posts ?: listOf()) { + items(searchPosts?.takeIf { it.isNotEmpty() } ?: posts ?: listOf()) { PostCard( post = it, navigate = navigate, diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/di/SharedModule.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/di/SharedModule.kt index 5d53d8a..a6ac502 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/di/SharedModule.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/di/SharedModule.kt @@ -18,6 +18,7 @@ import me.nathanfallet.extopy.viewmodels.auth.AuthViewModel import me.nathanfallet.extopy.viewmodels.notifications.NotificationsViewModel import me.nathanfallet.extopy.viewmodels.posts.PostViewModel import me.nathanfallet.extopy.viewmodels.root.RootViewModel +import me.nathanfallet.extopy.viewmodels.timelines.SearchViewModel import me.nathanfallet.extopy.viewmodels.timelines.TimelineComposeViewModel import me.nathanfallet.extopy.viewmodels.timelines.TimelineViewModel import me.nathanfallet.extopy.viewmodels.users.ProfileViewModel @@ -50,6 +51,7 @@ val useCaseModule = module { single { FetchTimelinePostsUseCase(get()) } // Users + single { FetchUsersUseCase(get()) } single { FetchUserUseCase(get(), get()) } single { UpdateFollowInUserUseCase(get(), get()) } single { FetchUserPostsUseCase(get(), get()) } @@ -57,6 +59,7 @@ val useCaseModule = module { // Posts single { CreatePostUseCase(get(), get()) } single { UpdateLikeInPostUseCase(get(), get()) } + single { FetchPostsUseCase(get()) } single { FetchPostUseCase(get(), get()) } single { FetchPostRepliesUseCase(get(), get()) } } @@ -66,6 +69,7 @@ val viewModelModule = module { factory { AuthViewModel(get(), get(), get(), get(), get()) } factory { TimelineViewModel(it[0], get(), get(), get(), get()) } factory { TimelineComposeViewModel(it[0], it[1], it[2], get()) } + factory { SearchViewModel(get(), get()) } factory { PostViewModel(it[0], get(), get(), get()) } factory { ProfileViewModel(it[0], get(), get(), get(), get()) } factory { NotificationsViewModel() } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostsUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostsUseCase.kt new file mode 100644 index 0000000..daf8f4d --- /dev/null +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/FetchPostsUseCase.kt @@ -0,0 +1,13 @@ +package me.nathanfallet.extopy.usecases.posts + +import me.nathanfallet.extopy.client.IExtopyClient +import me.nathanfallet.extopy.models.posts.Post +import me.nathanfallet.usecases.pagination.Pagination + +class FetchPostsUseCase( + private val client: IExtopyClient, +) : IFetchPostsUseCase { + + override suspend fun invoke(input: Pagination): List = client.posts.list(input) + +} diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/IFetchPostsUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/IFetchPostsUseCase.kt new file mode 100644 index 0000000..8832da4 --- /dev/null +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/posts/IFetchPostsUseCase.kt @@ -0,0 +1,7 @@ +package me.nathanfallet.extopy.usecases.posts + +import me.nathanfallet.extopy.models.posts.Post +import me.nathanfallet.usecases.base.ISuspendUseCase +import me.nathanfallet.usecases.pagination.Pagination + +interface IFetchPostsUseCase : ISuspendUseCase> diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUsersUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUsersUseCase.kt new file mode 100644 index 0000000..51894f0 --- /dev/null +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/FetchUsersUseCase.kt @@ -0,0 +1,13 @@ +package me.nathanfallet.extopy.usecases.users + +import me.nathanfallet.extopy.client.IExtopyClient +import me.nathanfallet.extopy.models.users.User +import me.nathanfallet.usecases.pagination.Pagination + +class FetchUsersUseCase( + private val client: IExtopyClient, +) : IFetchUsersUseCase { + + override suspend fun invoke(input: Pagination): List = client.users.list(input) + +} diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/IFetchUsersUseCase.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/IFetchUsersUseCase.kt new file mode 100644 index 0000000..32817b3 --- /dev/null +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/usecases/users/IFetchUsersUseCase.kt @@ -0,0 +1,7 @@ +package me.nathanfallet.extopy.usecases.users + +import me.nathanfallet.extopy.models.users.User +import me.nathanfallet.usecases.base.ISuspendUseCase +import me.nathanfallet.usecases.pagination.Pagination + +interface IFetchUsersUseCase : ISuspendUseCase> diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt index 20f1f91..879723a 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt @@ -2,25 +2,105 @@ package me.nathanfallet.extopy.viewmodels.timelines import com.rickclephas.kmm.viewmodel.KMMViewModel import com.rickclephas.kmm.viewmodel.MutableStateFlow +import com.rickclephas.kmm.viewmodel.coroutineScope +import com.rickclephas.kmp.nativecoroutines.NativeCoroutines import com.rickclephas.kmp.nativecoroutines.NativeCoroutinesState +import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.launch +import me.nathanfallet.extopy.models.application.SearchOptions +import me.nathanfallet.extopy.models.posts.Post +import me.nathanfallet.extopy.models.users.User +import me.nathanfallet.extopy.usecases.posts.IFetchPostsUseCase +import me.nathanfallet.extopy.usecases.users.IFetchUsersUseCase +import me.nathanfallet.usecases.pagination.Pagination +@OptIn(FlowPreview::class) class SearchViewModel( - + private val fetchUsersUseCase: IFetchUsersUseCase, + private val fetchPostsUseCase: IFetchPostsUseCase, ) : KMMViewModel() { // Properties private val _search = MutableStateFlow(viewModelScope, "") + private val _users = MutableStateFlow?>(viewModelScope, null) + private val _posts = MutableStateFlow?>(viewModelScope, null) + + private val _hasMoreUsers = MutableStateFlow(viewModelScope, true) + private val _hasMorePosts = MutableStateFlow(viewModelScope, true) + @NativeCoroutinesState val search = _search.asStateFlow() - // Methods + @NativeCoroutinesState + val users = _users.asStateFlow() + + @NativeCoroutinesState + val posts = _posts.asStateFlow() + + @NativeCoroutinesState + val hasMoreUsers = _hasMoreUsers.asStateFlow() + + @NativeCoroutinesState + val hasMorePosts = _hasMorePosts.asStateFlow() + + // Setters fun updateSearch(value: String) { _search.value = value } + // Methods + + init { + viewModelScope.coroutineScope.launch { + _search.debounce(500L).collect { + fetchUsers(true) + fetchPosts(true) + } + } + } + + @NativeCoroutines + suspend fun fetchUsers(reset: Boolean = false) { + val search = search.value.trim().takeIf { it.isNotBlank() } ?: return + _users.value = if (reset) fetchUsersUseCase(Pagination(25, 0, SearchOptions(search))).also { + _hasMoreUsers.value = it.isNotEmpty() + } else (_users.value ?: emptyList()) + fetchUsersUseCase( + Pagination(25, users.value?.size?.toLong() ?: 0, SearchOptions(search)) + ).also { + _hasMoreUsers.value = it.isNotEmpty() + } + } + + fun loadMoreUsers() { + if (!hasMoreUsers.value) return + viewModelScope.coroutineScope.launch { + fetchUsers() + } + } + + @NativeCoroutines + suspend fun fetchPosts(reset: Boolean = false) { + val search = search.value.trim().takeIf { it.isNotBlank() } ?: return + _posts.value = if (reset) fetchPostsUseCase(Pagination(25, 0, SearchOptions(search))).also { + _hasMorePosts.value = it.isNotEmpty() + } else (_posts.value ?: emptyList()) + fetchPostsUseCase( + Pagination(25, _posts.value?.size?.toLong() ?: 0, SearchOptions(search)) + ).also { + _hasMorePosts.value = it.isNotEmpty() + } + } + + fun loadMorePosts() { + if (!hasMorePosts.value) return + viewModelScope.coroutineScope.launch { + fetchPosts() + } + } + } diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/TimelineViewModel.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/TimelineViewModel.kt index 3a85333..8498f74 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/TimelineViewModel.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/TimelineViewModel.kt @@ -29,7 +29,6 @@ class TimelineViewModel( private val _timeline = MutableStateFlow(viewModelScope, null) private val _users = MutableStateFlow?>(viewModelScope, null) private val _posts = MutableStateFlow?>(viewModelScope, null) - private val _search = MutableStateFlow(viewModelScope, null) @NativeCoroutinesState val timeline = _timeline.asStateFlow() @@ -40,9 +39,6 @@ class TimelineViewModel( @NativeCoroutinesState val posts = _posts.asStateFlow() - @NativeCoroutinesState - val search = _search.asStateFlow() - private var hasMore = true // Methods @@ -64,10 +60,6 @@ class TimelineViewModel( } } - fun updateSearch(search: String?) { - _search.value = search - } - @NativeCoroutines suspend fun onLikeClicked(post: Post) { updateLikeInPostUseCase(post)?.let { @@ -86,11 +78,6 @@ class TimelineViewModel( } } - @NativeCoroutines - suspend fun doSearch() { - - } - fun loadMoreIfNeeded(postId: String) { if (!hasMore || posts.value?.lastOrNull()?.id != postId) return viewModelScope.coroutineScope.launch { diff --git a/shared/src/iosMain/kotlin/me/nathanfallet/extopy/di/Koin.kt b/shared/src/iosMain/kotlin/me/nathanfallet/extopy/di/Koin.kt index 8955811..a4f888f 100644 --- a/shared/src/iosMain/kotlin/me/nathanfallet/extopy/di/Koin.kt +++ b/shared/src/iosMain/kotlin/me/nathanfallet/extopy/di/Koin.kt @@ -3,6 +3,7 @@ package me.nathanfallet.extopy.di import me.nathanfallet.extopy.viewmodels.auth.AuthViewModel import me.nathanfallet.extopy.viewmodels.posts.PostViewModel import me.nathanfallet.extopy.viewmodels.root.RootViewModel +import me.nathanfallet.extopy.viewmodels.timelines.SearchViewModel import me.nathanfallet.extopy.viewmodels.timelines.TimelineComposeViewModel import me.nathanfallet.extopy.viewmodels.timelines.TimelineViewModel import me.nathanfallet.extopy.viewmodels.users.ProfileViewModel @@ -28,6 +29,8 @@ fun Koin.timelineComposeViewModel(body: String, repliedToId: String?, repostOfId parametersOf(body, repliedToId, repostOfId) } +val Koin.searchViewModel: SearchViewModel get() = get() + fun Koin.postViewModel(id: String): PostViewModel = get { parametersOf(id) } From e9544f01cb4a4a4394a5721877beb9b7b1c2ca44 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Tue, 12 Mar 2024 19:26:03 +0100 Subject: [PATCH 4/6] feat: search ios impl --- ios/Extopy.xcodeproj/project.pbxproj | 2 +- ios/{ => Extopy/DI}/KoinExtension.swift | 1 + .../Features/Timelines/TimelineView.swift | 24 ++++--------------- ios/Extopy/en.lproj/Localizable.strings | 1 + .../viewmodels/timelines/SearchViewModel.kt | 10 ++++++-- 5 files changed, 16 insertions(+), 22 deletions(-) rename ios/{ => Extopy/DI}/KoinExtension.swift (97%) diff --git a/ios/Extopy.xcodeproj/project.pbxproj b/ios/Extopy.xcodeproj/project.pbxproj index 69cfdd3..c0b2193 100644 --- a/ios/Extopy.xcodeproj/project.pbxproj +++ b/ios/Extopy.xcodeproj/project.pbxproj @@ -80,7 +80,7 @@ 6A996E58291EB51300F36B8C /* TimelineSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineSheet.swift; sourceTree = ""; }; 6AB01ADD2B3602C5001AF7FF /* TokenRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenRepository.swift; sourceTree = ""; }; 6AB01AE32B3605A1001AF7FF /* AuthView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthView.swift; sourceTree = ""; }; - 6AC04BB02B35A804009938B9 /* KoinExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KoinExtension.swift; sourceTree = SOURCE_ROOT; }; + 6AC04BB02B35A804009938B9 /* KoinExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = KoinExtension.swift; path = Extopy/DI/KoinExtension.swift; sourceTree = SOURCE_ROOT; }; 6AC04BB22B35A897009938B9 /* InjectStateViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InjectStateViewModel.swift; sourceTree = ""; }; 6AC04BB62B35A983009938B9 /* KMMViewModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMMViewModelExtension.swift; sourceTree = ""; }; 6AC04BBF2B35F46F009938B9 /* UserHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserHeaderView.swift; sourceTree = ""; }; diff --git a/ios/KoinExtension.swift b/ios/Extopy/DI/KoinExtension.swift similarity index 97% rename from ios/KoinExtension.swift rename to ios/Extopy/DI/KoinExtension.swift index 613a759..d87c4a5 100644 --- a/ios/KoinExtension.swift +++ b/ios/Extopy/DI/KoinExtension.swift @@ -31,6 +31,7 @@ extension KoinApplication { private static let keyPaths: [PartialKeyPath] = [ \.rootViewModel, + \.searchViewModel, \.authViewModel ] diff --git a/ios/Extopy/Features/Timelines/TimelineView.swift b/ios/Extopy/Features/Timelines/TimelineView.swift index 2339a47..d60ff96 100644 --- a/ios/Extopy/Features/Timelines/TimelineView.swift +++ b/ios/Extopy/Features/Timelines/TimelineView.swift @@ -15,6 +15,7 @@ import KMPNativeCoroutinesAsync struct TimelineView: View { @StateViewModel var viewModel: TimelineViewModel + @InjectStateViewModel var searchViewModel: SearchViewModel @State var sheet: TimelineSheet? @@ -22,19 +23,9 @@ struct TimelineView: View { var body: some View { ZStack { - /* - NavigationLink( - destination: TimelineView(viewModel: TimelineViewModel( - type: .search(search: viewModel.searchText) - )), - isActive: $viewModel.searchShown - ) { - EmptyView() - } - */ ScrollView { - LazyVStack(spacing: 8) { - ForEach(viewModel.users ?? [], id: \.namespacedId) { user in + LazyVStack(spacing: 16) { + ForEach(searchViewModel.users ?? viewModel.users ?? [], id: \.namespacedId) { user in NavigationLink(destination: ProfileView( viewModel: KoinApplication.shared.koin.profileViewModel(id: user.id), viewedBy: viewedBy @@ -56,7 +47,7 @@ struct TimelineView: View { ) } } - ForEach(viewModel.posts ?? [], id: \.namespacedId) { post in + ForEach(searchViewModel.posts ?? viewModel.posts ?? [], id: \.namespacedId) { post in NavigationLink(destination: PostView( viewModel: KoinApplication.shared.koin.postViewModel(id: post.id), viewedBy: viewedBy @@ -96,12 +87,7 @@ struct TimelineView: View { } } } - /* - .searchable(text: $viewModel.searchText) { - EmptyView() - } - .onSubmit(of: .search, viewModel.submitSearch) - */ + .searchable(text: Binding(get: { searchViewModel.search }, set: searchViewModel.updateSearch)) .sheet(item: $sheet) { sheet in switch (sheet) { case .compose(let repliedToId, let repostOfId): diff --git a/ios/Extopy/en.lproj/Localizable.strings b/ios/Extopy/en.lproj/Localizable.strings index 31f49c1..b76758a 100644 --- a/ios/Extopy/en.lproj/Localizable.strings +++ b/ios/Extopy/en.lproj/Localizable.strings @@ -10,6 +10,7 @@ "timeline_user_title" = "User profile"; "timeline_post_title" = "Post details"; "timeline_search_title" = "Search results"; +"timeline_search_field" = "Search…"; "timeline_compose_title" = "Compose a post"; "timeline_compose_reply_title" = "Reply to a post"; "timeline_compose_repost_title" = "Repost a post"; diff --git a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt index 879723a..c7dd84e 100644 --- a/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt +++ b/shared/src/commonMain/kotlin/me/nathanfallet/extopy/viewmodels/timelines/SearchViewModel.kt @@ -66,7 +66,10 @@ class SearchViewModel( @NativeCoroutines suspend fun fetchUsers(reset: Boolean = false) { - val search = search.value.trim().takeIf { it.isNotBlank() } ?: return + val search = search.value.trim().takeIf { it.isNotBlank() } ?: run { + _users.value = null + return + } _users.value = if (reset) fetchUsersUseCase(Pagination(25, 0, SearchOptions(search))).also { _hasMoreUsers.value = it.isNotEmpty() } else (_users.value ?: emptyList()) + fetchUsersUseCase( @@ -85,7 +88,10 @@ class SearchViewModel( @NativeCoroutines suspend fun fetchPosts(reset: Boolean = false) { - val search = search.value.trim().takeIf { it.isNotBlank() } ?: return + val search = search.value.trim().takeIf { it.isNotBlank() } ?: run { + _posts.value = null + return + } _posts.value = if (reset) fetchPostsUseCase(Pagination(25, 0, SearchOptions(search))).also { _hasMorePosts.value = it.isNotEmpty() } else (_posts.value ?: emptyList()) + fetchPostsUseCase( From f8f443f4c9da716d351d066f86a4a2268cbdfa5f Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Tue, 12 Mar 2024 19:45:08 +0100 Subject: [PATCH 5/6] revert spacing change --- ios/Extopy/Features/Timelines/TimelineView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Extopy/Features/Timelines/TimelineView.swift b/ios/Extopy/Features/Timelines/TimelineView.swift index d60ff96..ce12808 100644 --- a/ios/Extopy/Features/Timelines/TimelineView.swift +++ b/ios/Extopy/Features/Timelines/TimelineView.swift @@ -24,7 +24,7 @@ struct TimelineView: View { var body: some View { ZStack { ScrollView { - LazyVStack(spacing: 16) { + LazyVStack(spacing: 8) { ForEach(searchViewModel.users ?? viewModel.users ?? [], id: \.namespacedId) { user in NavigationLink(destination: ProfileView( viewModel: KoinApplication.shared.koin.profileViewModel(id: user.id), From d78e2d5a6528e5c0071736150ab70023ef36d361 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Tue, 12 Mar 2024 19:46:19 +0100 Subject: [PATCH 6/6] fix: crash on nav android --- .../main/java/me/nathanfallet/extopy/features/root/RootView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/me/nathanfallet/extopy/features/root/RootView.kt b/android/src/main/java/me/nathanfallet/extopy/features/root/RootView.kt index be40b74..c437a11 100644 --- a/android/src/main/java/me/nathanfallet/extopy/features/root/RootView.kt +++ b/android/src/main/java/me/nathanfallet/extopy/features/root/RootView.kt @@ -209,7 +209,7 @@ enum class NavigationItem( val title: Int, ) { - TIMELINE("timeline", R.drawable.ic_baseline_menu_24, R.string.timeline_title), + TIMELINE("timelines", R.drawable.ic_baseline_menu_24, R.string.timeline_title), DIRECT_MESSAGE( "direct_message", R.drawable.ic_baseline_message_24,