From e79e0d024bc98670529349c871cdcd4bdf91dce8 Mon Sep 17 00:00:00 2001
From: Truman Gao <106889354+tdgao@users.noreply.github.com>
Date: Mon, 17 Aug 2026 19:08:09 -0600
Subject: [PATCH] feat: app onboarding and library (#6923)
* refactor: remove unused legacy onboarded flag
* sqlx prepare
* feat: add onboarding checklist app db and add vue provider
* feat: add welcome page
* feat: add onboarding checklist component
* feat: move checklist visibility source of truth in app db
* feat: split up import modpack button
* feat-small: style tweak
* feat: remove discover section from homepage and add library
* refactor: move welcome screen to component
* refactor: move grid display into /library
* refactor: rename existing components
* refactor: split up the current library page files
* feat: add create group modal
* feat: add instance group definitions
* feat: update accordian for instance groups
* feat: add delete group
* feat: implement rename instance groups
* refactor: move instance group api out
* feat: add context menu for groups
* feat: style instance items in library
* feat: add selected instance item state
* feat: implement action bar for selection
* feat: drag and drop to move between groups
* feat: show ungrouped with header
* feat: improve edit group name
* small fix
* small style fixes
* feat: improve selection behaviour
* fix: dont toggle group when context menu open
* feat: drag and drop multiple selected
* small
* feat: add remove from group in action bar
* feat: add delay on icon hiding in inline input
* feat: improve icon hiding delay
* fix: bad routes.js
* feat: implement sort and filter options
* refactor: dont prefix filenames
* feat: change open/collapse group target
* feat: improve ungrouped behaviour
* feat: add shift to select multiple instances
* fix: icon disappear transition
* feat: add esc while dragging to cancel
* feat: update sorting and moved label
* feat: update context menu
* fix: multiple context menus can be opened
* refactor: instance groups to be identified by ID instead of name, names become display data
* feat: creating new group always adds instance
* feat: create group button, fix instance selection, and increase group name max length
* feat: strokes
* fix: show getting started checklist in all sidebar
* feat: set size on microsoft login screen
* fix: use ButtonStyled in Chips component
* feat: creating groups with selected instances and fix some moving selection and duplication bugs
* pnpm prepr
* feat: add tooltip for instance already in group
* feat: create instance with content in creation flow modal
- search modpack becomes search projects
- creation flow modal context receives prepareProjectInstall and createProjectInstall callbacks, from content-install.ts (shared with ContentInstallModal)
* feat: update instance card styles
* refactor: separate out instance card content
* update styles
* refactor: instance card
* fix: width of instance
* feat: update empty state
* feat: update sort and grouping dropdowns
* feat: better context menu options
* feat: add group action buttons
* feat: add/remove favourites group
* remove manual sort
* feat: improve the "New group" jank
* feat: add group by instance type and change group sorting
* feat: welcome screen styles match figma
* feat: not signed in skins demo
* feat: new hosting empty state
* feat: new instance card style
* feat: add tooltip and spice up animation more
* feat: improve the transitions for groups after dropping many instances
* feat: set instance group membership for bulk moving
* feat: remove fade out
* fix: allow dragging from buttons inside instance card
* fix: library page load in behaviour
* small fix
* feat: add group ordering and reordering
* feat: add drag to reorder groups
* fix: switching page not clearing selected instances
* style fixes
* style fix
* fix spacing
* feat: jump in changes
* feat: add styled newly created instances
* feat: improve jump in cards styles
* fix: welcome screen style
* fix: empty state styles
* feat: max 5 jump in items
* feat: max new instances to 3
* fix: search icon
* feat: clear selection after move
* feat: skins list use check icon styles
* feat: list will be deleted instances and default sort last played
* fix: stroke
* remove: no more group settings in instance general settings
* fix: resolving modpack server install
* feat: icon editor
* feat: add three hue shifted variants
* fix: surprise me doesnt pick symbol
* feat: add customize icon to create instance modal
* feat: skins loading state style
* fix: welcome logo
* fix: copy
* fix: left over usage of ButtonStyled from main's refactor
* feat: some leaked merge stuff
* feat: server empty state styles
* remove: instance helper text
* remove: auto link in set up stage
* feat: auto focus on search when modal open
* fix: delete instance modal style
* remove: modpack meta repeating
* fix: icon
* fix: font weight
* fix: dropdown filter preview heights
* pnpm prepr
* fix: sign into modrinth flashing change in position
* feat: add avatar transparent corner gets padding
* feat: drag and hold over group opens group
* feat: add random icon for custom instance
* feat: update loading icon
* polish: empty state for search
* polish: jump in cards
* fix: avatar could skip checking for image if tauri loads it first
* feat: add icon customize and randomizer in content install modal for add to new instances
* fix: avatar cannot read image pixels due to cors
* refactor: popup notifications toast type for instance sharing notifications
* feat: apply random icons modal and add popup notification for it
* polish: style
* fix: set_webview_visible
* QA
* qa
* feat: add inner white 15 opacity stroke around avatar
* add to catalog
* pnpm prepr
* fix: app event import
* feat: add new icons and backgrounds for icon editor
* feat: recents list generate from randomized icons and save icon in editor + icon editor modal fixes
* qa
* refactor: recipe -> config
* fix: event bus
* polish
* feat: add safe guard against randomizing empty icons
* feat: navigate to instance after creation
* fix: icon file names
* i18n on welcome screen
* i18n pass on PR
* fix: inconsistent max group name length
* refactor: use sqlx macro
* feat: add instance icon background selection drag
* feat: update catalog order
* fix: remove gradient for welcome screen
* remove: frog
* fix: min width
* feat: update corner size
* fix: context menu styles
* prepr
* fix: instance name trimming
* reorder
* fix: instance card loading state stayed until hovering
* feat: add icon randomizer blacklist
* blog
* prepr
---------
Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
---
apps/app-frontend/package.json | 1 +
apps/app-frontend/src/App.vue | 219 ++-
.../src/assets/icons/instance-file.svg | 3 +
.../src/assets/instance-icons/backpack.png | Bin 0 -> 146729 bytes
.../src/assets/instance-icons/beacon.png | Bin 0 -> 127369 bytes
.../src/assets/instance-icons/blue-shark.png | Bin 0 -> 104759 bytes
.../src/assets/instance-icons/bookshelf.png | Bin 0 -> 141090 bytes
.../src/assets/instance-icons/brown-bear.png | Bin 0 -> 107640 bytes
.../src/assets/instance-icons/cake.png | Bin 0 -> 69505 bytes
.../src/assets/instance-icons/campfire.png | Bin 0 -> 102418 bytes
.../src/assets/instance-icons/chest.png | Bin 0 -> 110814 bytes
.../src/assets/instance-icons/cogwheel.png | Bin 0 -> 121571 bytes
.../assets/instance-icons/command-block.png | Bin 0 -> 165172 bytes
.../src/assets/instance-icons/cooking-pot.png | Bin 0 -> 93026 bytes
.../src/assets/instance-icons/couch.png | Bin 0 -> 130602 bytes
.../assets/instance-icons/crafting-table.png | Bin 0 -> 142562 bytes
.../src/assets/instance-icons/creeper.png | Bin 0 -> 125441 bytes
.../instance-icons/enchanting-table.png | Bin 0 -> 140560 bytes
.../src/assets/instance-icons/ender-chest.png | Bin 0 -> 115480 bytes
.../assets/instance-icons/ender-dragon.png | Bin 0 -> 98395 bytes
.../src/assets/instance-icons/engine.png | Bin 0 -> 164545 bytes
.../src/assets/instance-icons/furnace.png | Bin 0 -> 135316 bytes
.../src/assets/instance-icons/gizmo.png | Bin 0 -> 85294 bytes
.../src/assets/instance-icons/globe.png | Bin 0 -> 131456 bytes
.../src/assets/instance-icons/grass-block.png | Bin 0 -> 82667 bytes
.../src/assets/instance-icons/lantern.png | Bin 0 -> 76031 bytes
.../src/assets/instance-icons/moobloom.png | Bin 0 -> 98198 bytes
.../src/assets/instance-icons/mr-pack.png | Bin 0 -> 124140 bytes
.../src/assets/instance-icons/orb.png | Bin 0 -> 87751 bytes
.../instance-icons/oxygen-distributor.png | Bin 0 -> 130807 bytes
.../src/assets/instance-icons/pancakes.png | Bin 0 -> 169973 bytes
.../src/assets/instance-icons/pickaxe.png | Bin 0 -> 73662 bytes
.../src/assets/instance-icons/poke-ball.png | Bin 0 -> 89928 bytes
.../assets/instance-icons/redstone-block.png | Bin 0 -> 125730 bytes
.../assets/instance-icons/sculk-sensor.png | Bin 0 -> 101677 bytes
.../src/assets/instance-icons/skeleton.png | Bin 0 -> 80690 bytes
.../src/assets/instance-icons/skillet.png | Bin 0 -> 81143 bytes
.../src/assets/instance-icons/slime-block.png | Bin 0 -> 113242 bytes
.../assets/instance-icons/space-helmet.png | Bin 0 -> 106524 bytes
.../assets/instance-icons/sticky-piston.png | Bin 0 -> 146434 bytes
.../src/assets/instance-icons/sword.png | Bin 0 -> 90229 bytes
.../src/assets/instance-icons/terminal.png | Bin 0 -> 102174 bytes
.../src/assets/instance-icons/tiny-potato.png | Bin 0 -> 48313 bytes
.../src/assets/instance-icons/tire.png | Bin 0 -> 130221 bytes
.../src/assets/instance-icons/tnt.png | Bin 0 -> 147019 bytes
.../assets/instance-icons/wrench-rinth.png | Bin 0 -> 72130 bytes
.../src/assets/instance-icons/wrench.png | Bin 0 -> 112809 bytes
.../src/assets/instance-icons/zombie.png | Bin 0 -> 90529 bytes
.../assets/welcome/modrinth-social-icon.png | Bin 0 -> 233731 bytes
.../src/components/GridDisplay.vue | 360 -----
.../src/components/RowDisplay.vue | 371 -----
.../src/components/ui/AccountsCard.vue | 1 +
.../src/components/ui/AppActionBar.vue | 28 +-
.../src/components/ui/ContextMenu.vue | 40 +-
.../src/components/ui/Instance.vue | 65 +-
.../src/components/ui/InstanceIndicator.vue | 23 +-
.../components/ui/QuickInstanceSwitcher.vue | 5 +-
.../src/components/ui/WelcomeScreen.vue | 154 +++
.../install_flow/AddServerToInstanceModal.vue | 48 +-
.../icon-editor-modal/editor-catalog.ts | 466 +++++++
.../icon-editor-modal/index.vue | 537 +++++++
.../ui/library/LibrarySelectionActionBar.vue | 206 +++
.../ui/library/group-instances-modal.vue | 150 ++
.../src/components/ui/library/index.vue | 450 ++++++
.../ui/library/instance-group/drag-gather.vue | 99 ++
.../library/instance-group/drag-preview.vue | 64 +
.../instance-group/group-action-buttons.vue | 95 ++
.../ui/library/instance-group/index.vue | 547 ++++++++
.../instance-group/instance-card-view.vue | 67 +
.../library/instance-group/instance-card.vue | 379 +++++
.../instance-group/instance-group-dnd.vue | 236 ++++
.../use-instance-drag-gather.ts | 130 ++
.../library/library-toolbar/filter-menu.vue | 70 +
.../ui/library/library-toolbar/index.vue | 56 +
.../library-toolbar/new-group-modal.vue | 177 +++
.../ui/library/library-toolbar/sort-menu.vue | 86 ++
.../src/components/ui/library/use-library.ts | 1230 +++++++++++++++++
.../ui/modal/ConfirmDeleteInstanceModal.vue | 123 +-
.../ui/modal/InstanceModalTitlePrefix.vue | 8 +-
.../apply-new-icons-modal.vue | 233 ++++
.../assets/01.png | Bin 0 -> 5986 bytes
.../assets/02.png | Bin 0 -> 5961 bytes
.../assets/03.png | Bin 0 -> 5187 bytes
.../assets/04.png | Bin 0 -> 7803 bytes
.../assets/05.png | Bin 0 -> 5640 bytes
.../assets/06.png | Bin 0 -> 5925 bytes
.../assets/07.png | Bin 0 -> 6469 bytes
.../assets/08.png | Bin 0 -> 5955 bytes
.../assets/09.png | Bin 0 -> 4223 bytes
.../ui/new-icon-editor-notification/index.vue | 144 ++
.../show-notification.ts | 12 +
.../ui/onboarding-checklist/index.vue | 130 ++
.../ui/settings/display/BehaviorSettings.vue | 43 +-
.../use-shared-instance-invite-handler.ts | 27 +-
.../src/components/ui/skin/EditSkinModal.vue | 14 +-
.../src/components/ui/world/InstanceItem.vue | 147 +-
.../components/ui/world/RecentWorldsList.vue | 71 +-
.../src/components/ui/world/WorldItem.vue | 128 +-
.../src/generated/app-events/AppEvent.ts | 4 +-
.../InstanceGroupsChangedPayload.ts | 3 +
.../app-events/OnboardingChecklist.ts | 3 +
.../generated/app-events/postcard/index.d.ts | 8 +-
.../generated/app-events/postcard/index.js | 45 +-
apps/app-frontend/src/helpers/analytics.ts | 2 +-
apps/app-frontend/src/helpers/install.ts | 3 +-
.../src/helpers/instance-groups.ts | 40 +
apps/app-frontend/src/helpers/instance.ts | 49 +
.../src/helpers/onboarding-checklist.ts | 9 +
apps/app-frontend/src/helpers/settings.ts | 2 -
apps/app-frontend/src/helpers/types.d.ts | 21 +-
.../app-frontend/src/locales/ar-SA/index.json | 43 +-
.../app-frontend/src/locales/cs-CZ/index.json | 43 +-
.../app-frontend/src/locales/da-DK/index.json | 31 +-
.../app-frontend/src/locales/de-CH/index.json | 33 -
.../app-frontend/src/locales/de-DE/index.json | 33 -
.../app-frontend/src/locales/en-US/index.json | 763 +++++++++-
.../src/locales/es-419/index.json | 33 -
.../app-frontend/src/locales/es-ES/index.json | 43 +-
.../app-frontend/src/locales/fi-FI/index.json | 43 +-
.../src/locales/fil-PH/index.json | 43 +-
.../app-frontend/src/locales/fr-FR/index.json | 30 -
.../app-frontend/src/locales/he-IL/index.json | 15 -
.../app-frontend/src/locales/hu-HU/index.json | 33 -
.../app-frontend/src/locales/id-ID/index.json | 43 +-
.../app-frontend/src/locales/it-IT/index.json | 33 -
.../app-frontend/src/locales/ja-JP/index.json | 33 -
.../app-frontend/src/locales/ko-KR/index.json | 33 -
.../app-frontend/src/locales/ms-MY/index.json | 52 +-
.../app-frontend/src/locales/nl-NL/index.json | 33 -
.../app-frontend/src/locales/no-NO/index.json | 22 +-
.../app-frontend/src/locales/pl-PL/index.json | 36 +-
.../app-frontend/src/locales/pt-BR/index.json | 33 -
.../app-frontend/src/locales/pt-PT/index.json | 34 +-
.../app-frontend/src/locales/ro-RO/index.json | 12 -
.../app-frontend/src/locales/ru-RU/index.json | 33 -
.../app-frontend/src/locales/sr-CS/index.json | 30 -
.../app-frontend/src/locales/sv-SE/index.json | 40 +-
.../app-frontend/src/locales/th-TH/index.json | 43 +-
.../app-frontend/src/locales/tr-TR/index.json | 33 -
.../app-frontend/src/locales/uk-UA/index.json | 33 -
.../app-frontend/src/locales/vi-VN/index.json | 43 +-
.../app-frontend/src/locales/zh-CN/index.json | 33 -
.../app-frontend/src/locales/zh-TW/index.json | 33 -
apps/app-frontend/src/pages/Browse.vue | 46 +-
apps/app-frontend/src/pages/Index.vue | 166 ++-
apps/app-frontend/src/pages/Skins.vue | 102 +-
.../settings-modal/general-settings.vue | 161 +--
.../components/settings-modal/index.vue | 5 +-
.../src/pages/instance/content/index.vue | 4 +-
.../src/pages/instance/layout.vue | 112 +-
.../app-frontend/src/pages/library/Custom.vue | 17 -
.../src/pages/library/Downloaded.vue | 17 -
apps/app-frontend/src/pages/library/Index.vue | 95 --
.../src/pages/library/Modpacks.vue | 47 -
.../src/pages/library/Overview.vue | 13 -
.../src/pages/library/Servers.vue | 47 -
apps/app-frontend/src/pages/library/index.js | 8 -
apps/app-frontend/src/pages/project/Index.vue | 29 +-
.../src/providers/content-install.ts | 44 +-
.../src/providers/onboarding-checklist.ts | 57 +
.../src/providers/server-install.ts | 2 +
apps/app-frontend/src/providers/setup.ts | 10 +-
.../src/providers/setup/app-event-codec.ts | 4 +
.../src/providers/setup/creation-modal.ts | 78 +-
.../providers/setup/server-install-content.ts | 4 +-
apps/app-frontend/src/routes.js | 33 -
apps/app/build.rs | 17 +
apps/app/capabilities/plugins.json | 1 +
apps/app/src/api/auth.rs | 3 +
apps/app/src/api/install.rs | 2 +
apps/app/src/api/instance.rs | 104 +-
apps/app/src/api/mod.rs | 1 +
apps/app/src/api/onboarding_checklist.rs | 14 +
apps/app/src/main.rs | 2 +
.../app-personalization/groups-demo.mp4 | Bin 0 -> 7152064 bytes
.../article/app-personalization/hosting.webp | Bin 0 -> 716946 bytes
.../app-personalization/icon-editor.webp | Bin 0 -> 586150 bytes
.../instance-creation.webp | Bin 0 -> 513326 bytes
.../app-personalization/play-page.webp | Bin 0 -> 721774 bytes
.../article/app-personalization/sign-in.webp | Bin 0 -> 473388 bytes
.../app-personalization/thumbnail.webp | Bin 0 -> 247588 bytes
.../article/app-personalization/welcome.webp | Bin 0 -> 165752 bytes
.../src/public/news/feed/articles.json | 7 +
apps/frontend/src/public/news/feed/rss.xml | 10 +-
.../src/routes/internal/analytics_event.rs | 6 +-
...706fce514b070987a4ff2047afa18ee60d237.json | 12 +
...c099d57f217b4c1f4a63761b5e07129eb1f84.json | 12 -
...6416ad15182131cfb6de3f2dab153c74a553c.json | 20 -
...506fbbabc4465357aa6476b8e8fa0af84158.json} | 122 +-
...c422c3ab7203409083fd3c9c968b00b46918f.json | 12 -
...5f60241f1526302015b8098ec8fd68c9743d3.json | 12 +
...432a5f4a6588f644b2fded4fdfc0b0d9d407.json} | 122 +-
...ebe2080733c323ec58f86969d9d1fdb4ba076.json | 12 +
...b09b1fe8be840b4a14ad2636d7bb558cc62a1.json | 12 +
...f3472d6e2f5349dabef91a203d8a4d938e4aa.json | 12 +
...b161dba6f0918353ce5065e3b6ae8d98b474.json} | 122 +-
...c12be71df20b8cf520019413f6ea751cd594.json} | 48 +-
...ec66677b42cdd09b8ae87cee0ef89d3875681.json | 20 +
...d06e8ca910f05a73f2b31fe80eef9033873d7.json | 12 -
...45eeeca9734a94f958f43a1605a38235b5fe0.json | 20 +
...8288cd69f7defc9f9990b8c18ecf2d4f76ef3.json | 12 +
...c4c7b4a5c56ddb12b7fbe2d8d63936853312e.json | 38 +
...c4ab5534a7f105cf386b53ac44c5527d2e2e7.json | 20 +
...b59c6d9d83486ccadae7351b1516d3387834f.json | 12 +
...deec7e741eca9490811ebad6594abe8a6126d.json | 12 +
...0ea2940ba9ada7b39f3c2fa973a36ee4cba2a.json | 12 -
...b087901087b5580012e68f96c6836b5a146ca.json | 12 +
...0260715120000_remove-onboarded-setting.sql | 1 +
.../20260715165608_onboarding-checklist.sql | 30 +
...60724120000_instance-group-definitions.sql | 65 +
.../20260805120000_instance-icon-editor.sql | 19 +
packages/app-lib/src/api/instance.rs | 11 +-
packages/app-lib/src/api/instance/groups.rs | 338 +++++
packages/app-lib/src/api/instance/icon.rs | 381 ++++-
.../app-lib/src/api/instance/lifecycle.rs | 15 +-
packages/app-lib/src/api/minecraft_auth.rs | 13 +-
packages/app-lib/src/api/minecraft_skins.rs | 18 +-
packages/app-lib/src/api/mod.rs | 17 +-
packages/app-lib/src/api/mr_auth.rs | 9 +
.../app-lib/src/api/onboarding_checklist.rs | 35 +
packages/app-lib/src/event/emit.rs | 32 +-
packages/app-lib/src/event/mod.rs | 14 +
packages/app-lib/src/install/model.rs | 5 +-
packages/app-lib/src/install/recovery.rs | 2 +-
packages/app-lib/src/install/runner.rs | 26 +-
.../adapters/sqlite/instance_rows.rs | 344 ++++-
.../instances/commands/create_instance.rs | 15 +-
.../state/instances/commands/edit_instance.rs | 33 +-
.../state/instances/commands/get_instance.rs | 11 +-
.../src/state/instances/commands/mod.rs | 2 +-
.../src/state/instances/model/instance.rs | 19 +
.../app-lib/src/state/legacy_converter.rs | 42 +-
packages/app-lib/src/state/mod.rs | 3 +
.../app-lib/src/state/onboarding_checklist.rs | 106 ++
packages/app-lib/src/state/settings.rs | 47 +-
packages/assets/generated-icons.ts | 6 +
packages/assets/icons/layout-grid.svg | 18 +
packages/assets/icons/page-round.svg | 9 +
packages/assets/icons/square-plus.svg | 17 +
packages/blog/articles/app-personalization.md | 99 ++
.../compiled/app_personalization.content.ts | 2 +
packages/blog/compiled/app_personalization.ts | 12 +
packages/blog/compiled/index.ts | 2 +
.../app-personalization/groups-demo.mp4 | Bin 0 -> 7152064 bytes
.../public/app-personalization/hosting.webp | Bin 0 -> 716946 bytes
.../app-personalization/icon-editor.webp | Bin 0 -> 586150 bytes
.../instance-creation.webp | Bin 0 -> 513326 bytes
.../public/app-personalization/play-page.webp | Bin 0 -> 721774 bytes
.../public/app-personalization/sign-in.webp | Bin 0 -> 473388 bytes
.../public/app-personalization/thumbnail.webp | Bin 0 -> 247588 bytes
.../public/app-personalization/welcome.webp | Bin 0 -> 165752 bytes
.../servers/server-list-empty/boris.png | Bin 0 -> 23653 bytes
.../servers/server-list-empty/fetch.png | Bin 0 -> 27094 bytes
.../server-list-empty/geometrically.png | Bin 0 -> 13639 bytes
.../servers/server-list-empty/imb11.png | Bin 0 -> 27301 bytes
.../assets/servers/server-list-empty/josh.png | Bin 0 -> 38446 bytes
.../servers/server-list-empty/michael.png | Bin 0 -> 4936 bytes
.../server-list-empty/modrinth-smp.png | Bin 0 -> 23919 bytes
.../servers/server-list-empty/prospector.png | Bin 0 -> 10820 bytes
.../assets/servers/server-list-empty/saya.png | Bin 0 -> 28627 bytes
.../servers/server-list-empty/truman.png | Bin 0 -> 2860 bytes
packages/ui/src/assets/welcome/frog.png | Bin 0 -> 304 bytes
.../ui/src/assets/welcome/icon-texture.png | Bin 0 -> 959049 bytes
packages/ui/src/components/base/Accordion.vue | 3 -
packages/ui/src/components/base/Avatar.vue | 157 ++-
.../src/components/base/DropdownFilterBar.vue | 63 +-
.../components/base/InlineEditableText.vue | 248 ++++
.../ui/src/components/base/SmartClickable.vue | 2 +-
.../ui/src/components/base/StyledInput.vue | 16 +-
packages/ui/src/components/base/index.ts | 1 +
.../components/CustomSetupStage.vue | 139 +-
.../components/SetupTypeStage.vue | 251 +++-
.../creation-flow-context.ts | 161 ++-
.../flows/creation-flow-modal/index.vue | 21 +-
.../stages/custom-setup-stage.ts | 2 +-
.../stages/final-config-stage.ts | 2 +-
.../stages/import-instance-stage.ts | 2 +-
.../flows/creation-flow-modal/stages/index.ts | 2 -
.../stages/modpack-stage.ts | 22 -
.../stages/setup-type-stage.ts | 2 +-
.../components/nav/PopupNotificationPanel.vue | 113 +-
.../notifications/NotificationToast.vue | 166 ++-
.../components/servers/ServerSetupModal.vue | 2 +-
.../ui/src/components/servers/flows/index.ts | 2 +-
.../servers/server-list-empty/Pointer.png | Bin 0 -> 551 bytes
.../server-list-empty/ServerListEmpty.vue | 311 ++---
.../ServerListEmptyPreview.vue | 245 ++++
.../grid-images/aircraft.png | Bin 21840 -> 0 bytes
.../server-list-empty/grid-images/alex's.png | Bin 19570 -> 0 bytes
.../grid-images/artifacts.png | Bin 704 -> 0 bytes
.../server-list-empty/grid-images/biomes.png | Bin 1167 -> 0 bytes
.../server-list-empty/grid-images/catac.png | Bin 12710 -> 0 bytes
.../server-list-empty/grid-images/cobble.png | Bin 17701 -> 0 bytes
.../grid-images/comforts.png | Bin 990 -> 0 bytes
.../server-list-empty/grid-images/create.png | Bin 22270 -> 0 bytes
.../server-list-empty/grid-images/create1.png | Bin 20019 -> 0 bytes
.../server-list-empty/grid-images/create2.png | Bin 20355 -> 0 bytes
.../server-list-empty/grid-images/create3.png | Bin 21715 -> 0 bytes
.../server-list-empty/grid-images/creeper.png | Bin 36105 -> 0 bytes
.../server-list-empty/grid-images/friends.png | Bin 18513 -> 0 bytes
.../server-list-empty/grid-images/geo.png | Bin 18242 -> 0 bytes
.../grid-images/naturalist.png | Bin 22716 -> 0 bytes
.../server-list-empty/grid-images/seasons.png | Bin 16140 -> 0 bytes
.../grid-images/travellers.png | Bin 20052 -> 0 bytes
.../server-list-empty/grid-images/tree.png | Bin 23739 -> 0 bytes
.../server-list-empty/grid-images/yum1.png | Bin 14167 -> 0 bytes
.../server-list-empty/grid-images/yum2.png | Bin 15751 -> 0 bytes
.../server-list-empty/grid-images/yum3.png | Bin 13945 -> 0 bytes
.../server-list-empty/grid-images/yung.png | Bin 15455 -> 0 bytes
.../ui/src/components/skin/SkinButton.vue | 61 +-
.../components/modals/ContentInstallModal.vue | 96 +-
.../hosting/manage/[id]/onboarding.vue | 2 +-
.../layouts/wrapped/hosting/manage/index.vue | 18 +-
packages/ui/src/locales/cs-CZ/index.json | 39 -
packages/ui/src/locales/da-DK/index.json | 24 -
packages/ui/src/locales/de-CH/index.json | 42 -
packages/ui/src/locales/de-DE/index.json | 42 -
packages/ui/src/locales/en-US/index.json | 147 +-
packages/ui/src/locales/es-419/index.json | 42 -
packages/ui/src/locales/es-ES/index.json | 42 -
packages/ui/src/locales/fr-FR/index.json | 42 -
packages/ui/src/locales/hu-HU/index.json | 18 -
packages/ui/src/locales/id-ID/index.json | 6 -
packages/ui/src/locales/it-IT/index.json | 42 -
packages/ui/src/locales/ja-JP/index.json | 42 -
packages/ui/src/locales/ko-KR/index.json | 42 -
packages/ui/src/locales/ms-MY/index.json | 39 -
packages/ui/src/locales/nl-NL/index.json | 42 -
packages/ui/src/locales/no-NO/index.json | 15 -
packages/ui/src/locales/pl-PL/index.json | 42 -
packages/ui/src/locales/pt-BR/index.json | 42 -
packages/ui/src/locales/ro-RO/index.json | 6 -
packages/ui/src/locales/ru-RU/index.json | 42 -
packages/ui/src/locales/sr-CS/index.json | 42 -
packages/ui/src/locales/sv-SE/index.json | 33 -
packages/ui/src/locales/th-TH/index.json | 6 -
packages/ui/src/locales/tr-TR/index.json | 42 -
packages/ui/src/locales/uk-UA/index.json | 18 -
packages/ui/src/locales/vi-VN/index.json | 42 -
packages/ui/src/locales/zh-CN/index.json | 42 -
packages/ui/src/locales/zh-TW/index.json | 42 -
.../ui/src/providers/popup-notifications.ts | 138 +-
.../base/InlineEditableText.stories.ts | 95 ++
.../nav/PopupNotificationPanel.stories.ts | 10 +
.../servers/CreationFlowModal.stories.ts | 53 +-
.../servers/ServerListEmpty.stories.ts | 27 +-
pnpm-lock.yaml | 186 ++-
347 files changed, 12456 insertions(+), 4505 deletions(-)
create mode 100644 apps/app-frontend/src/assets/icons/instance-file.svg
create mode 100755 apps/app-frontend/src/assets/instance-icons/backpack.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/beacon.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/blue-shark.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/bookshelf.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/brown-bear.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/cake.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/campfire.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/chest.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/cogwheel.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/command-block.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/cooking-pot.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/couch.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/crafting-table.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/creeper.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/enchanting-table.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/ender-chest.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/ender-dragon.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/engine.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/furnace.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/gizmo.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/globe.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/grass-block.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/lantern.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/moobloom.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/mr-pack.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/orb.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/oxygen-distributor.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/pancakes.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/pickaxe.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/poke-ball.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/redstone-block.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/sculk-sensor.png
create mode 100644 apps/app-frontend/src/assets/instance-icons/skeleton.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/skillet.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/slime-block.png
create mode 100644 apps/app-frontend/src/assets/instance-icons/space-helmet.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/sticky-piston.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/sword.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/terminal.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/tiny-potato.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/tire.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/tnt.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/wrench-rinth.png
create mode 100755 apps/app-frontend/src/assets/instance-icons/wrench.png
create mode 100644 apps/app-frontend/src/assets/instance-icons/zombie.png
create mode 100644 apps/app-frontend/src/assets/welcome/modrinth-social-icon.png
delete mode 100644 apps/app-frontend/src/components/GridDisplay.vue
delete mode 100644 apps/app-frontend/src/components/RowDisplay.vue
create mode 100644 apps/app-frontend/src/components/ui/WelcomeScreen.vue
create mode 100644 apps/app-frontend/src/components/ui/instance_settings/icon-editor-modal/editor-catalog.ts
create mode 100644 apps/app-frontend/src/components/ui/instance_settings/icon-editor-modal/index.vue
create mode 100644 apps/app-frontend/src/components/ui/library/LibrarySelectionActionBar.vue
create mode 100644 apps/app-frontend/src/components/ui/library/group-instances-modal.vue
create mode 100644 apps/app-frontend/src/components/ui/library/index.vue
create mode 100644 apps/app-frontend/src/components/ui/library/instance-group/drag-gather.vue
create mode 100644 apps/app-frontend/src/components/ui/library/instance-group/drag-preview.vue
create mode 100644 apps/app-frontend/src/components/ui/library/instance-group/group-action-buttons.vue
create mode 100644 apps/app-frontend/src/components/ui/library/instance-group/index.vue
create mode 100644 apps/app-frontend/src/components/ui/library/instance-group/instance-card-view.vue
create mode 100644 apps/app-frontend/src/components/ui/library/instance-group/instance-card.vue
create mode 100644 apps/app-frontend/src/components/ui/library/instance-group/instance-group-dnd.vue
create mode 100644 apps/app-frontend/src/components/ui/library/instance-group/use-instance-drag-gather.ts
create mode 100644 apps/app-frontend/src/components/ui/library/library-toolbar/filter-menu.vue
create mode 100644 apps/app-frontend/src/components/ui/library/library-toolbar/index.vue
create mode 100644 apps/app-frontend/src/components/ui/library/library-toolbar/new-group-modal.vue
create mode 100644 apps/app-frontend/src/components/ui/library/library-toolbar/sort-menu.vue
create mode 100644 apps/app-frontend/src/components/ui/library/use-library.ts
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/apply-new-icons-modal.vue
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/assets/01.png
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/assets/02.png
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/assets/03.png
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/assets/04.png
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/assets/05.png
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/assets/06.png
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/assets/07.png
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/assets/08.png
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/assets/09.png
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/index.vue
create mode 100644 apps/app-frontend/src/components/ui/new-icon-editor-notification/show-notification.ts
create mode 100644 apps/app-frontend/src/components/ui/onboarding-checklist/index.vue
create mode 100644 apps/app-frontend/src/generated/app-events/InstanceGroupsChangedPayload.ts
create mode 100644 apps/app-frontend/src/generated/app-events/OnboardingChecklist.ts
create mode 100644 apps/app-frontend/src/helpers/instance-groups.ts
create mode 100644 apps/app-frontend/src/helpers/onboarding-checklist.ts
delete mode 100644 apps/app-frontend/src/pages/library/Custom.vue
delete mode 100644 apps/app-frontend/src/pages/library/Downloaded.vue
delete mode 100644 apps/app-frontend/src/pages/library/Index.vue
delete mode 100644 apps/app-frontend/src/pages/library/Modpacks.vue
delete mode 100644 apps/app-frontend/src/pages/library/Overview.vue
delete mode 100644 apps/app-frontend/src/pages/library/Servers.vue
delete mode 100644 apps/app-frontend/src/pages/library/index.js
create mode 100644 apps/app-frontend/src/providers/onboarding-checklist.ts
create mode 100644 apps/app/src/api/onboarding_checklist.rs
create mode 100644 apps/frontend/src/public/news/article/app-personalization/groups-demo.mp4
create mode 100644 apps/frontend/src/public/news/article/app-personalization/hosting.webp
create mode 100644 apps/frontend/src/public/news/article/app-personalization/icon-editor.webp
create mode 100644 apps/frontend/src/public/news/article/app-personalization/instance-creation.webp
create mode 100644 apps/frontend/src/public/news/article/app-personalization/play-page.webp
create mode 100644 apps/frontend/src/public/news/article/app-personalization/sign-in.webp
create mode 100644 apps/frontend/src/public/news/article/app-personalization/thumbnail.webp
create mode 100644 apps/frontend/src/public/news/article/app-personalization/welcome.webp
create mode 100644 packages/app-lib/.sqlx/query-04b62cdfd635acb3d700211a104706fce514b070987a4ff2047afa18ee60d237.json
delete mode 100644 packages/app-lib/.sqlx/query-073e4c6fbf434f94c8015076b50c099d57f217b4c1f4a63761b5e07129eb1f84.json
delete mode 100644 packages/app-lib/.sqlx/query-0812e019f53d81d527ea15cbf7a6416ad15182131cfb6de3f2dab153c74a553c.json
rename packages/app-lib/.sqlx/{query-88a0520cb21aaea25bf12a5ad07e7f0614e912494f850e77dfc502b1afe7c42a.json => query-11dd50ff2700bf67a0da7cf67e12506fbbabc4465357aa6476b8e8fa0af84158.json} (57%)
delete mode 100644 packages/app-lib/.sqlx/query-175067f04e775f5469146f3cb77c422c3ab7203409083fd3c9c968b00b46918f.json
create mode 100644 packages/app-lib/.sqlx/query-1a1d2e6b837d5f2b43069f4de9f5f60241f1526302015b8098ec8fd68c9743d3.json
rename packages/app-lib/.sqlx/{query-aaf6e6a3de2dd9cb1c9db5dd9de2a6590b89c4f72449fdd34a7f140e2a11bf04.json => query-2399d3074def96c3dbc29eccca98432a5f4a6588f644b2fded4fdfc0b0d9d407.json} (57%)
create mode 100644 packages/app-lib/.sqlx/query-29d7a7578c6bf4a446eff7f68d1ebe2080733c323ec58f86969d9d1fdb4ba076.json
create mode 100644 packages/app-lib/.sqlx/query-4b8b302590a9ab956823789dfe9b09b1fe8be840b4a14ad2636d7bb558cc62a1.json
create mode 100644 packages/app-lib/.sqlx/query-5b33d55c05ca5157e50e43ca611f3472d6e2f5349dabef91a203d8a4d938e4aa.json
rename packages/app-lib/.sqlx/{query-0a708a6410e4d7d4cbdb07fa6ea32383be454526177686a0685a988af747db0f.json => query-6e0e46154aa79ddf77dbbd94528cb161dba6f0918353ce5065e3b6ae8d98b474.json} (57%)
rename packages/app-lib/.sqlx/{query-8e62fba05f331f91822ec204695ecb40567541c547181a4ef847318845cf3110.json => query-6f8b76b839db48539a70664af549c12be71df20b8cf520019413f6ea751cd594.json} (84%)
create mode 100644 packages/app-lib/.sqlx/query-73a5b7a4b61a75705f6ed3ea370ec66677b42cdd09b8ae87cee0ef89d3875681.json
delete mode 100644 packages/app-lib/.sqlx/query-7790039c6bfeba24c9a0f515b12d06e8ca910f05a73f2b31fe80eef9033873d7.json
create mode 100644 packages/app-lib/.sqlx/query-7b17b6dc7e42a064a0f6e501d8b45eeeca9734a94f958f43a1605a38235b5fe0.json
create mode 100644 packages/app-lib/.sqlx/query-85ae4979fb862c60859e2a6694d8288cd69f7defc9f9990b8c18ecf2d4f76ef3.json
create mode 100644 packages/app-lib/.sqlx/query-baa15329484896237f57ee6b585c4c7b4a5c56ddb12b7fbe2d8d63936853312e.json
create mode 100644 packages/app-lib/.sqlx/query-c264c05f91394756ef724b6cbb0c4ab5534a7f105cf386b53ac44c5527d2e2e7.json
create mode 100644 packages/app-lib/.sqlx/query-c715a78bfe15b58f7a14c9eaf3bb59c6d9d83486ccadae7351b1516d3387834f.json
create mode 100644 packages/app-lib/.sqlx/query-dfdc99cb5ec60bb08c566920628deec7e741eca9490811ebad6594abe8a6126d.json
delete mode 100644 packages/app-lib/.sqlx/query-e26d2ce1fdaaef4ef4648b57faf0ea2940ba9ada7b39f3c2fa973a36ee4cba2a.json
create mode 100644 packages/app-lib/.sqlx/query-fa1954f9c9c998fe4c66cbc82bab087901087b5580012e68f96c6836b5a146ca.json
create mode 100644 packages/app-lib/migrations/20260715120000_remove-onboarded-setting.sql
create mode 100644 packages/app-lib/migrations/20260715165608_onboarding-checklist.sql
create mode 100644 packages/app-lib/migrations/20260724120000_instance-group-definitions.sql
create mode 100644 packages/app-lib/migrations/20260805120000_instance-icon-editor.sql
create mode 100644 packages/app-lib/src/api/instance/groups.rs
create mode 100644 packages/app-lib/src/api/onboarding_checklist.rs
create mode 100644 packages/app-lib/src/state/onboarding_checklist.rs
create mode 100644 packages/assets/icons/layout-grid.svg
create mode 100644 packages/assets/icons/page-round.svg
create mode 100644 packages/assets/icons/square-plus.svg
create mode 100644 packages/blog/articles/app-personalization.md
create mode 100644 packages/blog/compiled/app_personalization.content.ts
create mode 100644 packages/blog/compiled/app_personalization.ts
create mode 100644 packages/blog/public/app-personalization/groups-demo.mp4
create mode 100644 packages/blog/public/app-personalization/hosting.webp
create mode 100644 packages/blog/public/app-personalization/icon-editor.webp
create mode 100644 packages/blog/public/app-personalization/instance-creation.webp
create mode 100644 packages/blog/public/app-personalization/play-page.webp
create mode 100644 packages/blog/public/app-personalization/sign-in.webp
create mode 100644 packages/blog/public/app-personalization/thumbnail.webp
create mode 100644 packages/blog/public/app-personalization/welcome.webp
create mode 100644 packages/ui/src/assets/servers/server-list-empty/boris.png
create mode 100644 packages/ui/src/assets/servers/server-list-empty/fetch.png
create mode 100644 packages/ui/src/assets/servers/server-list-empty/geometrically.png
create mode 100644 packages/ui/src/assets/servers/server-list-empty/imb11.png
create mode 100644 packages/ui/src/assets/servers/server-list-empty/josh.png
create mode 100644 packages/ui/src/assets/servers/server-list-empty/michael.png
create mode 100644 packages/ui/src/assets/servers/server-list-empty/modrinth-smp.png
create mode 100644 packages/ui/src/assets/servers/server-list-empty/prospector.png
create mode 100644 packages/ui/src/assets/servers/server-list-empty/saya.png
create mode 100644 packages/ui/src/assets/servers/server-list-empty/truman.png
create mode 100644 packages/ui/src/assets/welcome/frog.png
create mode 100644 packages/ui/src/assets/welcome/icon-texture.png
create mode 100644 packages/ui/src/components/base/InlineEditableText.vue
delete mode 100644 packages/ui/src/components/flows/creation-flow-modal/stages/modpack-stage.ts
create mode 100644 packages/ui/src/components/servers/server-list-empty/Pointer.png
create mode 100644 packages/ui/src/components/servers/server-list-empty/ServerListEmptyPreview.vue
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/aircraft.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/alex's.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/artifacts.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/biomes.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/catac.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/cobble.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/comforts.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/create.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/create1.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/create2.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/create3.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/creeper.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/friends.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/geo.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/naturalist.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/seasons.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/travellers.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/tree.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/yum1.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/yum2.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/yum3.png
delete mode 100644 packages/ui/src/components/servers/server-list-empty/grid-images/yung.png
create mode 100644 packages/ui/src/stories/base/InlineEditableText.stories.ts
diff --git a/apps/app-frontend/package.json b/apps/app-frontend/package.json
index 18ff367db0..5a88bd2d92 100644
--- a/apps/app-frontend/package.json
+++ b/apps/app-frontend/package.json
@@ -14,6 +14,7 @@
"test": "vue-tsc --noEmit"
},
"dependencies": {
+ "@dnd-kit/vue": "^0.5.0",
"@modrinth/api-client": "workspace:^",
"@modrinth/assets": "workspace:*",
"@modrinth/ui": "workspace:*",
diff --git a/apps/app-frontend/src/App.vue b/apps/app-frontend/src/App.vue
index 3db155776b..eeb37273f6 100644
--- a/apps/app-frontend/src/App.vue
+++ b/apps/app-frontend/src/App.vue
@@ -13,11 +13,10 @@ import {
ChevronLeftIcon,
ChevronRightIcon,
CompassIcon,
- HomeIcon,
- LibraryIcon,
LogInIcon,
LogOutIcon,
NewspaperIcon,
+ PlayIcon,
PlusIcon,
RefreshCwIcon,
RightArrowIcon,
@@ -57,7 +56,7 @@ import {
import { renderString } from '@modrinth/utils'
import { useQuery, useQueryClient } from '@tanstack/vue-query'
import { getVersion } from '@tauri-apps/api/app'
-import { invoke } from '@tauri-apps/api/core'
+import { convertFileSrc, invoke } from '@tauri-apps/api/core'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { fetch as tauriFetch } from '@tauri-apps/plugin-http'
import { openUrl } from '@tauri-apps/plugin-opener'
@@ -74,6 +73,7 @@ import FriendsList from '@/components/ui/friends/FriendsList.vue'
import HostingUpdateRequired from '@/components/ui/HostingUpdateRequired.vue'
import AddServerToInstanceModal from '@/components/ui/install_flow/AddServerToInstanceModal.vue'
import UnknownPackWarningModal from '@/components/ui/install_flow/UnknownPackWarningModal.vue'
+import IconEditorModal from '@/components/ui/instance_settings/icon-editor-modal/index.vue'
import MinecraftAuthErrorModal from '@/components/ui/minecraft-auth-error-modal/MinecraftAuthErrorModal.vue'
import MinecraftRequiredModal from '@/components/ui/minecraft-required-modal/MinecraftRequiredModal.vue'
import AppSettingsModal from '@/components/ui/modal/AppSettingsModal.vue'
@@ -82,6 +82,9 @@ import ModpackAlreadyInstalledModal from '@/components/ui/modal/ModpackAlreadyIn
import ModrinthAccountRequiredModal from '@/components/ui/modal/ModrinthAccountRequiredModal.vue'
import UpdateToPlayModal from '@/components/ui/modal/UpdateToPlayModal.vue'
import NavButton from '@/components/ui/NavButton.vue'
+import NewIconEditorNotification from '@/components/ui/new-icon-editor-notification/index.vue'
+import { shouldShowNewIconEditorNotification } from '@/components/ui/new-icon-editor-notification/show-notification'
+import OnboardingChecklist from '@/components/ui/onboarding-checklist/index.vue'
import PrideFundraiserBanner from '@/components/ui/PrideFundraiserBanner.vue'
import PromotionWrapper from '@/components/ui/PromotionWrapper.vue'
import QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue'
@@ -248,7 +251,7 @@ useAppEvent(
'warning',
(event) =>
addNotification({
- title: 'Warning',
+ title: formatMessage(messages.warning),
text: event.message,
type: 'warning',
}),
@@ -332,19 +335,68 @@ provideModalBehavior({
onHide: () => release_ads_window_hold(),
})
+const creationIconEditorModal = ref(null)
+const creationGeneratedIcon = ref(null)
+const creationIconTarget = ref('creation-flow')
+
const {
installationModal,
unknownPackWarningModal,
fetchExistingInstanceNames,
handleCreate,
handleBrowseModpacks,
- searchModpacks,
- getProjectVersions,
+ searchProjects,
getLoaderManifest,
setModpackAlreadyInstalledModal,
handleModpackDuplicateCreateAnyway,
handleModpackDuplicateGoToInstance,
-} = setupProviders(tauriApiClient, notificationManager, popupNotificationManager)
+ onboardingChecklist,
+} = setupProviders(
+ tauriApiClient,
+ notificationManager,
+ popupNotificationManager,
+ appEvents,
+ (iconPath) =>
+ creationGeneratedIcon.value?.path === iconPath ? creationGeneratedIcon.value.config : null,
+)
+const { hasLoggedIntoMinecraft, hasLoggedIntoModrinth, showChecklist } = onboardingChecklist
+const showFriendsList = computed(() => !showChecklist.value || hasLoggedIntoModrinth.value)
+
+async function randomizeCreationIcon() {
+ const generated = await creationIconEditorModal.value?.randomizeAndSave()
+ if (!generated) return null
+
+ creationGeneratedIcon.value = { path: generated.iconPath, config: generated.config }
+ return {
+ path: generated.iconPath,
+ previewUrl: convertFileSrc(generated.iconPath),
+ }
+}
+
+function customizeCreationIcon() {
+ creationIconTarget.value = 'creation-flow'
+ creationIconEditorModal.value?.show()
+}
+
+function customizeContentInstallIcon() {
+ creationIconTarget.value = 'content-install'
+ creationIconEditorModal.value?.show()
+}
+
+function onCreationIconSaved(iconPath, config) {
+ creationGeneratedIcon.value = { path: iconPath, config }
+ if (creationIconTarget.value === 'content-install') {
+ modInstallModal.value?.setIcon(iconPath, convertFileSrc(iconPath))
+ return
+ }
+
+ const context = installationModal.value?.ctx
+ if (!context) return
+
+ context.instanceIcon.value = null
+ context.instanceIconUrl.value = convertFileSrc(iconPath)
+ context.instanceIconPath.value = iconPath
+}
const news = ref([])
const displayedServerInviteNotifications = new Set()
@@ -360,7 +412,6 @@ window.addEventListener('online', () => {
offline.value = false
})
-const showOnboarding = ref(false)
const nativeDecorations = ref(false)
const os = ref('')
@@ -425,6 +476,15 @@ const { formatMessage } = useVIntl()
const formatBytes = useFormatBytes()
const messages = defineMessages({
+ warning: { id: 'app.notification.warning', defaultMessage: 'Warning' },
+ moreOptions: { id: 'app.navigation.more-options', defaultMessage: 'More options' },
+ goBack: { id: 'app.navigation.go-back', defaultMessage: 'Go back' },
+ goForward: { id: 'app.navigation.go-forward', defaultMessage: 'Go forward' },
+ nextImage: { id: 'app.navigation.next-image', defaultMessage: 'Next image' },
+ updateDownloadMissingVersion: {
+ id: 'app.update.download-error.missing-version',
+ defaultMessage: 'Failed to download update: no version available',
+ },
updateInstalledToastTitle: {
id: 'app.update.complete-toast.title',
defaultMessage: 'Version {version} was successfully installed!',
@@ -467,10 +527,6 @@ const messages = defineMessages({
id: 'app.nav.home',
defaultMessage: 'Home',
},
- library: {
- id: 'app.nav.library',
- defaultMessage: 'Library',
- },
modrinthHosting: {
id: 'app.nav.modrinth-hosting',
defaultMessage: 'Modrinth Hosting',
@@ -530,6 +586,7 @@ function handleAdsConsentRequired(required) {
}
const notification = addPopupNotification({
+ contentType: 'standard',
title: formatMessage(messages.adsConsentTitle),
text: formatMessage(messages.adsConsentBody),
type: 'info',
@@ -562,6 +619,16 @@ function handleAdsConsentRequired(required) {
}
async function setupApp() {
+ await onboardingChecklist.initialize()
+
+ if (shouldShowNewIconEditorNotification(showChecklist.value)) {
+ addPopupNotification({
+ contentType: 'custom',
+ component: NewIconEditorNotification,
+ autoCloseMs: null,
+ })
+ }
+
const {
native_decorations,
theme,
@@ -570,8 +637,6 @@ async function setupApp() {
collapsed_navigation,
hide_nametag_skins_page,
advanced_rendering,
- onboarded,
- default_page,
toggle_sidebar,
developer_mode,
feature_flags,
@@ -583,16 +648,10 @@ async function setupApp() {
i18n.global.locale.value = locale
}
- if (default_page === 'Library') {
- await router.push('/library')
- }
-
os.value = await getOS()
const dev = await isDev()
isDevEnvironment.value = dev
const version = await getVersion()
- showOnboarding.value = !onboarded
-
nativeDecorations.value = native_decorations
if (os.value !== 'MacOS') await getCurrentWindow().setDecorations(native_decorations)
@@ -614,7 +673,7 @@ async function setupApp() {
if (telemetry) {
initAnalytics()
if (dev) debugAnalytics()
- trackEvent('Launched', { version, dev, onboarded })
+ trackEvent('Launched', { version, dev })
}
if (!dev) document.addEventListener('contextmenu', (event) => event.preventDefault())
@@ -818,6 +877,7 @@ const {
projectInfo: contentInstallProjectInfo,
handleInstallToInstance,
handleCreateAndInstall,
+ prepareNewInstance,
handleNavigate: handleContentInstallNavigate,
handleCancel: handleContentInstallCancel,
setContentInstallModal,
@@ -837,6 +897,35 @@ const {
handleIncompatibilityWarningCancel: handleContentInstallIncompatibilityWarningCancel,
} = contentInstall
+async function prepareCreationProjectInstall(projectId, projectType) {
+ if (projectType === 'modpack') {
+ await contentInstall.install(
+ projectId,
+ null,
+ null,
+ 'CreationModalProject',
+ undefined,
+ (instanceId) => void router.push(`/instance/${encodeURIComponent(instanceId)}`),
+ )
+ return null
+ }
+
+ await prepareNewInstance(projectId)
+ const info = contentInstallProjectInfo.value
+ if (!info) throw new Error(`Project information is unavailable: '${projectId}'`)
+
+ return {
+ projectId,
+ title: info.title,
+ iconUrl: info.iconUrl,
+ link: info.link,
+ owner: info.owner,
+ compatibleLoaders: [...contentInstallLoaders.value],
+ gameVersions: [...contentInstallGameVersions.value],
+ releaseGameVersions: new Set(contentInstallReleaseGameVersions.value),
+ }
+}
+
const serverInstall = createServerInstall({
router,
handleError,
@@ -1090,17 +1179,16 @@ async function handleLiveNotification(notification) {
if (generation !== liveNotificationGeneration) return
const popupNotification = addPopupNotification({
+ contentType: 'toast',
title: serverName,
+ type: 'server-invite',
+ actorName: invitedBy?.username ?? null,
+ actorAvatarUrl: invitedBy?.avatar_url ?? null,
+ entityName: serverName,
autoCloseMs: null,
- toast: {
- type: 'server-invite',
- actorName: invitedBy?.username ?? null,
- actorAvatarUrl: invitedBy?.avatar_url ?? null,
- entityName: serverName,
- onAccept: () => acceptServerInviteNotification(notification),
- onDecline: () => declineServerInviteNotification(notification),
- onOpenActor: () => openServerInviteInviterProfile(invitedBy?.username ?? null),
- },
+ onAccept: () => acceptServerInviteNotification(notification),
+ onDecline: () => declineServerInviteNotification(notification),
+ onOpenActor: () => openServerInviteInviterProfile(invitedBy?.username ?? null),
})
serverInvitePopupNotificationIds.add(popupNotification.id)
}
@@ -1277,6 +1365,7 @@ function showDelayedUpdatePopup() {
if (metered.value && !finishedDownloading.value) {
addPopupNotification({
+ contentType: 'standard',
title: formatMessage(updatePopupMessages.updateAvailable),
text: formatMessage(updatePopupMessages.meteredBody, { version: update.version }),
type: 'info',
@@ -1298,6 +1387,7 @@ function showDelayedUpdatePopup() {
})
} else if (finishedDownloading.value) {
addPopupNotification({
+ contentType: 'standard',
title: formatMessage(updatePopupMessages.downloadComplete),
text: formatMessage(updatePopupMessages.downloadedBody, {
version: update.version,
@@ -1396,6 +1486,7 @@ async function checkLinuxUpdates() {
const nextPopupTime = getNextAppUpdatePopupTime(latestVersion)
if (nextPopupTime !== null && Date.now() >= nextPopupTime) {
addPopupNotification({
+ contentType: 'standard',
title: formatMessage(updatePopupMessages.updateAvailable),
text: formatMessage(updatePopupMessages.linuxBody, { version: latestVersion }),
type: 'info',
@@ -1415,7 +1506,7 @@ async function downloadAvailableUpdate() {
async function downloadUpdate(versionToDownload) {
if (!versionToDownload) {
- handleError(`Failed to download update: no version available`)
+ handleError(formatMessage(messages.updateDownloadMissingVersion))
return
}
@@ -1579,18 +1670,34 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
type="instance"
show-snapshot-toggle
:fetch-existing-instance-names="fetchExistingInstanceNames"
- :search-modpacks="searchModpacks"
- :get-project-versions="getProjectVersions"
+ :search-projects="searchProjects"
+ :prepare-project-install="prepareCreationProjectInstall"
+ :create-project-install="handleCreateAndInstall"
:get-loader-manifest="getLoaderManifest"
+ :randomize-instance-icon="randomizeCreationIcon"
+ :customize-instance-icon="customizeCreationIcon"
@create="handleCreate"
@browse-modpacks="handleBrowseModpacks"
/>
+