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>
This commit is contained in:
Truman Gao
2026-08-18 01:08:09 +00:00
committed by GitHub
co-authored by Prospector
parent d5556271f9
commit e79e0d024b
347 changed files with 12456 additions and 4505 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ interface ProjectProperties extends InstanceProperties {
}
type AnalyticsEventMap = {
Launched: { version: string; dev: boolean; onboarded: boolean }
Launched: { version: string; dev: boolean }
PageView: { path: string; fromPath: string; failed: unknown }
InstanceCreate: { source: string }
InstanceCreateStart: { source: string }
+2 -1
View File
@@ -10,7 +10,7 @@ import type { InstallProgressSecondary } from '@/generated/app-events/InstallPro
import type { SharedInstanceUnavailableReason } from '@/generated/app-events/SharedInstanceUnavailableReason'
import type { AppEvents } from '@/providers/app-events'
import type { InstanceLink, InstanceLoader } from './types'
import type { InstanceIconConfig, InstanceLink, InstanceLoader } from './types'
export type {
InstallErrorView,
@@ -56,6 +56,7 @@ export interface InstallCreateInstanceRequest {
loader: InstanceLoader
loaderVersion: string | null
iconPath: string | null
iconConfig?: InstanceIconConfig | null
link?: InstanceLink | null
}
@@ -0,0 +1,40 @@
import { invoke } from '@tauri-apps/api/core'
export const FAVORITES_GROUP_ID = 'group:favorites'
export const MAX_INSTANCE_GROUP_NAME_LENGTH = 256
export type InstanceGroupDefinition = {
id: string
name: string
}
export type InstanceGroupMembershipUpdate = {
instance_id: string
group_ids: string[]
}
export async function list_groups(): Promise<InstanceGroupDefinition[]> {
return await invoke('plugin:instance|instance_list_groups')
}
export async function create_group(name: string): Promise<InstanceGroupDefinition> {
return await invoke('plugin:instance|instance_create_group', { name })
}
export async function rename_group(id: string, newName: string): Promise<InstanceGroupDefinition> {
return await invoke('plugin:instance|instance_rename_group', { id, newName })
}
export async function delete_group(id: string): Promise<void> {
return await invoke('plugin:instance|instance_delete_group', { id })
}
export async function set_group_order(groupIds: string[]): Promise<void> {
return await invoke('plugin:instance|instance_set_group_order', { groupIds })
}
export async function set_group_memberships(
updates: InstanceGroupMembershipUpdate[],
): Promise<void> {
return await invoke('plugin:instance|instance_set_group_memberships', { updates })
}
+49
View File
@@ -13,10 +13,17 @@ import type {
ContentFile,
ContentFileProjectType,
GameInstance,
InstanceIconConfig,
InstanceLoader,
SharedInstanceAttachment,
} from './types'
export function getInstanceIconUrl(iconPath: string | null | undefined): string | null {
if (!iconPath) return null
if (iconPath.startsWith('http://') || iconPath.startsWith('https://')) return iconPath
return convertFileSrc(iconPath)
}
export async function remove(instanceId: string): Promise<void> {
return await invoke('plugin:instance|instance_remove', { instanceId })
}
@@ -389,6 +396,48 @@ export async function edit_icon(instanceId: string, iconPath: string | null): Pr
return await invoke('plugin:instance|instance_edit_icon', { instanceId, iconPath })
}
export async function edit_generated_icon(
instanceId: string,
config: InstanceIconConfig,
symbolBytes: number[],
): Promise<string> {
return await invoke('plugin:instance|instance_edit_generated_icon', {
instanceId,
config,
symbolBytes,
})
}
export async function edit_generated_icon_if_empty(
instanceId: string,
config: InstanceIconConfig,
symbolBytes: number[],
): Promise<boolean> {
const result = await invoke<string | null>('plugin:instance|instance_edit_generated_icon', {
instanceId,
config,
symbolBytes,
onlyIfEmpty: true,
})
return result !== null
}
export async function cache_generated_icon(
config: InstanceIconConfig,
symbolBytes: number[],
addToRecents = false,
): Promise<string> {
return await invoke('plugin:instance|instance_cache_generated_icon', {
config,
symbolBytes,
addToRecents,
})
}
export async function get_recent_icon_configs(): Promise<InstanceIconConfig[]> {
return await invoke('plugin:instance|instance_get_recent_icon_configs')
}
export type SharedInstanceUsers = {
user_ids: string[]
users: SharedInstanceUser[]
@@ -0,0 +1,9 @@
import { invoke } from '@tauri-apps/api/core'
import type { OnboardingChecklist } from '@/generated/app-events/OnboardingChecklist'
export type { OnboardingChecklist }
export async function getOnboardingChecklist(): Promise<OnboardingChecklist> {
return await invoke('plugin:onboarding-checklist|get_onboarding_checklist')
}
@@ -48,8 +48,6 @@ export type AppSettings = {
discord_rpc: boolean
personalized_ads: boolean
onboarded: boolean
extra_launch_args: string[]
custom_env_vars: [string, string][]
memory: MemorySettings
+18 -3
View File
@@ -8,13 +8,14 @@ export type GameInstance = {
name: string
icon_path?: string
icon_config?: InstanceIconConfig | null
game_version: string
protocol_version?: number
loader: InstanceLoader
loader_version?: string
groups: string[]
group_ids: string[]
link?: InstanceLink | null
shared_instance?: SharedInstanceAttachment | null
@@ -38,6 +39,22 @@ export type GameInstance = {
hooks: Hooks
}
export type IconBackground =
| {
type: 'color'
value: string
}
| {
type: 'linear-top-down-gradient'
top_color: string
bottom_color: string
}
export type InstanceIconConfig = {
background: IconBackground
symbol: string
}
type InstallStage =
| 'installed'
| 'minecraft_installing'
@@ -202,8 +219,6 @@ type AppSettings = {
developer_mode: boolean
personalized_ads: boolean
onboarded: boolean
extra_launch_args: string[]
custom_env_vars: [string, string][]
memory: MemorySettings