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" /> +
- - + + - - - @@ -1823,9 +1919,17 @@ provideAppUpdateDownloadProgress(appUpdateDownload) :class="{ 'pb-12': !hasPlus }" data-overlayscrollbars-initialize > +