From eae6217c5394d29fc6e3ed3eb085e8ca7e05a362 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Fri, 10 Jan 2025 15:34:27 -0300 Subject: [PATCH] Show progress when deleting old logs --- .../greenart7c3/nostrsigner/NostrSigner.kt | 55 +++++++++++++++++-- .../nostrsigner/database/ApplicationDao.kt | 36 ++++++++++-- .../nostrsigner/ui/PermissionsScreen.kt | 3 +- .../nostrsigner/ui/SettingsScreen.kt | 4 +- 4 files changed, 86 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/NostrSigner.kt b/app/src/main/java/com/greenart7c3/nostrsigner/NostrSigner.kt index 673bd19..7aa909f 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/NostrSigner.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/NostrSigner.kt @@ -39,6 +39,7 @@ import java.util.Timer import java.util.TimerTask import java.util.UUID import java.util.concurrent.ConcurrentHashMap +import kotlin.coroutines.cancellation.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -46,6 +47,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking @@ -56,6 +58,7 @@ class NostrSigner : Application() { private var databases = ConcurrentHashMap() lateinit var settings: AmberSettings var job: Job? = null + val status = MutableStateFlow("") val isOnMobileDataState = mutableStateOf(false) val isOnWifiDataState = mutableStateOf(false) @@ -117,10 +120,54 @@ class NostrSigner : Application() { job = applicationIOScope.launch { LocalPreferences.allSavedAccounts(this@NostrSigner).forEach { databases[it.npub]?.let { database -> - val oneWeek = System.currentTimeMillis() - ONE_WEEK - database.applicationDao().deleteHistoryBefore(TimeUtils.oneWeekAgo()) - database.applicationDao().deleteNotificationBefore(TimeUtils.oneWeekAgo()) - database.applicationDao().deleteLogsBefore(oneWeek) + try { + status.value = "Deleting old log entries from ${it.npub}" + val oneWeek = System.currentTimeMillis() - ONE_WEEK + val oneWeekAgo = TimeUtils.oneWeekAgo() + val countHistory = database.applicationDao().countOldHistory(oneWeekAgo) + if (countHistory > 0) { + status.value = "Deleting $countHistory old history entries" + var logs = database.applicationDao().getOldHistory(oneWeekAgo) + while (logs.isNotEmpty()) { + status.value = "Deleting 100/$countHistory old history entries" + logs.forEach { history -> + database.applicationDao().deleteHistory(history) + } + logs = database.applicationDao().getOldHistory(oneWeekAgo) + } + } + + val countNotification = database.applicationDao().countOldNotification(oneWeekAgo) + if (countNotification > 0) { + status.value = "Deleting $countNotification old notification entries" + var logs = database.applicationDao().getOldNotification(oneWeekAgo) + while (logs.isNotEmpty()) { + status.value = "Deleting 100/$countNotification old notification entries" + logs.forEach { history -> + database.applicationDao().deleteNotification(history) + } + logs = database.applicationDao().getOldNotification(oneWeekAgo) + } + } + + val countLog = database.applicationDao().countOldLog(oneWeek) + if (countLog > 0) { + status.value = "Deleting $countLog old notification entries" + var logs = database.applicationDao().getOldLog(oneWeek) + while (logs.isNotEmpty()) { + status.value = "Deleting 100/$countLog old log entries" + logs.forEach { history -> + database.applicationDao().deleteLog(history) + } + logs = database.applicationDao().getOldLog(oneWeek) + } + } + status.value = "" + } catch (e: Exception) { + if (e is CancellationException) throw e + Log.e("NostrSigner", "Error deleting old log entries", e) + status.value = "" + } } } } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/database/ApplicationDao.kt b/app/src/main/java/com/greenart7c3/nostrsigner/database/ApplicationDao.kt index bd9df5b..cccd4df 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/database/ApplicationDao.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/database/ApplicationDao.kt @@ -166,15 +166,39 @@ interface ApplicationDao { @Transaction suspend fun deletePermission(permission: ApplicationPermissionsEntity) - @Query("DELETE FROM history WHERE time < :time") + @Query("SELECT COUNT(*) FROM history WHERE time < :time") @Transaction - suspend fun deleteHistoryBefore(time: Long) + suspend fun countOldHistory(time: Long): Long - @Query("DELETE FROM notification WHERE time < :time") + @Query("SELECT * FROM history WHERE time < :time LIMIT 100") @Transaction - suspend fun deleteNotificationBefore(time: Long) + suspend fun getOldHistory(time: Long): List - @Query("DELETE FROM amber_log WHERE time < :time") + @Delete + @Transaction + suspend fun deleteHistory(historyEntity: HistoryEntity) + + @Query("SELECT COUNT(*) FROM notification WHERE time < :time") + @Transaction + suspend fun countOldNotification(time: Long): Long + + @Query("SELECT * FROM notification WHERE time < :time LIMIT 100") + @Transaction + suspend fun getOldNotification(time: Long): List + + @Delete + @Transaction + suspend fun deleteNotification(notificationEntity: NotificationEntity) + + @Query("SELECT COUNT(*) FROM amber_log WHERE time < :time") + @Transaction + suspend fun countOldLog(time: Long): Long + + @Query("SELECT * FROM amber_log WHERE time < :time LIMIT 100") + @Transaction + suspend fun getOldLog(time: Long): List + + @Delete @Transaction - suspend fun deleteLogsBefore(time: Long) + suspend fun deleteLog(logEntity: LogEntity) } diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/PermissionsScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/PermissionsScreen.kt index 116e7a6..7f99334 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/PermissionsScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/PermissionsScreen.kt @@ -60,7 +60,8 @@ fun PermissionsScreen( } if (isLoading) { - CenterCircularProgressIndicator(modifier) + val status = NostrSigner.getInstance().status.collectAsStateWithLifecycle() + CenterCircularProgressIndicator(modifier, status.value) } else { val applications = database.applicationDao().getAllFlow(account.signer.keyPair.pubKey.toHexKey()).collectAsStateWithLifecycle(emptyList()) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt index d700b98..85df9c1 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/SettingsScreen.kt @@ -47,6 +47,7 @@ import androidx.compose.ui.text.withLink import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavController import com.greenart7c3.nostrsigner.BuildConfig import com.greenart7c3.nostrsigner.LocalPreferences @@ -103,7 +104,8 @@ fun SettingsScreen( } if (isLoading) { - CenterCircularProgressIndicator(modifier) + val status = NostrSigner.getInstance().status.collectAsStateWithLifecycle() + CenterCircularProgressIndicator(modifier, status.value) } else { Column( modifier,