2023-08-03 11:07:35 -04:00
< script setup >
import {
Button ,
HomeIcon ,
SearchIcon ,
LibraryIcon ,
PlusIcon ,
SettingsIcon ,
XIcon ,
Notifications ,
LogOutIcon ,
} from 'omorphia'
import { appWindow } from '@tauri-apps/api/window'
import { saveWindowState , StateFlags } from 'tauri-plugin-window-state-api'
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
import FakeAppBar from '@/components/ui/tutorial/FakeAppBar.vue'
import FakeAccountsCard from '@/components/ui/tutorial/FakeAccountsCard.vue'
import { MinimizeIcon , MaximizeIcon } from '@/assets/icons'
import ModrinthLoadingIndicator from '@/components/modrinth-loading-indicator.js'
import FakeSearch from '@/components/ui/tutorial/FakeSearch.vue'
import FakeGridDisplay from '@/components/ui/tutorial/FakeGridDisplay.vue'
import FakeRowDisplay from '@/components/ui/tutorial/FakeRowDisplay.vue'
import { onMounted , ref } from 'vue'
import { window } from '@tauri-apps/api'
import TutorialTip from '@/components/ui/tutorial/TutorialTip.vue'
import FakeSettings from '@/components/ui/tutorial/FakeSettings.vue'
import { get , set } from '@/helpers/settings.js'
import mixpanel from 'mixpanel-browser'
import GalleryImage from '@/components/ui/tutorial/GalleryImage.vue'
import LoginCard from '@/components/ui/tutorial/LoginCard.vue'
import StickyTitleBar from '@/components/ui/tutorial/StickyTitleBar.vue'
import { auto _install _java , get _jre } from '@/helpers/jre.js'
import { handleError } from '@/store/notifications.js'
import ImportingCard from '@/components/ui/tutorial/ImportingCard.vue'
2023-08-04 23:38:34 -07:00
import ModrinthLoginScreen from '@/components/ui/tutorial/ModrinthLoginScreen.vue'
2023-08-03 11:07:35 -04:00
import PreImportScreen from '@/components/ui/tutorial/PreImportScreen.vue'
const phase = ref ( 0 )
const page = ref ( 1 )
const props = defineProps ( {
finish : {
type : Function ,
default : ( ) => { } ,
} ,
} )
2023-08-04 23:38:34 -07:00
const flow = ref ( '' )
2023-08-03 11:07:35 -04:00
const nextPhase = ( ) => {
phase . value ++
mixpanel . track ( 'TutorialPhase' , { page : phase . value } )
}
const prevPhase = ( ) => {
phase . value --
}
2023-08-04 23:38:34 -07:00
const nextPage = ( newFlow ) => {
2023-08-03 11:07:35 -04:00
page . value ++
mixpanel . track ( 'OnboardingPage' , { page : page . value } )
2023-08-04 23:38:34 -07:00
if ( newFlow ) {
flow . value = newFlow
}
2023-08-03 11:07:35 -04:00
}
const endOnboarding = ( ) => {
nextPhase ( )
}
const prevPage = ( ) => {
page . value --
}
const finishOnboarding = async ( ) => {
mixpanel . track ( 'OnboardingFinish' )
const settings = await get ( )
2023-08-04 23:38:34 -07:00
settings . fully _onboarded = true
2023-08-03 11:07:35 -04:00
await set ( settings )
props . finish ( )
}
async function fetchSettings ( ) {
const fetchSettings = await get ( ) . catch ( handleError )
if ( ! fetchSettings . java _globals . JAVA _17 ) {
const path = await auto _install _java ( 17 ) . catch ( handleError )
fetchSettings . java _globals . JAVA _17 = await get _jre ( path ) . catch ( handleError )
}
if ( ! fetchSettings . java _globals . JAVA _8 ) {
const path = await auto _install _java ( 8 ) . catch ( handleError )
fetchSettings . java _globals . JAVA _8 = await get _jre ( path ) . catch ( handleError )
}
await set ( fetchSettings ) . catch ( handleError )
}
onMounted ( async ( ) => {
await fetchSettings ( )
} )
< / script >
< template >
< div v-if = "phase === 0" class="onboarding" >
< StickyTitleBar / >
< GalleryImage
v - if = "page === 1"
: gallery = " [
{
url : 'https://cdn.discordapp.com/attachments/817413688771608587/1131109353928265809/Screenshot_2023-07-15_at_4.16.18_PM.png' ,
title : 'Discovery' ,
subtitle : 'See the latest and greatest mods and modpacks to play with from Modrinth' ,
} ,
{
url : 'https://cdn.discordapp.com/attachments/817413688771608587/1131109354238640238/Screenshot_2023-07-15_at_4.17.43_PM.png' ,
title : 'Profile Management' ,
subtitle :
'Play, manage and search through all the amazing profiles downloaded on your computer at any time, even offline!' ,
} ,
] "
logo
>
< Button color = "primary" @click ="nextPage" > Get started < / Button >
< / GalleryImage >
< LoginCard v-else-if = "page === 2" :next-page="nextPage" :prev-page="prevPage" / >
2023-08-04 23:38:34 -07:00
< ModrinthLoginScreen
2023-08-03 11:07:35 -04:00
v - else - if = "page === 3"
2023-08-04 23:38:34 -07:00
: modal = "false"
: next - page = "nextPage"
: prev - page = "prevPage"
: flow = "flow"
/ >
< PreImportScreen
v - else - if = "page === 4"
2023-08-03 11:07:35 -04:00
: next - page = "endOnboarding"
: prev - page = "prevPage"
: import - page = "nextPage"
/ >
2023-08-04 23:38:34 -07:00
< ImportingCard v-else-if = "page === 5" :next-page="endOnboarding" :prev-page="prevPage" / >
2023-08-03 11:07:35 -04:00
< / div >
< div v-else class = "container" >
< StickyTitleBar v-if = "phase === 9" / >
< div v-if = "phase < 9" class="nav-container" >
< div class = "nav-section" >
< FakeAccountsCard : show -demo = " phase = = = 3 " >
< TutorialTip
: progress - function = "nextPhase"
: previous - function = "prevPhase"
: progress = "phase"
title = "Signing in"
description = "The Modrinth App uses your Microsoft account to allow you to launch Minecraft. You can sign in with your Microsoft account here, and switch between multiple accounts."
/ >
< / FakeAccountsCard >
< div class = "pages-list" >
< div class = "btn icon-only" : class = "{ active: phase < 4 }" >
< HomeIcon / >
< / div >
< div class = "btn icon-only" : class = "{ active: phase === 4 || phase === 5 }" >
< SearchIcon / >
< / div >
< div
class = "btn icon-only"
: class = " {
active : phase === 6 || phase === 7 ,
highlighted : phase === 6 ,
} "
>
< LibraryIcon / >
< / div >
< / div >
< / div >
< div class = "settings pages-list" >
< Button class = "active" icon -only @click ="finishOnboarding" >
< LogOutIcon / >
< / Button >
< Button class = "sleek-primary" icon -only >
< PlusIcon / >
< / Button >
< Button icon -only : class = "{ active: phase === 8, highlighted: phase === 8 }" >
< SettingsIcon / >
< / Button >
< / div >
< / div >
< div v-if = "phase < 9" class="view" >
< div data -tauri -drag -region class = "appbar" >
< section class = "navigation-controls" >
< Breadcrumbs data -tauri -drag -region / >
< / section >
< section class = "mod-stats" >
< FakeAppBar : show -running = " phase = = = 7 " : show -download = " phase = = = 5 " >
< template # running >
< TutorialTip
: progress - function = "nextPhase"
: previous - function = "prevPhase"
: progress = "phase"
title = "Playing modpacks"
description = "When you launch a modpack, you can manage it directly in the title bar here. You can stop the modpack, view the logs, and see all currently running packs."
/ >
< / template >
< template # download >
< TutorialTip
: progress - function = "nextPhase"
: previous - function = "prevPhase"
: progress = "phase"
title = "Installing modpacks"
description = "When you download a modpack, Modrinth App will automatically install it for you. You can view the progress of the installation here."
/ >
< / template >
< / FakeAppBar >
< / section >
< section class = "window-controls" >
< Button class = "titlebar-button" icon -only @click ="() => appWindow.minimize()" >
< MinimizeIcon / >
< / Button >
< Button class = "titlebar-button" icon -only @click ="() => appWindow.toggleMaximize()" >
< MaximizeIcon / >
< / Button >
< Button
class = "titlebar-button close"
icon - only
@ click = "
( ) => {
saveWindowState ( StateFlags . ALL )
window . getCurrent ( ) . close ( )
}
"
>
< XIcon / >
< / Button >
< / section >
< / div >
< div class = "router-view" >
< ModrinthLoadingIndicator
offset - height = "var(--appbar-height)"
offset - width = "var(--sidebar-width)"
/ >
< Notifications ref = "notificationsWrapper" / >
< FakeRowDisplay v-if = "phase < 4 || phase > 8" :show-instance="phase === 2" / >
< FakeGridDisplay v-if = "phase === 6 || phase === 7" :show-instances="phase === 6" / >
< suspense >
< FakeSearch v-if = "phase === 4 || phase === 5" :show-search="phase === 4" / >
< / suspense >
< FakeSettings v-if = "phase === 8" / >
< / div >
< / div >
< TutorialTip
v - if = "phase === 1"
class = "first-tip highlighted"
: progress - function = "nextPhase"
: progress = "phase"
title = "Enter the Modrinth App!"
description = " This is the Modrinth App guide . Key parts are marked with a green shadow . Click 'Next' to
proceed . You can leave the tutorial anytime using the Exit button above the plus button on the bottom left . "
/ >
< div v-if = "phase === 1" class="whole-page-shadow" / >
< TutorialTip
v - if = "phase === 2"
class = "sticky-tip"
: progress - function = "nextPhase"
: previous - function = "prevPhase"
: progress = "phase"
title = "Home page"
description = "This is the home page. Here you can see all the latest modpacks, mods, and other content on Modrinth. You can also see a few of your installed modpacks here."
/ >
< TutorialTip
v - if = "phase === 4"
class = "sticky-tip"
: progress - function = "nextPhase"
: previous - function = "prevPhase"
: progress = "phase"
title = "Searching for content"
description = "You can search for content on Modrinth by navigating to the search page. You can search for mods, modpacks, and more, and install them directly from here."
/ >
< TutorialTip
v - if = "phase === 6"
class = "sticky-tip"
: progress - function = "nextPhase"
: previous - function = "prevPhase"
: progress = "phase"
title = "Modpack library"
description = "You can view all your installed modpacks in the library. You can launch any modpack from here, or click the card to view more information about it."
/ >
< TutorialTip
v - if = "phase === 8"
class = "sticky-tip"
: progress - function = "nextPhase"
: previous - function = "prevPhase"
: progress = "phase"
title = "Settings"
description = "You can view and change the settings for the Modrinth App here. You can change the appearance, set and download new Java versions, and more."
/ >
< TutorialTip
v - if = "phase === 9"
class = "final-tip highlighted"
: progress - function = "finishOnboarding"
: progress = "phase"
title = "Enter the Modrinth App!"
description = "That's it! You're ready to use the Modrinth App. If you need help, you can always join our discord server!"
/ >
< / div >
< / template >
< style scoped lang = "scss" >
. sleek - primary {
background - color : var ( -- color - brand - highlight ) ;
transition : all ease - in - out 0.1 s ;
}
. navigation - controls {
flex - grow : 1 ;
width : min - content ;
}
. window - controls {
z - index : 20 ;
display : none ;
flex - direction : row ;
align - items : center ;
gap : 0.25 rem ;
. titlebar - button {
display : flex ;
align - items : center ;
justify - content : center ;
cursor : pointer ;
transition : all ease - in - out 0.1 s ;
background - color : var ( -- color - raised - bg ) ;
color : var ( -- color - base ) ;
& . close {
& : hover ,
& : active {
background - color : var ( -- color - red ) ;
color : var ( -- color - accent - contrast ) ;
}
}
& : hover ,
& : active {
background - color : var ( -- color - button - bg ) ;
color : var ( -- color - contrast ) ;
}
}
}
. container {
-- appbar - height : 3.25 rem ;
-- sidebar - width : 4.5 rem ;
height : 100 vh ;
display : flex ;
flex - direction : row ;
overflow : hidden ;
. view {
width : calc ( 100 % - var ( -- sidebar - width ) ) ;
. appbar {
display : flex ;
align - items : center ;
background : var ( -- color - raised - bg ) ;
box - shadow : var ( -- shadow - inset - sm ) , var ( -- shadow - floating ) ;
padding : var ( -- gap - md ) ;
height : 3.25 rem ;
gap : var ( -- gap - sm ) ;
user - select : none ;
- webkit - user - select : none ;
}
. router - view {
width : 100 % ;
height : calc ( 100 % - 3.125 rem ) ;
overflow : auto ;
overflow - x : hidden ;
background - color : var ( -- color - bg ) ;
}
}
}
. nav - container {
display : flex ;
flex - direction : column ;
align - items : center ;
justify - content : space - between ;
height : 100 % ;
background - color : var ( -- color - raised - bg ) ;
box - shadow : var ( -- shadow - inset - sm ) , var ( -- shadow - floating ) ;
padding : var ( -- gap - md ) ;
width : var ( -- sidebar - width ) ;
max - width : var ( -- sidebar - width ) ;
min - width : var ( -- sidebar - width ) ;
-- sidebar - width : 4.5 rem ;
}
. pages - list {
display : flex ;
flex - direction : column ;
align - items : flex - start ;
justify - content : flex - start ;
width : 100 % ;
gap : 0.5 rem ;
. btn {
background - color : var ( -- color - raised - bg ) ;
height : 3 rem ! important ;
width : 3 rem ! important ;
padding : 0.75 rem ;
border - radius : var ( -- radius - md ) ;
box - shadow : none ;
svg {
width : 1.5 rem ! important ;
height : 1.5 rem ! important ;
max - width : 1.5 rem ! important ;
max - height : 1.5 rem ! important ;
}
& . active {
background - color : var ( -- color - button - bg ) ;
box - shadow : var ( -- shadow - floating ) ;
}
& . sleek - primary {
background - color : var ( -- color - brand - highlight ) ;
transition : all ease - in - out 0.1 s ;
}
& . sleek - exit {
background - color : var ( -- color - red ) ;
color : var ( -- color - accent - contrast ) ;
transition : all ease - in - out 0.1 s ;
}
}
}
. nav - section {
display : flex ;
flex - direction : column ;
justify - content : flex - start ;
align - items : center ;
width : 100 % ;
height : 100 % ;
gap : 1 rem ;
}
. sticky - tip {
position : absolute ;
bottom : 1 rem ;
right : 1 rem ;
z - index : 10 ;
}
. intro - card {
display : flex ;
flex - direction : column ;
padding : var ( -- gap - xl ) ;
. app - logo {
width : 100 % ;
height : auto ;
display : block ;
margin : auto ;
}
p {
color : var ( -- color - contrast ) ;
text - align : left ;
width : 100 % ;
}
. actions {
display : flex ;
flex - direction : row ;
align - items : center ;
justify - content : flex - end ;
gap : var ( -- gap - sm ) ;
}
}
. final - tip {
position : absolute ;
bottom : 50 % ;
right : 50 % ;
transform : translate ( 50 % , 50 % ) ;
z - index : 10 ;
}
. onboarding {
background : top linear - gradient ( 0 deg , # 31375 f , rgba ( 8 , 14 , 55 , 0 ) ) ,
url ( https : //cdn.modrinth.com/landing-new/landing-lower.webp);
background - size : cover ;
height : 100 vh ;
min - height : 100 vh ;
max - height : 100 vh ;
width : 100 % ;
display : flex ;
flex - direction : column ;
align - items : center ;
justify - content : center ;
padding : var ( -- gap - xl ) ;
padding - top : calc ( 2.5 rem + var ( -- gap - lg ) ) ;
}
. first - tip {
position : absolute ;
top : 50 % ;
left : 50 % ;
transform : translate ( - 50 % , - 50 % ) ;
z - index : 10 ;
}
. whole - page - shadow {
position : absolute ;
top : 0 ;
left : 0 ;
width : 100 vw ;
height : 100 % ;
backdrop - filter : brightness ( 0.5 ) ;
- webkit - backdrop - filter : brightness ( 0.5 ) ;
z - index : 9 ;
}
< / style >