diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8784f83aa..d8d792439 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -136,6 +136,10 @@
android:label="@string/notification_checking_finished_title"
android:launchMode="singleTask"/>
+
+
diff --git a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt
index 97362a902..eac8aee2c 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/settings/SettingsViewModel.kt
@@ -47,6 +47,7 @@ import com.stevesoltys.seedvault.worker.AppBackupWorker
import com.stevesoltys.seedvault.worker.AppBackupWorker.Companion.UNIQUE_WORK_NAME
import com.stevesoltys.seedvault.worker.AppCheckerWorker
import com.stevesoltys.seedvault.worker.BackupRequester.Companion.requestFilesAndAppBackup
+import com.stevesoltys.seedvault.worker.FileCheckerWorker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -90,6 +91,8 @@ internal class SettingsViewModel(
private val mBackupSize = MutableLiveData()
val backupSize: LiveData = mBackupSize
+ private val mFilesBackupSize = MutableLiveData()
+ val filesBackupSize: LiveData = mFilesBackupSize
internal val lastBackupTime = settingsManager.lastBackupTime
internal val appBackupWorkInfo =
@@ -329,10 +332,20 @@ internal class SettingsViewModel(
}
}
+ fun loadFileBackupSize() {
+ viewModelScope.launch(Dispatchers.IO) {
+ mFilesBackupSize.postValue(storageBackup.getBackupSize())
+ }
+ }
+
fun checkAppBackups(percent: Int) {
AppCheckerWorker.scheduleNow(app, percent)
}
+ fun checkFileBackups(percent: Int) {
+ FileCheckerWorker.scheduleNow(app, percent)
+ }
+
fun onLogcatUriReceived(uri: Uri?) = viewModelScope.launch(Dispatchers.IO) {
if (uri == null) {
onLogcatError()
diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/check/AppCheckFragment.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/check/AppCheckFragment.kt
index f6988b803..280a655f3 100644
--- a/app/src/main/java/com/stevesoltys/seedvault/ui/check/AppCheckFragment.kt
+++ b/app/src/main/java/com/stevesoltys/seedvault/ui/check/AppCheckFragment.kt
@@ -20,8 +20,8 @@ import com.stevesoltys.seedvault.R
import com.stevesoltys.seedvault.settings.SettingsViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
-private const val WARN_PERCENT = 25
-private const val WARN_BYTES = 1024 * 1024 * 1024 // 1 GB
+internal const val WARN_PERCENT = 25
+internal const val WARN_BYTES = 1024 * 1024 * 1024 // 1 GB
class AppCheckFragment : Fragment() {
diff --git a/app/src/main/java/com/stevesoltys/seedvault/ui/check/FileCheckFragment.kt b/app/src/main/java/com/stevesoltys/seedvault/ui/check/FileCheckFragment.kt
new file mode 100644
index 000000000..0882c082d
--- /dev/null
+++ b/app/src/main/java/com/stevesoltys/seedvault/ui/check/FileCheckFragment.kt
@@ -0,0 +1,89 @@
+/*
+ * SPDX-FileCopyrightText: 2024 The Calyx Institute
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package com.stevesoltys.seedvault.ui.check
+
+import android.os.Bundle
+import android.text.format.Formatter
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.ScrollView
+import android.widget.TextView
+import androidx.fragment.app.Fragment
+import com.google.android.material.slider.LabelFormatter
+import com.google.android.material.slider.Slider
+import com.stevesoltys.seedvault.R
+import com.stevesoltys.seedvault.settings.SettingsViewModel
+import org.koin.androidx.viewmodel.ext.android.activityViewModel
+
+class FileCheckFragment : Fragment() {
+
+ private val viewModel: SettingsViewModel by activityViewModel()
+ private lateinit var sliderLabel: TextView
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View {
+ val v = inflater.inflate(R.layout.fragment_app_check, container, false) as ScrollView
+
+ v.requireViewById(R.id.titleView).setText(R.string.settings_file_check_title)
+ v.requireViewById(R.id.descriptionView).setText(R.string.settings_file_check_text)
+ v.requireViewById(R.id.introView).setText(R.string.settings_file_check_text2)
+
+ val slider = v.requireViewById(R.id.slider)
+ sliderLabel = v.requireViewById(R.id.sliderLabel)
+
+ // label not scrolling will be fixed in material-components 1.12.0 (next update)
+ slider.setLabelFormatter { value ->
+ viewModel.filesBackupSize.value?.let {
+ Formatter.formatShortFileSize(context, (it * value / 100).toLong())
+ } ?: "${value.toInt()}%"
+ }
+ slider.addOnChangeListener { _, value, _ ->
+ onSliderChanged(value)
+ }
+
+ viewModel.filesBackupSize.observe(viewLifecycleOwner) {
+ if (it != null) {
+ slider.labelBehavior = LabelFormatter.LABEL_VISIBLE
+ slider.invalidate()
+ onSliderChanged(slider.value)
+ }
+ // we can stop observing as the loaded size won't change again
+ viewModel.filesBackupSize.removeObservers(viewLifecycleOwner)
+ }
+
+ v.requireViewById