Remember what is in the trash, and add a screen to restore from it
The staged-delete work left a hole. The undo handle lived in BrowserUiState, so a delete from an earlier session was unreachable even though the files were sitting on the volume; and because nothing on disk recorded which folder an item came from, not even the user could put one back by hand with confidence. Adding a Trash screen alone would not have fixed it: the recovery data did not survive the process. So the origin is now written at delete time. data/ gains its first persistence: a SQLite index (staged path, original path, name, type, size, timestamp). SQLite rather than Room because an annotation processor is a large addition to this build for one table and three queries, and behind a TrashIndex port so domain/Trash keeps no Context while the tests drive it with a map and the real one is still tested against real SQLite. New Trash entry in the overflow menu lists batches and restores a whole one. The index is an index, not the truth: the staged files are the truth, and the two can disagree if a user empties the folder by hand or pulls a card. Reconciled both ways - restorableFrom drops entries whose file has gone, purgeExpired forgets entries whose folder has gone and sweeps folders no entry mentions - and rows are written after the move, so a crash leaves an unindexed folder (harmless, swept) rather than an entry that could never restore. Verified on hardware: delete, force-stop, relaunch, restore. Also corrects the docs where they claimed input swipe x y x y 900 is delivered as a plain tap on MIUI. It does open the selection bar - it was driven that way - but it has also landed as a tap, so it is flaky rather than impossible.
This commit is contained in:
@@ -5,7 +5,9 @@ import de.softwareapp_hb.filemanager.data.ContentResolverIncomingSource
|
||||
import de.softwareapp_hb.filemanager.data.DeleteRequestFactory
|
||||
import de.softwareapp_hb.filemanager.data.IncomingSource
|
||||
import de.softwareapp_hb.filemanager.data.MediaStoreDeleter
|
||||
import de.softwareapp_hb.filemanager.data.SqliteTrashIndex
|
||||
import de.softwareapp_hb.filemanager.data.StorageProvider
|
||||
import de.softwareapp_hb.filemanager.data.TrashIndex
|
||||
import de.softwareapp_hb.filemanager.domain.OperationNotifier
|
||||
import de.softwareapp_hb.filemanager.service.ServiceOperationNotifier
|
||||
|
||||
@@ -34,11 +36,16 @@ class FileManagerApplication : Application() {
|
||||
lateinit var incoming: IncomingSource
|
||||
private set
|
||||
|
||||
/** Remembers what is in the trash, and where each item came from. */
|
||||
lateinit var trashIndex: TrashIndex
|
||||
private set
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
storage = StorageProvider(this)
|
||||
notifier = ServiceOperationNotifier(this)
|
||||
deleteRequests = MediaStoreDeleter(this).factory()
|
||||
incoming = ContentResolverIncomingSource(contentResolver)
|
||||
trashIndex = SqliteTrashIndex(this)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user