-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* make the app work offline * remove watch * merge bookmarks on signin
- Loading branch information
1 parent
9e36600
commit 3a8bb6a
Showing
8 changed files
with
81 additions
and
134 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
shared/data/src/commonMain/kotlin/fr/androidmakers/store/graphql/ApolloExtensions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,41 @@ | ||
package fr.androidmakers.store.graphql | ||
|
||
import com.apollographql.apollo3.ApolloCall | ||
import com.apollographql.apollo3.api.ApolloResponse | ||
import com.apollographql.apollo3.api.Operation | ||
import com.apollographql.apollo3.cache.normalized.FetchPolicy | ||
import com.apollographql.apollo3.cache.normalized.fetchPolicy | ||
import com.apollographql.apollo3.exception.ApolloException | ||
import com.apollographql.apollo3.exception.CacheMissException | ||
import com.apollographql.apollo3.exception.DefaultApolloException | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.filterNot | ||
import kotlinx.coroutines.flow.flow | ||
|
||
internal fun <T : Operation.Data> Flow<ApolloResponse<T>>.ignoreCacheMisses(): Flow<ApolloResponse<T>> { | ||
return filterNot { | ||
// Ignore cache misses | ||
it.exception is CacheMissException | ||
} | ||
} | ||
|
||
|
||
internal fun <T : Operation.Data> ApolloCall<T>.cacheAndNetwork(): Flow<Result<T>> { | ||
return flow { | ||
var hasData = false | ||
var exception: ApolloException? = null | ||
fetchPolicy(FetchPolicy.CacheAndNetwork) | ||
.toFlow() | ||
.collect { | ||
if (it.data != null) { | ||
hasData = true | ||
emit(Result.success(it.data!!)) | ||
} else { | ||
exception = it.exception ?: DefaultApolloException("No data found") | ||
} | ||
} | ||
if (!hasData) { | ||
emit(Result.failure(exception!!)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 16 additions & 84 deletions
100
...ed/data/src/commonMain/kotlin/fr/androidmakers/store/graphql/SessionsGraphQLRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,113 +1,45 @@ | ||
package fr.androidmakers.store.graphql | ||
|
||
import com.apollographql.apollo3.ApolloClient | ||
import com.apollographql.apollo3.api.Mutation | ||
import com.apollographql.apollo3.cache.normalized.FetchPolicy | ||
import com.apollographql.apollo3.cache.normalized.apolloStore | ||
import com.apollographql.apollo3.cache.normalized.fetchPolicy | ||
import com.apollographql.apollo3.cache.normalized.optimisticUpdates | ||
import com.apollographql.apollo3.cache.normalized.refetchPolicy | ||
import com.apollographql.apollo3.cache.normalized.watch | ||
import fr.androidmakers.domain.model.Session | ||
import fr.androidmakers.domain.repo.SessionsRepository | ||
import fr.androidmakers.store.graphql.type.buildBookmarkConnection | ||
import fr.androidmakers.store.graphql.type.buildSession | ||
import kotlinx.coroutines.flow.Flow | ||
import kotlinx.coroutines.flow.map | ||
|
||
class SessionsGraphQLRepository(private val apolloClient: ApolloClient) : SessionsRepository { | ||
|
||
suspend fun addBookmark(uid: String?, sessionId: String): Boolean { | ||
return modifyBookmarks(uid, AddBookmarkMutation(sessionId)) { sessionIds -> | ||
AddBookmarkMutation.Data { | ||
addBookmark = buildBookmarkConnection { | ||
nodes = (sessionIds + sessionId).map { | ||
buildSession { | ||
this.id = it | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
suspend fun removeBookmark(uid: String?, sessionId: String): Boolean { | ||
return modifyBookmarks(uid, RemoveBookmarkMutation(sessionId)) { sessionIds -> | ||
RemoveBookmarkMutation.Data { | ||
removeBookmark = buildBookmarkConnection { | ||
nodes = (sessionIds - sessionId).map { | ||
buildSession { | ||
this.id = it | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
override suspend fun setBookmark(userId: String, sessionId: String, value: Boolean) { | ||
try { | ||
if (value) { | ||
addBookmark(userId, sessionId) | ||
} else { | ||
removeBookmark(userId, sessionId) | ||
} | ||
} catch (e: Exception) { | ||
e.printStackTrace() | ||
val mutation = if (value) { | ||
AddBookmarkMutation(sessionId) | ||
} else { | ||
RemoveBookmarkMutation(sessionId) | ||
} | ||
val response = apolloClient.mutation(mutation).execute() | ||
if (response.exception != null) { | ||
response.exception!!.printStackTrace() | ||
} | ||
} | ||
|
||
override fun getSession(id: String): Flow<Result<Session>> { | ||
return apolloClient.query(GetSessionQuery(id)) | ||
.fetchPolicy(FetchPolicy.CacheAndNetwork) | ||
.watch() | ||
.ignoreCacheMisses() | ||
.map { | ||
it.dataAssertNoErrors.session.sessionDetails.toSession() | ||
} | ||
.toResultFlow() | ||
.cacheAndNetwork() | ||
.map { it.map { it.session.sessionDetails.toSession() } } | ||
} | ||
|
||
override fun getBookmarks(uid: String): Flow<Result<Set<String>>> { | ||
return apolloClient.query(BookmarksQuery()) | ||
.fetchPolicy(FetchPolicy.NetworkOnly) | ||
.refetchPolicy(FetchPolicy.CacheOnly) | ||
.watch().map { | ||
it.data!!.bookmarkConnection!!.nodes.map { it.id }.toSet() | ||
}.toResultFlow() | ||
} | ||
|
||
private suspend fun <D : Mutation.Data> modifyBookmarks( | ||
uid: String?, | ||
mutation: Mutation<D>, | ||
data: (sessionIds: List<String>) -> D | ||
): Boolean { | ||
val optimisticData = try { | ||
val bookmarks = apolloClient.apolloStore.readOperation(BookmarksQuery()).bookmarkConnection | ||
data(bookmarks!!.nodes.map { it.id }) | ||
} catch (e: Exception) { | ||
null | ||
} | ||
val response = apolloClient.mutation(mutation) | ||
.apply { | ||
if (optimisticData != null) { | ||
optimisticUpdates(optimisticData) | ||
} | ||
.toFlow() | ||
.map { | ||
it.dataAssertNoErrors.bookmarkConnection.nodes.map { it.id }.toSet() | ||
} | ||
.execute() | ||
|
||
return response.data != null | ||
.toResultFlow() | ||
} | ||
|
||
override fun getSessions(): Flow<Result<List<Session>>> { | ||
return apolloClient.query(GetSessionsQuery()) | ||
.fetchPolicy(FetchPolicy.CacheAndNetwork) | ||
.watch() | ||
.ignoreCacheMisses() | ||
.map { | ||
it.dataAssertNoErrors.sessions.nodes.map { it.sessionDetails.toSession() } | ||
} | ||
.toResultFlow() | ||
.cacheAndNetwork() | ||
.map { it.map { it.sessions.nodes.map { it.sessionDetails.toSession() } } } | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
shared/ui/src/commonMain/kotlin/com/androidmakers/ui/common/navigation/UserViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,13 @@ | ||
package com.androidmakers.ui.common.navigation | ||
|
||
import fr.androidmakers.domain.interactor.SyncBookmarksUseCase | ||
import fr.androidmakers.domain.repo.UserRepository | ||
import org.koin.core.component.KoinComponent | ||
import org.koin.core.component.inject | ||
|
||
class UserData: KoinComponent { | ||
val userRepository: UserRepository by inject() | ||
val syncBookmarksUseCase: SyncBookmarksUseCase by inject() | ||
} | ||
|
||
|