Ubisam-MobileGit/tasks/056-reading-gestures-and-fast-listing.md
choiminyeong fa87a0b32f TASK-056: edge-swipe outline, resizable pair, tree-based directory listing
- Code viewer: the outline opens with a swipe from the left edge and closes
  with a swipe left, with one pane or two.
- Side-by-side .h/.cpp: a draggable handle resizes the panes (20% to 80%).
- Directory listing reads Git tree objects instead of the contents endpoint,
  which looked up the last commit of every entry.
- A listing that needs more than one request shows percent and count.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-28 15:29:10 +09:00

4.6 KiB

TASK-056: Reading gestures, a resizable pair, and fast directory listing

Status: implemented; required checks pass; installed on the product owner's Z Fold7, awaiting their confirmation Owner: Claude Reviewer: human product owner

Outcome

Second round of requests from the human product owner after using the app on their Galaxy Z Fold7 (SM-F966N), 2026-09-28.

Scope

  • Included:
    1. Code viewer: swiping right from the far left edge brings the outline tree in; swiping left puts it away. This also works while a .h and a .cpp are shown side by side.
    2. Side-by-side pair: a handle between the two panes is dragged to resize them. Dragging left gives the .cpp (right) more room, dragging right gives the .h (left) more room. Neither pane can be made narrower than 20% of the width.
    3. Directory listing is read from Git's tree object (/repos/{owner}/{repo}/git/trees/{sha}) instead of the contents endpoint. The contents endpoint looks up the last commit of every entry, so its cost grows with the number of files.
    4. A directory listing that takes more than one request shows a progress bar with the percentage and the count ("40% · 200 / 500개").
  • Excluded:
    • A percentage while a single file loads. A file arrives as one response; there is nothing to measure it against until it has arrived. The indeterminate indicator stays.
    • A percentage for a directory that fits in one request (up to 100 entries): it goes from nothing to complete in one step, so there is no intermediate value to show.

Writable paths

  • app/src/main/java/com/ubisam/ubgitea/data/repositories/GiteaRepositoryBrowserApi.kt
  • app/src/main/java/com/ubisam/ubgitea/feature/codebrowser/
  • app/src/main/res/values/strings_codebrowser.xml
  • app/src/test/java/com/ubisam/ubgitea/
  • tasks/, docs/

Acceptance criteria

  • The outline opens from the left edge and closes with a swipe left, with one pane or two.
  • The split is draggable, clamped, and survives rotation (rememberSaveable).
  • The root of a ref is listed from the tree of that ref's commit; a directory reached by walking down is listed from its own tree.
  • A ref containing / works: it is passed as a query parameter, never as a path segment.
  • When the ref moves, directory ids remembered for the old commit are dropped.
  • A directory whose tree id is not known (opened directly, not by walking down), or a ref the commit lookup cannot resolve, is still listed through the contents endpoint.
  • Symbolic links (mode 120000) and submodules (commit) keep their types.
  • Unit tests cover each of the above for the listing, and the split's clamp.

How the listing works

A tree is addressed by its id, and a directory's id is only known from the listing of its parent.

  1. Root: GET commits?sha={ref}&limit=1&stat=false&files=false&verification=false gives the commit; GET git/trees/{commit} gives the root's entries.
  2. Each listing remembers the id of every directory in it, keyed by repository, ref and path.
  3. A subdirectory is listed with GET git/trees/{remembered id}.
  4. Every listing of the root compares the commit with the one remembered. If it changed, all ids remembered for that ref are dropped.

The remembered ids live in memory only, for the life of the process.

Security and privacy

No additional concerns. The same authenticated transport and the same host are used; no new data is stored, and nothing is logged.

Required checks

./gradlew compileDebugKotlin compileDebugUnitTestKotlin testDebugUnitTest assembleDebug lintDebug

Evidence

  • Required checks pass: 427 unit tests, 0 failures; lint 0 errors.
  • Measured from a PC against the company Gitea 1.23.5, on a public repository, a directory of 30 entries: contents endpoint about 0.33 s, tree endpoint 0.04 to 0.06 s, commit lookup 0.05 s. These are request times from a PC, not timings taken inside the app.
  • Installed on the SM-F966N over wireless adb.
  • Not verified by the implementer on the device: the gestures, the handle, the listing speed as felt in the app, and the progress bar. No directory with more than 100 entries was opened, so the progress bar has only been exercised by reasoning and by the paging unit test.

Known limitations

  • Opening a subdirectory costs one request; opening the root costs two (commit, then tree).
  • A subdirectory opened after the ref moved, without the root being listed again, shows the tree of the commit it was remembered from until the root is next listed.
  • The tree endpoint gives no last-commit information per entry. The listing never showed any, so nothing visible is lost.

Review findings

None yet.