Skip to content
Snippets Groups Projects
Verified Commit 86f97677 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

fix: initial sync

parent bf720298
No related branches found
No related tags found
No related merge requests found
......@@ -57,6 +57,10 @@ class SyncManager @Inject constructor(
userSyncHandler.sync(server)
drinkSyncHandler.sync(server)
if (user != null) {
Log.i(
"SyncManager",
"syncing transactions for user ${user.userId}, incremental ${incremental}"
)
if (incremental) {
transactionSyncHandler.syncIncremental(Pair(server, user.userId))
} else {
......@@ -65,7 +69,7 @@ class SyncManager @Inject constructor(
}
} catch (e: Exception) {
Log.e(
"Sync",
"SyncManager",
"Could not finish transaction for ${user?.name} (${user?.userId}) on ${server.url}",
e
)
......
......@@ -32,34 +32,44 @@ abstract class BaseIncrementalSyncHandler<Context, Entry, Key> :
abstract suspend fun loadLatestEntry(context: Context): Entry?
abstract suspend fun loadAdded(context: Context, latest: Entry): List<Entry>
override suspend fun sync(context: Context) {
super.sync(context)
}
override suspend fun syncIncremental(context: Context) {
if (syncState.compareAndSet(State.Idle, State.Loading) ||
syncState.compareAndSet(State.Error(), State.Loading)) {
syncState.compareAndSet(State.Error(), State.Loading)
) {
Log.w(this::class.simpleName, "Started incremental sync")
val success = try {
val result = withTransaction {
try {
withTransaction {
val latestEntry = loadLatestEntry(context)
if (latestEntry != null) {
val addedEntries = loadAdded(context, latestEntry)
for (loadedEntry in addedEntries) {
store(loadedEntry)
}
true
} else {
false
// If we can't do an incremental sync, do a full sync
val loadedEntries = loadCurrent(context)
val storedEntries = loadStored(context)
val storedKeys = storedEntries.map(::entryToKey).toSet()
val loadedKeys = loadedEntries.map(::entryToKey).toSet()
val removedKeys = storedKeys - loadedKeys
for (removedKey in removedKeys) {
Log.e("SyncHandler", "deleting: $removedKey")
delete(removedKey)
}
for (loadedEntry in loadedEntries) {
store(loadedEntry)
}
}
}
syncState.value = State.Idle
Log.w(this::class.simpleName, "Finished incremental sync")
result
} catch (e: Exception) {
Log.e(this::class.simpleName, "Error while syncing data", e)
syncState.value = State.Error("Error while syncing data: $e")
false
}
// If we can't do an incremental sync, do a full sync
if (!success) {
sync(context)
}
} else {
Log.w(this::class.simpleName, "Already syncing, disregarding sync request")
......
......@@ -33,11 +33,14 @@ import de.chaosdorf.meteroid.storage.AccountPreferences
import de.chaosdorf.meteroid.sync.SyncManager
import de.chaosdorf.meteroid.ui.navigation.Routes
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
......@@ -81,4 +84,14 @@ class AppViewModel @Inject constructor(
}.mapLatest { server ->
server?.let { syncManager.checkOffline(it) } ?: false
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
init {
viewModelScope.launch {
serverRepository.getAllFlow().distinctUntilChanged().collectLatest { list ->
for (server in list) {
syncManager.sync(server, null, incremental = false)
}
}
}
}
}
......@@ -33,9 +33,12 @@ import de.chaosdorf.meteroid.model.ServerId
import de.chaosdorf.meteroid.model.ServerRepository
import de.chaosdorf.meteroid.model.UserRepository
import de.chaosdorf.meteroid.sync.AccountProvider
import de.chaosdorf.meteroid.sync.SyncManager
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn
......@@ -44,6 +47,7 @@ import javax.inject.Inject
@HiltViewModel
class NavigationViewModel @Inject constructor(
syncManager: SyncManager,
serverRepository: ServerRepository,
userRepository: UserRepository,
pinnedUserRepository: PinnedUserRepository,
......@@ -73,6 +77,18 @@ class NavigationViewModel @Inject constructor(
else pinnedUserRepository.isPinnedFlow(it.first, it.second)
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
init {
viewModelScope.launch {
combine(server, user) { server, user ->
server?.let { Pair(server, user) }
}.distinctUntilChanged().collectLatest { account ->
account?.let { (server, user) ->
syncManager.sync(server, user, incremental = true)
}
}
}
}
fun togglePin(serverId: ServerId, userId: UserId) {
viewModelScope.launch {
accountProvider.togglePin(serverId, userId)
......
......@@ -83,7 +83,7 @@ fun MeteroidTopBar(
?.replace("{server}", it.arguments?.getLong("server")?.toString() ?: "{server}")
?.replace("{user}", it.arguments?.getLong("user")?.toString() ?: "{user}")
}
Log.e("Navigation", "BACKSTACK: [${backstackEntries.joinToString(" ")}]")
Log.i("Navigation", "BACKSTACK: [${backstackEntries.joinToString(" ")}]")
}
val avatarPainter = rememberAvatarPainter(
......
......@@ -109,13 +109,13 @@ sealed class WrappedSlide {
override fun create(
transactions: List<Transaction>,
drinks: Map<DrinkId, Drink>
): WrappedSlide = transactions
): WrappedSlide? = transactions
.map { it.timestamp.toLocalDateTime(TimeZone.currentSystemDefault()) }
.groupingBy { Pair(it.dayOfWeek, it.hour) }
.eachCount()
.maxBy { it.value }
.key
.let { (dayOfWeek, hour) ->
.maxByOrNull { it.value }
?.key
?.let { (dayOfWeek, hour) ->
MostActive(dayOfWeek, hour)
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment