From 0d33cfd6e4fd1da5b1bff5734a06dc8c4d238771 Mon Sep 17 00:00:00 2001 From: Tom Vincent Date: Tue, 30 Jun 2026 16:13:09 +0100 Subject: [PATCH] Add network connectivity check --- app/src/main/AndroidManifest.xml | 2 + .../gitnote/manager/StorageManager.kt | 76 +++++++++++++++---- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3e997ac..a444e9a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,8 @@ + + = MutableStateFlow(SyncState.Ok(true)) val syncState: StateFlow = _syncState + private fun isNetworkAvailable(): Boolean { + val connectivityManager = MyApp.appModule.context + .getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager ?: return true + return try { + val network = connectivityManager.activeNetwork ?: return false + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + } catch (_: SecurityException) { + true + } + } + + private suspend fun ensureRepoOpen(): Result { + if (gitManager.isRepoInitialized) return success(Unit) + return gitManager.openRepo(prefs.repoPath()) + } + + private suspend fun commitAllWithRetry(author: GitAuthor, message: String): Result { + val firstAttempt = gitManager.commitAll(author, message) + val err = firstAttempt.exceptionOrNull() + + if (err is GitException && err.type == GitExceptionType.RepoNotInit) { + err.message?.let { Log.e(TAG, it) } + _syncState.emit(SyncState.Error(err.message)) + ensureRepoOpen().onFailure { openErr -> + openErr.message?.let { Log.e(TAG, it) } + _syncState.emit(SyncState.Error(openErr.message)) + return failure(openErr) + } + return gitManager.commitAll(author, message).onFailure { retryErr -> + retryErr.message?.let { Log.e(TAG, it) } + _syncState.emit(SyncState.Error(retryErr.message)) + } + } + + firstAttempt.onFailure { err -> + err.message?.let { Log.e(TAG, it) } + _syncState.emit(SyncState.Error(err.message)) + } + return firstAttempt + } + suspend fun updateDatabaseAndRepo(): Result = locker.withLock { Log.d(TAG, "updateDatabaseAndRepo") @@ -72,16 +118,15 @@ class StorageManager { val author = prefs.gitAuthor() var isError = false - gitManager.commitAll( + commitAllWithRetry( author, "commit from gitnote to update the repo of the app" ).onFailure { err -> - err.message?.let { Log.e(TAG, it) } - _syncState.emit(SyncState.Error(err.message)) return@withLock failure(err) } - if (remoteUrl.isNotEmpty()) { + val online = isNetworkAvailable() + if (remoteUrl.isNotEmpty() && online) { _syncState.emit(SyncState.Pull) gitManager.pull(cred, author).onFailure { err -> isError = true @@ -90,7 +135,7 @@ class StorageManager { } } - if (remoteUrl.isNotEmpty()) { + if (remoteUrl.isNotEmpty() && online) { _syncState.emit(SyncState.Push) // todo: maybe async this call gitManager.push(cred).onFailure { err -> @@ -136,7 +181,13 @@ class StorageManager { Log.d(TAG, "repoPath = $repoPath") progressCb?.invoke(Progress.Timestamps) - val timestamps = gitManager.getTimestamps().getOrThrow() + val timestamps = gitManager.getTimestamps().fold( + onSuccess = { it }, + onFailure = { err -> + err.message?.let { Log.e(TAG, it) } + return failure(err) + } + ) dao.clearAndInit(repoPath, timestamps, progressCb) prefs.databaseCommit.update(fsCommit) @@ -326,16 +377,15 @@ class StorageManager { var isError = false - gitManager.commitAll( + commitAllWithRetry( author, "commit from gitnote, before doing a change" ).onFailure { err -> - err.message?.let { Log.e(TAG, it) } - _syncState.emit(SyncState.Error(err.message)) return failure(err) } - if (remoteUrl.isNotEmpty()) { + val online = isNetworkAvailable() + if (remoteUrl.isNotEmpty() && online) { _syncState.emit(SyncState.Pull) gitManager.pull(cred, author).onFailure { err -> isError = true @@ -360,15 +410,13 @@ class StorageManager { } ) - gitManager.commitAll(author, commitMessage).onFailure { err -> - err.message?.let { Log.e(TAG, it) } - _syncState.emit(SyncState.Error(err.message)) + commitAllWithRetry(author, commitMessage).onFailure { err -> return failure(err) } prefs.databaseCommit.update(gitManager.lastCommit()) - if (remoteUrl.isNotEmpty()) { + if (remoteUrl.isNotEmpty() && online) { _syncState.emit(SyncState.Push) gitManager.push(cred).onFailure { err -> isError = true