mirror of
https://github.com/modrinth/code.git
synced 2026-08-27 10:04:52 +00:00
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:
+164
-55
@@ -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"
|
||||
/>
|
||||
<IconEditorModal
|
||||
ref="creationIconEditorModal"
|
||||
:config="creationGeneratedIcon?.config"
|
||||
@saved="onCreationIconSaved"
|
||||
/>
|
||||
<UnknownPackWarningModal ref="unknownPackWarningModal" />
|
||||
<div
|
||||
class="app-grid-navbar bg-bg-raised flex flex-col p-[0.5rem] pt-0 gap-[0.25rem] w-[--left-bar-width]"
|
||||
>
|
||||
<NavButton v-tooltip.right="formatMessage(messages.home)" to="/">
|
||||
<HomeIcon />
|
||||
<NavButton
|
||||
v-tooltip.right="formatMessage(messages.home)"
|
||||
to="/"
|
||||
:is-primary="(route) => route.path === '/'"
|
||||
:is-subpage="
|
||||
() =>
|
||||
(route.path.startsWith('/browse') || route.path.startsWith('/project')) && route.query.i
|
||||
"
|
||||
>
|
||||
<PlayIcon />
|
||||
</NavButton>
|
||||
<NavButton
|
||||
v-tooltip.right="formatMessage(commonMessages.discoverContentLabel)"
|
||||
@@ -1605,19 +1712,6 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
<NavButton v-tooltip.right="formatMessage(appMessages.skinSelectorLabel)" to="/skins">
|
||||
<ShirtIcon />
|
||||
</NavButton>
|
||||
<NavButton
|
||||
v-tooltip.right="formatMessage(messages.library)"
|
||||
to="/library"
|
||||
:is-primary="(r) => r.path === '/library' || r.path === '/library'"
|
||||
:is-subpage="
|
||||
() =>
|
||||
route.path.startsWith('/instance') ||
|
||||
((route.path.startsWith('/browse') || route.path.startsWith('/project')) &&
|
||||
route.query.i)
|
||||
"
|
||||
>
|
||||
<LibraryIcon />
|
||||
</NavButton>
|
||||
<NavButton
|
||||
v-tooltip.right="formatMessage(messages.modrinthHosting)"
|
||||
to="/hosting/manage"
|
||||
@@ -1652,7 +1746,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
v-tooltip.right="formatMessage(messages.modrinthAccount)"
|
||||
type="quiet"
|
||||
size="xl"
|
||||
label="More options"
|
||||
:label="formatMessage(messages.moreOptions)"
|
||||
:options="[
|
||||
{
|
||||
id: 'view-profile',
|
||||
@@ -1707,7 +1801,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
<div data-tauri-drag-region class="ml-2 flex shrink-0 items-center gap-2">
|
||||
<IconButton
|
||||
type="outlined"
|
||||
label="Go back"
|
||||
:label="formatMessage(messages.goBack)"
|
||||
class="!h-7 !min-w-7 !w-7 !border !border-surface-4 !p-0 !opacity-100"
|
||||
:disabled="!canNavigateBack"
|
||||
@click="router.back()"
|
||||
@@ -1719,7 +1813,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
</IconButton>
|
||||
<IconButton
|
||||
type="outlined"
|
||||
label="Go forward"
|
||||
:label="formatMessage(messages.goForward)"
|
||||
class="!h-7 !min-w-7 !w-7 !border !border-surface-4 !p-0 !opacity-100"
|
||||
:disabled="!canNavigateForward"
|
||||
@click="router.forward()"
|
||||
@@ -1736,7 +1830,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
<IconButton
|
||||
v-if="!forceSidebar && themeStore.toggleSidebar"
|
||||
:type="sidebarToggled ? 'base' : 'quiet'"
|
||||
label="Next image"
|
||||
:label="formatMessage(messages.nextImage)"
|
||||
class="mr-3 transition-transform"
|
||||
:class="{ 'rotate-180': !sidebarToggled }"
|
||||
@click="sidebarToggled = !sidebarToggled"
|
||||
@@ -1808,7 +1902,9 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
<RouterView v-else v-slot="{ Component }">
|
||||
<template v-if="Component">
|
||||
<Suspense @pending="onSuspensePending" @resolve="onSuspenseResolve">
|
||||
<component :is="Component"></component>
|
||||
<KeepAlive include="LibraryPage">
|
||||
<component :is="Component"></component>
|
||||
</KeepAlive>
|
||||
</Suspense>
|
||||
</template>
|
||||
</RouterView>
|
||||
@@ -1823,9 +1919,17 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
:class="{ 'pb-12': !hasPlus }"
|
||||
data-overlayscrollbars-initialize
|
||||
>
|
||||
<OnboardingChecklist
|
||||
@create-instance="installationModal?.show()"
|
||||
@login-minecraft="accounts?.login()"
|
||||
@login-modrinth="signIn"
|
||||
/>
|
||||
<div id="sidebar-teleport-target" class="sidebar-teleport-content"></div>
|
||||
<div class="sidebar-default-content" :class="{ 'sidebar-enabled': sidebarVisible }">
|
||||
<div class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid">
|
||||
<div
|
||||
v-show="hasLoggedIntoMinecraft"
|
||||
class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid"
|
||||
>
|
||||
<h3 class="text-base text-primary font-medium m-0">
|
||||
{{ formatMessage(messages.playingAs) }}
|
||||
</h3>
|
||||
@@ -1833,7 +1937,10 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
<AccountsCard ref="accounts" />
|
||||
</suspense>
|
||||
</div>
|
||||
<div class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid">
|
||||
<div
|
||||
v-show="showFriendsList"
|
||||
class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid"
|
||||
>
|
||||
<suspense>
|
||||
<FriendsList :credentials="credentials" :sign-in="() => requestSignIn()" />
|
||||
</suspense>
|
||||
@@ -1897,6 +2004,8 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
:preferred-game-version="contentInstallPreferredGameVersion"
|
||||
:release-game-versions="contentInstallReleaseGameVersions"
|
||||
:project-info="contentInstallProjectInfo"
|
||||
:randomize-icon="randomizeCreationIcon"
|
||||
:customize-icon="customizeContentInstallIcon"
|
||||
@install="handleInstallToInstance"
|
||||
@create-and-install="handleCreateAndInstall"
|
||||
@navigate="handleContentInstallNavigate"
|
||||
|
||||
Reference in New Issue
Block a user