Hierarchical Input Widget #71
Open
opened 2026-05-14 16:45:12 +00:00 by guettli
·
2 comments
No Branch/Tag Specified
main
issue-563-agentloop-validation
dummy-pr-test
issue-560-fix-firebase-run-url
issue-539-stable-imap-uid
issue-533-shared-email-list
plan-issue-555
drop-nix
plan-issue-484
plan-issue-539
plan-issue-535
plan-issue-474
plan-issue-533
fix-dagger-engineless-precommit
issue-521-fix-deploy-yml-wait-time-api
issue-502-fix-email-id-collision-mailbox
issue-492-eliminate-duplicate-build-runner
issue-494-website-change-detection
issue-491-parallelize-check
issue-478-fix-stalwart-dual-stack-bind
issue-475-allowed-addresses-glob
issue-473-search-result-reorder
issue-453-update-agentloop-defaults
issue-466-structured-search
issue-505-exclude-chaos-monkey-from-regular-ci
issue-509-fix-search-result-sorting
fix-ink-sparkle-remaining-tests
issue-506-fix-search-emails-tests
issue-504-runner-wait-time
issue-488-search-notes
issue-472-changelog-issue-links
issue-501-folder-search-local-sqlite
issue-486-fix-stale-test-shader-mismatch
fix/prevent-settled-search-rerun-473
issue-467-fix-search-stale-results
issue-446-installed-versions-in-changelog
issue-462-fix-pr
issue-448-chaos-monkey-test
issue-436-notes-on-emails
issue-429-unify-mail-display
issue-422-move-to-folder-create-new
issue-414-ensure-not-run-as-root
issue-424-unify-email-list-views
issue-419-trusted-senders-page
issue-425-fix-prs
test-foo
issue-421-bug-report
issue-383-fix-ci
issue-394-fix-deploy-flutter-version
issue-391-fix-ci-double-trigger
issue-376-combined-inbox-v2
issue-376-combined-inbox
issue-384-fix-open-prs
sops-migrate
issue-339-safe-first-on-imap-fetch
issue-340-try-catch-measure-height
issue-342-pin-intl-version
issue-341-guard-threademails-last
issue-335-agentloop-code-test
issue-329-fix
issue-315-fix
issue-320-fix
issue-325-fix
issue-312-fix
issue-311-fix
issue-305-fix
issue-304-fix
issue-299-fix
issue-300-fix
issue-298-fix
issue-296-fix
issue-294-fix
issue-289-fix
issue-288-fix
issue-287-fix
issue-286-fix
issue-277-fix
issue-282-fix
issue-280-fix
issue-272-fix
issue-268-fix
issue-267-fix
issue-266-fix
issue-258-fix
issue-260-fix
issue-257-fix
issue-253-fix
issue-216-fix
issue-251-fix
issue-249-fix
issue-question-fixes
issue-235-fix
issue-236-fix-v2
issue-237-fix
issue-236-fix
issue-228-fix
issue-217-fix
issue-214-fix
issue-213-fix
issue-208-fix
issue-205-fix
issue-204-fix
issue-203-fix
issue-202-fix
issue-129-fix
issue-161-fix
issue-160-fix
issue-201-fix
issue-210-fix
issue-198-fix
issue-200-fix
issue-144-fix
issue-199-fix
fix/playstore-upload-use-requests
issue-193-fix
issue-186-fix
issue-185-fix
issue-192-fix
issue-183-fix
issue-175-fix
issue-172-fix
issue-171-fix
issue-167-fix
issue-136-fix
issue-162-fix
issue-179-fix
issue-155-fix
issue-154-fix
issue-152-fix
issue-151-fix
issue-141-fix
issue-150-fix
issue-164-fix
migrate-to-dagger
task/d1-ci-matrix
task/a4-typeconverter-json
task/u7-onboarding-walkthrough
task/d3-sync-doc
task/a5-layer-boundary-lint
task/t5-golden-tests
task/p5-date-cache
task/s4-link-handling
task/p3-html-parse-isolate
task/u8-mark-all-read
task/u3-recent-searches
task/a3-jmap-injectable-http-client
task/r5-tls-error-handling
fix/playstore-redirect-retry
task/t3-repository-contract-tests
task/p2-email-list-pagination
task/p1-fts5-search
fix/playstore-upload-timeout
task/a1-email-detail-notifier
fix/upgrade-workmanager-0.9
fix/android-core-library-desugaring
task/p4-db-indexes
task/r3-html-error-boundary
task/d2-check-coverage
task/a2-email-tile
task/t4-migration-tests
task/t2-widget-tests
task/t1-email-repo-coverage
task/u6-connection-status
task/u4-push-notifications
task/u2-draft-sync
task/u1-list-unsubscribe
task/s2-hostname-validation
task/r6-reliability-fuzz-tests
task/r4-sync-error-banner
task/r2-force-resync
task/r1-undo-history-persistence
No results found.
Labels
Clear labels
NeedSupervisor
State/InProgress
State/Later
State/Planned
automerge
ci-failure
do-not-merge
loop/code
loop/code-ci-pending
loop/code-done
loop/code-in-process
loop/merge
loop/merge-done
loop/merge-in-process
loop/plan
loop/plan-done
loop/plan-in-process
Issue escalated to a human supervisor; agentloop will skip it until cleared.
Eligible for automatic merge by CI
Issue opened by agentloop to track a failing CI workflow; used for deduplication.
Plan PR — review only, do not merge.
Add to run the built-in "code" prompt; override at prompts/code.md.
Prompt "code" finished; waiting for the PR's CI to pass before advancing.
Prompt "code" finished successfully.
Agent for the "code" prompt is currently running on this issue.
Managed by agentloop
Managed by agentloop
Managed by agentloop
Add to run the built-in "plan" prompt; override at prompts/plan.md.
Prompt "plan" finished successfully.
Agent for the "plan" prompt is currently running on this issue.
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: guettli/sharedinbox#71
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
When looking at a mail, or pressing on a mail in the list-view, there should open a hierarchical option list around the place where the user pushed the screen.
This input should be a generic input widget, and should be in its own git repo.
The possiblities of inputs should be a DAG.
Each level should not have more than 8 items, but it is up to the widget user to decide that.
Roughly 1.5cm around the finger of the user there should be N items. Moving to one item, selects it. Now there could be again N sub-items or the item is a final item. Then it the selected one.
How to develop something like that, so that it is re-usable in almost all Flutter applications?
Create a plan. Don't implement.
Are there already similar input widgets?
Set Label "State/Question" when done.
Existing similar widgets
star_menusupports nested/hierarchical menus but is aging.pie_menuis actively maintained but flat only. Neither supports a DAG structure or the continuous-drag-to-select gesture described.Plan:
dag_pieFlutter packageConcept: A radial overlay widget where items appear ~1.5 cm around the touch point. Dragging the finger toward an item hovers/selects it. Releasing on a leaf node returns the selection; releasing on an intermediate node replaces the current ring with its children (breadcrumb navigation through the DAG).
Public API sketch
Key implementation pieces
GestureDetectoronLongPressoronTapDownto record touch point;GestureDetector.onPanUpdateto track drag direction and highlight the nearest item.OverlayEntrypositioned at the touch point, drawn withCustomPainter(arcs + icons). NoshowDialog— must not block the rest of the UI.MediaQuery.devicePixelRatio+PlatformDispatcher.viewsfor physical-to-logical conversion). Clamp to screen edges.currentParentIdstack. On hover of an intermediate node, animate the current ring out and the children ring in. Back-swipe or centre-tap goes up a level.AnimationController+CurvedAnimationfor ring appear/disappear;TweenAnimationBuilderfor item highlight.dag_pie(or similar) with zero dependencies on SharedInbox internals. OnlyflutterSDK.Open questions before implementation
Setting State/Question — please review the plan and answer the open questions before I start implementation.
Plan: Hierarchical Radial Input Widget (standalone Flutter package)
Existing similar widgets
pie_menu(pub.dev)radial_menu(pub.dev)flutter_context_menuNone of the existing packages support a multi-level DAG with sub-menus opening around the finger position. A new package is warranted.
Design
Interaction model:
DAG model:
Callers pass a root
List<RadialItem>(up to 8 items per level). Each item can have its own children. The widget enforces the ≤ 8 limit; extras are silently dropped or trigger an assertion in debug mode.Layout algorithm
1.5 cm=physicalSize / devicePixelRatio * 56(approx 56 logical px ≈ 1.5 cm on a 150 dpi screen; configurable).API (package public surface)
Repository structure (standalone package)
Hosted on Codeberg (or pub.dev if published). In
sharedinbox, add it as a path dependency initially, then switch to a version dependency once stable.Open questions (setting label "State/Question")