Repository navigation
Instance Folders and Drag & Drop - #135
Conversation
vertical_rule nesting indicator
clean up code tho)
`::new` methods for many config structs
- add icons to context menu buttons - split sidebar messages into SidebarMessage, rename stuff - adjust drag/drop and context menu handling
There was a problem hiding this comment.
Pull request overview
This PR introduces a new sidebar model centered around folders + drag & drop + context menus, alongside a broader refactor that splits “main menu” vs “sidebar” events into dedicated message enums and update handlers. It also updates persisted config/JSON handling to better preserve unknown fields across versions.
Changes:
- Added a persisted sidebar tree (
SidebarConfig) supporting folders, expand/collapse, rename, delete, and drag & drop reordering. - Refactored UI messaging by introducing
MainMenuMessageandSidebarMessage, plusFrom<...> for Messageconversions to simplify.into()usage across the UI. - Various UI/UX polish: context-menu closing behavior, onboarding welcome navigation tweaks, and config schema forward-compat via
#[serde(flatten)] _extra.
Reviewed changes
Copilot reviewed 78 out of 79 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| quantum_launcher/src/view.rs | Wraps root view in a mouse area to hide modals on click; updates window message .into() usage. |
| quantum_launcher/src/update.rs | Routes new MainMenuMessage/SidebarMessage; updates config sidebar on list load; introduces CoreHideModal. |
| quantum_launcher/src/tick.rs | Converts nested message construction to .into() pattern. |
| quantum_launcher/src/stylesheet/widgets.rs | Adds FlatExtraDarkDead button style; adjusts text input colors. |
| quantum_launcher/src/stylesheet/styles.rs | Styles FlatExtraDarkDead; minor style refactors. |
| quantum_launcher/src/state/mod.rs | Converts message wrapping to .into(). |
| quantum_launcher/src/state/message.rs | Adds SidebarMessage + MainMenuMessage; adds From<T> for Message macro conversions; adds CoreHideModal. |
| quantum_launcher/src/state/menu.rs | Expands LaunchModal for sidebar context menu/dragging/renaming; adds helper for drag modal state. |
| quantum_launcher/src/mods_store.rs | Uses .into() for InstallModsMessage. |
| quantum_launcher/src/message_update/shortcuts.rs | Uses .into() conversions for shortcut messages. |
| quantum_launcher/src/message_update/recommended.rs | Uses .into() conversions for recommended-mods messages. |
| quantum_launcher/src/message_update/presets.rs | Uses .into() conversions for presets messages. |
| quantum_launcher/src/message_update/mod.rs | Adds message_update/launch.rs; converts many message mappings to .into(). |
| quantum_launcher/src/message_update/manage_mods.rs | Uses .into() conversions for manage-mods messages. |
| quantum_launcher/src/message_update/launch.rs | New: handles MainMenuMessage and SidebarMessage updates (resize/scroll/folder ops/drag&drop). |
| quantum_launcher/src/message_update/edit_instance.rs | Uses MainMenuMessage::ChangeTab and some config constructor helpers. |
| quantum_launcher/src/message_update/create_instance.rs | Uses .into() conversions for create-instance messages. |
| quantum_launcher/src/message_update/accounts.rs | Uses .into() conversions; uses ConfigAccount::from_account. |
| quantum_launcher/src/message_handler/mod.rs | Uses .into() conversions for child messages. |
| quantum_launcher/src/message_handler/iced_event.rs | Updates keyboard handling to new message types; makes hide_submenu public. |
| quantum_launcher/src/menu_renderer/sidebar/mod.rs | New: renders folder/instance nodes with context menus, drag handles, and drop receivers. |
| quantum_launcher/src/menu_renderer/sidebar/drop_recv.rs | New: drop target UI for drag & drop (before/after/inside). |
| quantum_launcher/src/menu_renderer/shortcuts.rs | Uses .into() conversions for shortcut UI events. |
| quantum_launcher/src/menu_renderer/settings.rs | Uses config helper c_idle_fps; minor UI layout tweaks; .into() conversions. |
| quantum_launcher/src/menu_renderer/onboarding/welcome.rs | Welcome screen layout + keyboard navigation; offline username now uses MainMenuMessage::UsernameSet. |
| quantum_launcher/src/menu_renderer/onboarding/mod.rs | Minor type-path cleanup for widget types. |
| quantum_launcher/src/menu_renderer/mods/presets.rs | .into() conversions for presets/recommended/mods navigation. |
| quantum_launcher/src/menu_renderer/mods/mods_store.rs | .into() conversions for mods store UI. |
| quantum_launcher/src/menu_renderer/mods/mods_manage.rs | Improves context menus w/ icons; uses offset helper; .into() conversions. |
| quantum_launcher/src/menu_renderer/mods/jarmods.rs | .into() conversions for jarmods UI events. |
| quantum_launcher/src/menu_renderer/mods/install_loader.rs | .into() conversions for installer UI events. |
| quantum_launcher/src/menu_renderer/mods/export_mods.rs | .into() conversions for export-mods UI events. |
| quantum_launcher/src/menu_renderer/mod.rs | Adds sidebar module; introduces icon+text ctx button helper; adds generic offset helper. |
| quantum_launcher/src/menu_renderer/login.rs | .into() conversions for account UI events. |
| quantum_launcher/src/menu_renderer/launch.rs | Integrates new sidebar renderer + sidebar context menu/drag tooltip; rewires sidebar scroll/resize messages. |
| quantum_launcher/src/menu_renderer/edit_instance.rs | .into() conversions and small UI sizing tweaks. |
| quantum_launcher/src/menu_renderer/create.rs | .into() conversions; uses offset helper; sidebar scrollable id cleanup. |
| quantum_launcher/src/main.rs | Uses c_idle_fps; doc tweak. |
| quantum_launcher/src/config/sidebar/types.rs | New: sidebar node types, selection types, and drag location types. |
| quantum_launcher/src/config/sidebar/mod.rs | New: persisted sidebar tree with folder ops + dedupe “fix()”. |
| quantum_launcher/src/config/sidebar/drag_drop.rs | New: drag/drop mutation logic (remove/insert + illegal-location checks). |
| quantum_launcher/src/config/mod.rs | Adds sidebar config + c_sidebar() and c_idle_fps(); adds _extra preservation fields; adds sidebar sync from instance lists. |
| quantum_launcher/src/cli/mod.rs | Minor doc wording updates. |
| quantum_launcher/Cargo.toml | Reorders deps; adds rand for folder IDs. |
| docs/ROADMAP.md | Minor wording update. |
| docs/CODEBASE.md | Minor wording update. |
| crates/ql_servers/src/run.rs | Comment wording update. |
| crates/ql_servers/src/create.rs | Uses new InstanceConfigJson::new(...) constructor. |
| crates/ql_servers/Cargo.toml | Dependency cleanup. |
| crates/ql_packager/src/multimc.rs | Simplifies fabric install call path. |
| crates/ql_mod_manager/src/store/mod.rs | Improves comment formatting. |
| crates/ql_mod_manager/src/loaders/paper.rs | Uses ModTypeInfo::new_regular. |
| crates/ql_mod_manager/src/loaders/neoforge.rs | Uses ModTypeInfo::new_regular. |
| crates/ql_mod_manager/src/loaders/forge/server.rs | Uses ModTypeInfo::new_regular. |
| crates/ql_mod_manager/src/loaders/forge/mod.rs | Uses ModTypeInfo::new_regular; comment punctuation. |
| crates/ql_mod_manager/src/loaders/fabric/mod.rs | Uses ModTypeInfo::new_regular/new_with_backend. |
| crates/ql_mod_manager/Cargo.toml | Dependency cleanup. |
| crates/ql_java_handler/src/lib.rs | Doc wording update. |
| crates/ql_java_handler/Cargo.toml | Dependency cleanup. |
| crates/ql_instances/src/lib.rs | Doc wording update. |
| crates/ql_instances/src/launcher_update_detector.rs | Doc formatting. |
| crates/ql_instances/src/download/libraries.rs | Adds cleanup of extracted natives junk; renames LWJGL URL constants; comment tweaks. |
| crates/ql_instances/src/download/downloader.rs | Uses InstanceConfigJson::new(...) constructor. |
| crates/ql_core/src/progress.rs | Doc wording update. |
| crates/ql_core/src/lib.rs | Minor trait import cleanup; doc tweak. |
| crates/ql_core/src/json/instance_config.rs | Adds constructors + _extra preservation fields to multiple JSON structs. |
| changelogs/unreleased.md | Adds TLDR + entries for instance folders and modal closing fix. |
| changelogs/0.5.md | Minor text tweaks. |
| changelogs/0.4.md | Formatting and wording tweaks. |
| changelogs/0.4.2.md | Formatting tweaks. |
| changelogs/0.4.1.md | Formatting and wording tweaks. |
| changelogs/0.3.md | Formatting and wording tweaks. |
| changelogs/0.3.1.md | Formatting and wording tweaks. |
| changelogs/0.2.md | Formatting and wording tweaks. |
| changelogs/0.1.md | Formatting tweaks. |
| assets/freedesktop/quantum-launcher.metainfo.xml | XML formatting cleanup; release date/description updates. |
| README.md | Simplifies/edits comparison section wording. |
| Cargo.lock | Reflects dependency changes (e.g., rand). |
| CONTRIBUTING.md | Minor wording tweak. |
Comments suppressed due to low confidence (3)
quantum_launcher/src/config/mod.rs:28
- Typo/grammar:
Optionis plural here, not possessive. Consider changing this to “Many fields areOptions for backwards compatibility.”
quantum_launcher/src/config/mod.rs:195 SidebarNodeKind::Folder { .. }is a struct-variant pattern, butSidebarNodeKind::Folderis defined as a tuple variant (Folder(SidebarFolder)), so this match arm won't compile. UseSidebarNodeKind::Folder(_).
quantum_launcher/src/config/mod.rs:193update_sidebarcurrently removes all sidebar instance nodes whoseInstanceKinddoesn't matchis_server(because the retain closure requires*instance_kind == kind). Sincecore_list_loadedis called separately for clients and servers, this will wipe the other kind from the persisted sidebar. Keep nodes of the otherInstanceKind(returntruefor them), and only filter byinstancesfor the matching kind. Also consider precomputinginstancesinto aHashSetto avoid repeatedVec::containsscans.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| match &self.kind { | ||
| SidebarNodeKind::Instance(kind) => { | ||
| kind.is_server() == other.is_server() && self.name == other.get_name() | ||
| } | ||
| SidebarNodeKind::Folder { .. } => false, | ||
| } |
There was a problem hiding this comment.
SidebarNodeKind::Folder { .. } doesn't match the SidebarNodeKind::Folder(SidebarFolder) tuple variant and will fail to compile. Use SidebarNodeKind::Folder(_) instead.
| self.config.c_sidebar().drag_drop(being_dragged, location); | ||
| if let Some(sel) = &self.selected_instance { | ||
| if being_dragged != sel { | ||
| self.selected_instance = None; | ||
| } | ||
| } |
There was a problem hiding this comment.
In DragDrop, the currently selected instance is cleared whenever the dragged item is not the selected instance. This also clears selection when dragging a folder or dragging a different instance, which is surprising UX (moving other items shouldn't deselect the active instance). Consider only clearing selected_instance if the selected instance is the one being moved/removed, or if the drag-drop operation actually made the selected instance invalid.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This PR aims to overhaul the sidebar with folders to store instances in, drag & drop, context menus, and more.