A copy into a picked folder says where it went, and Show takes you there
The last acceptance criterion M16 had left open. After Copy to..., the snackbar reads 'Copied to AADst' with a Show button; after a move to a picked folder it keeps the undoable message instead, because the sources are gone and Show would lead nowhere. Two things needed care rather than a string. The action button was hard-wired to undo() - the label was a parameter beside it, which let the two disagree - so UiMessage now carries a MessageAction, and the label follows from it: Undo for an undo, Show for a jump. And a message cannot name a folder from the path alone: a volume root has no name of its own, and internal storage's is 0. The message carries the picked PickerFolder, and the screen resolves its label the way breadcrumbs do - so copying into the root reads 'Copied to Internal storage', which is the case a plain path.name would have got wrong. Four tests: the message names the destination and offers Show; Show opens it; a paste into the folder on screen still names nothing and offers nothing (its destination is the screen); a move to a picked folder offers Undo. All four driven through the view model, and both snackbar variants checked on the phone, including the volume-root one. detekt's SpreadOperator baseline entries moved with the expression, so the message building is now a small helper with a deliberate suppression and a reason, and the baseline was regenerated: three obsolete entries removed, none added.
This commit is contained in:
+10
-5
@@ -2,7 +2,7 @@
|
||||
|
||||
Generated from the source by `tools/make-code-map.py` - do not edit by hand. Regenerate it after a change (`python3 tools/make-code-map.py`); `--check` exits non-zero when this file is stale.
|
||||
|
||||
79 source files, 13393 lines - 35 test files, 404 tests. The behaviour index at the end lists every test name, and in this project a test name is a sentence about what the app does, so it doubles as the specification.
|
||||
79 source files, 13481 lines - 35 test files, 409 tests. The behaviour index at the end lists every test name, and in this project a test name is a sentence about what the app does, so it doubles as the specification.
|
||||
|
||||
Start at `AGENTS.md`. What is done, and why: `docs/ROADMAP.md` and `CHANGELOG.md`. What was verified by hand rather than by a test: `docs/EDGE_CASE_TESTING.md`.
|
||||
|
||||
@@ -100,10 +100,10 @@ The browser screen: view model, state, list and grid, dialogs, selection bar
|
||||
| `BrowserDetailPane.kt` | 131 | The second pane of the wide layout: what is inside the folder the user picked, or a preview and the details of the file they picked. DetailPane(), FolderPreview(), ImagePreview() | - |
|
||||
| `BrowserDialogs.kt` | 385 | The Copy to… / Move to… picker. TransferToDialog(), titleFor(), hereFor(), BatchRenameDialog(), PREVIEW_NAMES, batchRenameNote(), NameDialog(), ConfirmDialog(), ConflictDialog() | `BrowserDialogsTest` (5) |
|
||||
| `BrowserRoots.kt` | 270 | A row on the root screen: a volume, with its free space when the platform reports it. RootRow(), itemCountLabel(), EmptyState(), LibrarySectionHeader(), BookmarkSectionHeader(), SectionHeader(), BookmarkRow(), LibraryRow(), Breadcrumbs() | `BrowserRootsTest` (4) |
|
||||
| `BrowserScreen.kt` | 603 | BrowserScreen() | - |
|
||||
| `BrowserScreen.kt` | 622 | The text of a snackbar message. BrowserScreen(), messageText() | - |
|
||||
| `BrowserTopBar.kt` | 238 | The browser's app bar: title, up, the favourite star, and the search / sort / overflow actions. BrowserTopBar(), SEARCH_FIELD_WIDTH | `BrowserTopBarTest` (4) |
|
||||
| `BrowserUiState.kt` | 348 | One immutable description of everything the browser shows. ViewMode, SearchScope, Clipboard, PickerFolder, TransferPicker, UiMessage, ConflictPrompt, RootItem, Bookmark, DetailFocus, Undo, UndoMove, Overlay, BrowserUiState | - |
|
||||
| `BrowserViewModel.kt` | 2392 | Drives the browser screen. BrowserViewModel, ArchivePreview | `BrowserViewModelTest` (97) |
|
||||
| `BrowserUiState.kt` | 379 | One immutable description of everything the browser shows. ViewMode, SearchScope, Clipboard, PickerFolder, TransferPicker, MessageAction, UiMessage, ConflictPrompt, RootItem, Bookmark, DetailFocus, Undo, UndoMove, Overlay, BrowserUiState | - |
|
||||
| `BrowserViewModel.kt` | 2430 | Drives the browser screen. BrowserViewModel, ArchivePreview | `BrowserViewModelTest` (102) |
|
||||
| `DetailsSheet.kt` | 109 | Name, location, size, type and modified date for one entry. DetailsSheet(), DetailLines(), DetailLine() | - |
|
||||
| `EntryIntents.kt` | 58 | Wraps an entry's path in a content:// URI another app may read. contentUriFor(), viewIntent(), shareIntent() | - |
|
||||
| `IncomingBar.kt` | 60 | The bar shown while another app is waiting on this one. IncomingBar() | - |
|
||||
@@ -581,7 +581,7 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- a library or the root list has nothing to star
|
||||
- the star gives way to the search field
|
||||
|
||||
### `ui/browser/BrowserViewModelTest.kt` (97)
|
||||
### `ui/browser/BrowserViewModelTest.kt` (102)
|
||||
|
||||
- starts on the root list
|
||||
- opening a folder lists it with directories first and natural order
|
||||
@@ -596,6 +596,11 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- the picker walks up to the volumes and back down
|
||||
- a conflicting destination asks before overwriting, naming that folder
|
||||
- cancelling the picker copies nothing
|
||||
- a copy says where it went and offers to show it
|
||||
- show takes the user to the folder the copy went to
|
||||
- a paste into the folder on screen names no destination and offers no action
|
||||
- the message's undo action is the undo
|
||||
- a move to a chosen folder offers undo rather than show
|
||||
- navigating up goes to the parent then to the roots
|
||||
- selection survives toggling and clears on navigation
|
||||
- a file with no preview of its own is handed to the system
|
||||
|
||||
@@ -298,6 +298,10 @@ Driven on the phone through the real UI (`adb` taps on `uiautomator` dumps), wit
|
||||
- **Move** into a picked folder: the same walk into `AAMv`. `AASrc` ended up empty, `AAMv` held the
|
||||
file, the snackbar said *Moved 1 item*, the listing said *This folder is empty*, and the selection bar
|
||||
was gone.
|
||||
- **The message and its Show button.** After a copy into `AADst` the snackbar read *Copied to AADst* with
|
||||
**Show**, and tapping Show opened `AADst` with the copied file in it. Repeated into a volume root — the
|
||||
case where the path has no name of its own — it read *Copied to Internal storage*, which is the label
|
||||
rule doing its job rather than `0` leaking into a sentence.
|
||||
- **The trail and the volume row.** Both first read the platform's own name for internal storage —
|
||||
`0 / AADst` and a row labelled `0` — which is correct as a path and useless as a label. Fixed by
|
||||
giving the picker the same label rule as the roots screen; the second pass reads *Internal storage /
|
||||
|
||||
+8
-4
@@ -64,8 +64,10 @@ would no longer have.
|
||||
|
||||
## The queue after 1.0
|
||||
|
||||
Ordered by what it protects, not by what is fun. Nothing here is scheduled; the first two are what a
|
||||
release should not go out without.
|
||||
Ordered by what it protects, not by what is fun. **Four of the five items are done** — thumbnails, the
|
||||
scaling numbers (which turned into progressive listing), Copy to… / Move to…, and the CI benchmark. What is
|
||||
left is the baseline profile's *measurement*, which needs a physical API 33+ device and cannot be finished
|
||||
on this machine; everything else in the list says what it produced.
|
||||
|
||||
1. **Baseline profile** — **generated and committed**: `app/src/main/baseline-prof.txt` is bundled in the
|
||||
release APK, written by the `:baselineprofile` module. What remains is its *measurement*: collection
|
||||
@@ -90,8 +92,10 @@ release should not go out without.
|
||||
two taps; a move clears it. Conflicts ask the same question as a paste, naming the picked folder. Seven
|
||||
tests cover the verbs, the picker's walk, folders-only listing, the conflict target, cancellation, and
|
||||
the selection rule. Driven on the phone for both verbs (see `EDGE_CASE_TESTING.md`), which is what caught
|
||||
the picker naming internal storage by its raw name `0`. **Not done**: the "copied to X — Show" message
|
||||
with a jump to the destination; the copy reports itself the way a paste does.
|
||||
the picker naming internal storage by its raw name `0`. A copy into a picked folder says **"Copied to
|
||||
<folder>"** and offers **Show**, which opens that folder — the destination's label resolved the way
|
||||
breadcrumbs are, so a volume root reads *Internal storage* rather than `0`. A move keeps the undoable
|
||||
message instead, because its sources are gone.
|
||||
5. **A CI run of the benchmarks on an emulator** — **done**: `.github/workflows/benchmark.yml` runs the four
|
||||
benchmarks on API 35 (`reactivecircus/android-emulator-runner`, `google_apis`, x86_64, SwiftShader) on
|
||||
demand and every Monday, installs the app and resets its compilation before instrumenting it, pulls the
|
||||
|
||||
Reference in New Issue
Block a user