Make Copy to… and Cut to… the selection bar's actions
The selection bar offered Copy and Move, which only filled an in-app clipboard; the destination picker then lived behind an overflow menu, and Paste in the top bar. That made a copy a two-step detour through another folder - the thing M16's picker exists to avoid. - The bar's two verbs are now Copy to… and Cut to…, both opening the destination picker. - The clipboard state, Paste here, and the overflow's duplicate Copy to… / Move to… are removed. The picker's cut title and confirm are Cut to… / Cut here. - A copy still keeps the selection for a second destination; a cut clears it. Conflicts still ask before overwriting, naming the picked folder. - Five clipboard tests are removed; the mark, restart and undo tests now use the picker. BrowserTopBar's search and overflow sections are extracted so its two new detekt findings are fixed rather than baselined. Driven on the Xiaomi phone: Copy to… copied 120 x 16 MB through Internal storage -> AADemo -> Target and reported Copied 121 items to Target; Cut to… moved file001.bin and offered Undo; a name in the way raised Items already exist here; the top-bar overflow has no Paste. The foreground-service video was re-recorded against the new bar at 16.1 s. Verified: ./tools/verify.sh green, the code map current, 426 unit tests pass, and the video decodes as H.264 1080x2400 with no audio.
This commit is contained in:
+12
-17
@@ -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.
|
||||
|
||||
80 source files, 13902 lines - 37 test files, 431 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.
|
||||
80 source files, 13853 lines - 37 test files, 426 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`.
|
||||
|
||||
@@ -29,7 +29,7 @@ Pure Kotlin, **no Android imports**: paths, file names, kinds, sorting, formatti
|
||||
| `StoragePath.kt` | 89 | A normalized, absolute, backend-agnostic storage path. StoragePath | `StoragePathTest` (8) |
|
||||
| `ThumbnailKey.kt` | 22 | The identity of a thumbnail: which file it came from, and which version of that file. ThumbnailKey | `ThumbnailKeyTest` (4) |
|
||||
| `Timestamps.kt` | 20 | Timestamps for the details sheet. Timestamps | - |
|
||||
| `TransferPlanner.kt` | 105 | Turns "copy/paste these items into that folder" into a per-item decision, before a single byte is written. ConflictPolicy, TransferAction, TransferSource, TransferItem, TransferPlanner | `TransferPlannerTest` (5) |
|
||||
| `TransferPlanner.kt` | 105 | Turns "copy or move these items into that folder" into a per-item decision, before a single byte is written. ConflictPolicy, TransferAction, TransferSource, TransferItem, TransferPlanner | `TransferPlannerTest` (5) |
|
||||
|
||||
## data/
|
||||
|
||||
@@ -101,15 +101,15 @@ 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` | 444 | Compressing something, with the one choice that changes what comes out. CompressDialog(), 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` | 661 | The browser, and everything that can be on top of it. 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` | 391 | One immutable description of everything the browser shows. ViewMode, SearchScope, Clipboard, CompressRequest, PickerFolder, TransferPicker, MessageAction, UiMessage, ConflictPrompt, RootItem, Bookmark, DetailFocus, Undo, UndoMove, Overlay, BrowserUiState | - |
|
||||
| `BrowserViewModel.kt` | 2601 | Drives the browser screen. BrowserViewModel, ArchivePreview | `BrowserViewModelTest` (117) |
|
||||
| `BrowserScreen.kt` | 657 | The browser, and everything that can be on top of it. BrowserScreen(), messageText() | - |
|
||||
| `BrowserTopBar.kt` | 271 | The browser's app bar: title, up, the favourite star, and the search / sort / overflow actions. BrowserTopBar(), SearchFieldActions(), BrowserOverflowMenu(), SEARCH_FIELD_WIDTH | `BrowserTopBarTest` (4) |
|
||||
| `BrowserUiState.kt` | 384 | One immutable description of everything the browser shows. ViewMode, SearchScope, CompressRequest, PickerFolder, TransferPicker, MessageAction, UiMessage, ConflictPrompt, RootItem, Bookmark, DetailFocus, Undo, UndoMove, Overlay, BrowserUiState | - |
|
||||
| `BrowserViewModel.kt` | 2566 | Drives the browser screen. BrowserViewModel, ArchivePreview | `BrowserViewModelTest` (112) |
|
||||
| `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() | - |
|
||||
| `IncomingRequest.kt` | 46 | What another app asked this one to do. IncomingRequest | - |
|
||||
| `SelectionBar.kt` | 219 | The contextual action bar shown while entries are selected. StorageAccessPrompt(), SelectionBar() | `SelectionBarTest` (3) |
|
||||
| `SelectionBar.kt` | 183 | The contextual action bar shown while entries are selected. StorageAccessPrompt(), SelectionBar() | `SelectionBarTest` (3) |
|
||||
| `SortSheet.kt` | 128 | Sort key, direction, hidden files and list/grid — all in one sheet. sortKeyLabel(), SortSheet() | - |
|
||||
|
||||
## ui/viewer/
|
||||
@@ -595,7 +595,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` (117)
|
||||
### `ui/browser/BrowserViewModelTest.kt` (112)
|
||||
|
||||
- starts on the root list
|
||||
- opening a folder lists it with directories first and natural order
|
||||
@@ -613,10 +613,8 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- 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
|
||||
- a copy into the folder on screen marks the copy
|
||||
- a copy into another folder marks it there, not here
|
||||
- reading the folder again spends its marks
|
||||
- a rename marks the name it produced
|
||||
@@ -676,9 +674,6 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- rename moves the entry to the new name
|
||||
- delete removes the selected entries directly when the platform has no dialog
|
||||
- delete prefers the platform dialog and leaves the files alone until it returns
|
||||
- copy then paste duplicates into the current folder
|
||||
- cut then paste moves and clears the clipboard
|
||||
- a pasted name that already exists asks before overwriting
|
||||
- without any grant the browser asks for a folder
|
||||
- a granted tree becomes the only root
|
||||
- focusing a folder in the master pane lists it for the detail pane
|
||||
@@ -688,7 +683,7 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- a focused volume previews the contents of that volume
|
||||
- the browsed folder and view settings survive a restart
|
||||
- a search query is not restored, so the folder is not hidden on launch
|
||||
- a selection and a clipboard do not survive a restart
|
||||
- a selection does not survive a restart
|
||||
- restarting on the roots screen stays on the roots screen
|
||||
- search reaches into a subfolder, not just the one being browsed
|
||||
- clearing the query brings the folder back
|
||||
@@ -703,8 +698,8 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
- a filename cannot be a path
|
||||
- a batch rename cannot be given a path either
|
||||
- undoing a rename puts the old name back
|
||||
- undoing a cut-paste moves the item back
|
||||
- a copy is not undoable, because nothing was changed
|
||||
- undoing a cut to a chosen folder moves the item back
|
||||
- a copy to a chosen folder is not undoable, because nothing was changed
|
||||
- the undo handle is cleared once it has been used
|
||||
- a shared file is saved into the folder the user chose
|
||||
- a shared file never overwrites one already in the folder
|
||||
@@ -717,7 +712,7 @@ Every test name in the suite, by file: the fastest way to see whether something
|
||||
|
||||
### `ui/browser/SelectionBarTest.kt` (3)
|
||||
|
||||
- the destination verbs live in the overflow menu
|
||||
- the destination verbs are on the bar
|
||||
- several files are offered a rename and not the details
|
||||
- a single file keeps both
|
||||
|
||||
|
||||
Reference in New Issue
Block a user