You've already forked AstralRinth
forked from didirus/AstralRinth
Onboarding (#132)
* Initial onboarding * Update OnboardingModal.vue * Add finish * Animation * Automatic opening * Move onboarding icon to outside of main appbar * Run lint * run fmt * mostly finish * Finish onboarding * fix onboarding bug + linux build * fix build again * Add back window shadows --------- Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com> Co-authored-by: Jai A <jaiagr+gpg@pm.me> Co-authored-by: Jai A <jai@modrinth.com>
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="mode !== 'isolated'"
|
||||
ref="button"
|
||||
class="button-base avatar-button"
|
||||
:class="{ expanded: expanded }"
|
||||
@click="toggle()"
|
||||
:class="{ expanded: mode === 'expanded' }"
|
||||
@click="showCard = !showCard"
|
||||
>
|
||||
<Avatar :size="expanded ? 'xs' : 'sm'" :src="selectedAccount?.profile_picture ?? ''" />
|
||||
<div v-show="expanded" class="avatar-text">
|
||||
<Avatar
|
||||
:size="mode === 'expanded' ? 'xs' : 'sm'"
|
||||
:src="selectedAccount ? `https://mc-heads.net/avatar/${selectedAccount.id}/128` : ''"
|
||||
/>
|
||||
<div v-show="mode === 'expanded'" class="avatar-text">
|
||||
<div class="text no-select">
|
||||
{{ selectedAccount ? selectedAccount.username : 'Offline' }}
|
||||
</div>
|
||||
@@ -17,9 +21,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<Card v-if="showCard" ref="card" class="account-card" :class="{ expanded: expanded }">
|
||||
<Card
|
||||
v-if="showCard || mode === 'isolated'"
|
||||
ref="card"
|
||||
class="account-card"
|
||||
:class="{ expanded: mode === 'expanded', isolated: mode === 'isolated' }"
|
||||
>
|
||||
<div v-if="selectedAccount" class="selected account">
|
||||
<Avatar size="xs" :src="selectedAccount.profile_picture" />
|
||||
<Avatar size="xs" :src="`https://mc-heads.net/avatar/${selectedAccount.id}/128`" />
|
||||
<div>
|
||||
<h4>{{ selectedAccount.username }}</h4>
|
||||
<p>Selected</p>
|
||||
@@ -37,7 +46,7 @@
|
||||
<div v-if="displayAccounts.length > 0" class="account-group">
|
||||
<div v-for="account in displayAccounts" :key="account.id" class="account-row">
|
||||
<Button class="option account" @click="setAccount(account)">
|
||||
<Avatar :src="account.profile_picture" class="icon" />
|
||||
<Avatar :src="`https://mc-heads.net/avatar/${account.id}/128`" class="icon" />
|
||||
<p>{{ account.username }}</p>
|
||||
</Button>
|
||||
<Button v-tooltip="'Log out'" icon-only @click="logout(account.id)">
|
||||
@@ -55,7 +64,7 @@
|
||||
|
||||
<script setup>
|
||||
import { Avatar, Button, Card, PlusIcon, TrashIcon, UsersIcon, LogInIcon } from 'omorphia'
|
||||
import { ref, defineProps, computed, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
|
||||
import {
|
||||
users,
|
||||
remove_user,
|
||||
@@ -68,51 +77,41 @@ import { handleError } from '@/store/state.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
defineProps({
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
mode: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: 'normal',
|
||||
},
|
||||
})
|
||||
|
||||
const settings = ref(await get().catch(handleError))
|
||||
const emit = defineEmits(['change'])
|
||||
|
||||
const appendProfiles = (accounts) => {
|
||||
return accounts.map((account) => {
|
||||
return {
|
||||
...account,
|
||||
profile_picture: `https://mc-heads.net/avatar/${account.id}/128`,
|
||||
}
|
||||
})
|
||||
const settings = ref({})
|
||||
const accounts = ref([])
|
||||
async function refreshValues() {
|
||||
settings.value = await get().catch(handleError)
|
||||
accounts.value = await users().catch(handleError)
|
||||
}
|
||||
|
||||
const accounts = ref(await users().then(appendProfiles).catch(handleError))
|
||||
defineExpose({
|
||||
refreshValues,
|
||||
})
|
||||
await refreshValues()
|
||||
|
||||
const displayAccounts = computed(() =>
|
||||
accounts.value.filter((account) => settings.value.default_user !== account.id)
|
||||
)
|
||||
|
||||
const selectedAccount = ref(
|
||||
const selectedAccount = computed(() =>
|
||||
accounts.value.find((account) => account.id === settings.value.default_user)
|
||||
)
|
||||
|
||||
const refreshValues = async () => {
|
||||
accounts.value = await users().then(appendProfiles).catch(handleError)
|
||||
selectedAccount.value = accounts.value.find(
|
||||
(account) => account.id === settings.value.default_user
|
||||
)
|
||||
}
|
||||
|
||||
let showCard = ref(false)
|
||||
let card = ref(null)
|
||||
let button = ref(null)
|
||||
|
||||
const setAccount = async (account) => {
|
||||
async function setAccount(account) {
|
||||
settings.value.default_user = account.id
|
||||
selectedAccount.value = account
|
||||
await set(settings.value).catch(handleError)
|
||||
emit('change')
|
||||
}
|
||||
|
||||
const login = async () => {
|
||||
async function login() {
|
||||
const url = await authenticate_begin_flow().catch(handleError)
|
||||
|
||||
const window = new WebviewWindow('loginWindow', {
|
||||
@@ -120,14 +119,6 @@ const login = async () => {
|
||||
url: url,
|
||||
})
|
||||
|
||||
window.once('tauri://created', function () {
|
||||
console.log('webview created')
|
||||
})
|
||||
|
||||
window.once('tauri://error', function (e) {
|
||||
console.log('webview error', e)
|
||||
})
|
||||
|
||||
const loggedIn = await authenticate_await_completion().catch(handleError)
|
||||
await setAccount(loggedIn)
|
||||
await refreshValues()
|
||||
@@ -141,14 +132,15 @@ const logout = async (id) => {
|
||||
if (!selectedAccount.value && accounts.value.length > 0) {
|
||||
await setAccount(accounts.value[0])
|
||||
await refreshValues()
|
||||
} else {
|
||||
emit('change')
|
||||
}
|
||||
mixpanel.track('AccountLogOut')
|
||||
}
|
||||
|
||||
const toggle = () => {
|
||||
showCard.value = !showCard.value
|
||||
}
|
||||
|
||||
let showCard = ref(false)
|
||||
let card = ref(null)
|
||||
let button = ref(null)
|
||||
const handleClickOutside = (event) => {
|
||||
const elements = document.elementsFromPoint(event.clientX, event.clientY)
|
||||
if (
|
||||
@@ -219,6 +211,12 @@ onBeforeUnmount(() => {
|
||||
&.expanded {
|
||||
left: 13.5rem;
|
||||
}
|
||||
|
||||
&.isolated {
|
||||
position: relative;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.accounts-title {
|
||||
|
||||
@@ -61,7 +61,6 @@ const hideContextMenu = () => {
|
||||
}
|
||||
|
||||
const optionClicked = (option) => {
|
||||
console.log('item check', item.value)
|
||||
emit('option-clicked', {
|
||||
item: item.value,
|
||||
option: option,
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<script setup>
|
||||
import { Button, Modal, XIcon, DownloadIcon, DropdownSelect, formatCategory } from 'omorphia'
|
||||
import { add_project_from_version as installMod } from '@/helpers/profile'
|
||||
import { defineExpose, ref } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { handleError, useTheming } from '@/store/state.js'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<JavaDetectionModal ref="detectJavaModal" @submit="(val) => emit('update:modelValue', val)" />
|
||||
<div class="toggle-setting">
|
||||
<div class="toggle-setting" :class="{ compact }">
|
||||
<input
|
||||
autocomplete="off"
|
||||
:disabled="props.disabled"
|
||||
@@ -18,10 +18,7 @@
|
||||
"
|
||||
/>
|
||||
<span class="installation-buttons">
|
||||
<Button
|
||||
:disabled="props.disabled"
|
||||
@click="$refs.detectJavaModal.show(props.version, props.modelValue)"
|
||||
>
|
||||
<Button :disabled="props.disabled" @click="autoDetect">
|
||||
<SearchIcon />
|
||||
Auto detect
|
||||
</Button>
|
||||
@@ -48,11 +45,12 @@
|
||||
|
||||
<script setup>
|
||||
import { Button, SearchIcon, PlayIcon, CheckIcon, XIcon, FolderSearchIcon } from 'omorphia'
|
||||
import { get_jre } from '@/helpers/jre.js'
|
||||
import { find_jre_17_jres, get_jre } from '@/helpers/jre.js'
|
||||
import { ref } from 'vue'
|
||||
import { open } from '@tauri-apps/api/dialog'
|
||||
import JavaDetectionModal from '@/components/ui/JavaDetectionModal.vue'
|
||||
import mixpanel from 'mixpanel-browser'
|
||||
import { handleError } from '@/store/state.js'
|
||||
|
||||
const props = defineProps({
|
||||
version: {
|
||||
@@ -74,6 +72,10 @@ const props = defineProps({
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
compact: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
@@ -117,6 +119,18 @@ async function handleJavaFileInput() {
|
||||
emit('update:modelValue', result)
|
||||
}
|
||||
}
|
||||
|
||||
const detectJavaModal = ref(null)
|
||||
async function autoDetect() {
|
||||
if (!props.compact) {
|
||||
detectJavaModal.value.show(props.version, props.modelValue)
|
||||
} else {
|
||||
let versions = await find_jre_17_jres().catch(handleError)
|
||||
if (versions.length > 0) {
|
||||
emit('update:modelValue', versions[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -131,12 +145,15 @@ async function handleJavaFileInput() {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
&.compact {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.installation-buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin: 0;
|
||||
|
||||
@@ -47,18 +47,7 @@
|
||||
<Card v-if="showCard === true" ref="card" class="info-card">
|
||||
<div v-for="loadingBar in currentLoadingBars" :key="loadingBar.id" class="info-text">
|
||||
<h3 class="info-title">
|
||||
{{ loadingBar.bar_type.pack_name ?? 'Installing Modpack' }}
|
||||
</h3>
|
||||
<ProgressBar :progress="Math.floor(loadingBar.current)" />
|
||||
<div class="row">{{ Math.floor(loadingBar.current) }}% {{ loadingBar.message }}</div>
|
||||
</div>
|
||||
</Card>
|
||||
</transition>
|
||||
<transition name="download">
|
||||
<Card v-if="showCard === true" ref="card" class="info-card">
|
||||
<div v-for="loadingBar in currentLoadingBars" :key="loadingBar.id" class="info-text">
|
||||
<h3 class="info-title">
|
||||
{{ loadingBar.bar_type.pack_name ?? 'Installing Modpack' }}
|
||||
{{ loadingBar.title }}
|
||||
</h3>
|
||||
<ProgressBar :progress="Math.floor(loadingBar.current)" />
|
||||
<div class="row">{{ Math.floor(loadingBar.current) }}% {{ loadingBar.message }}</div>
|
||||
@@ -123,6 +112,7 @@ const profiles = ref(null)
|
||||
const infoButton = ref(null)
|
||||
const profileButton = ref(null)
|
||||
const showCard = ref(false)
|
||||
|
||||
const showProfiles = ref(false)
|
||||
|
||||
const currentProcesses = ref(await getRunningProfiles().catch(handleError))
|
||||
@@ -159,15 +149,25 @@ const goToTerminal = (path) => {
|
||||
router.push(`/instance/${encodeURIComponent(path ?? selectedProfile.value.path)}/logs`)
|
||||
}
|
||||
|
||||
const currentLoadingBars = ref(Object.values(await progress_bars_list().catch(handleError)))
|
||||
|
||||
const unlistenLoading = await loading_listener(async () => {
|
||||
await refreshInfo()
|
||||
})
|
||||
const currentLoadingBars = ref([])
|
||||
|
||||
const refreshInfo = async () => {
|
||||
const currentLoadingBarCount = currentLoadingBars.value.length
|
||||
currentLoadingBars.value = Object.values(await progress_bars_list().catch(handleError))
|
||||
currentLoadingBars.value = Object.values(await progress_bars_list().catch(handleError)).map(
|
||||
(x) => {
|
||||
if (x.bar_type.type === 'java_download') {
|
||||
x.title = 'Downloading Java ' + x.bar_type.version
|
||||
}
|
||||
if (x.bar_type.profile_name) {
|
||||
x.title = x.bar_type.profile_name
|
||||
}
|
||||
if (x.bar_type.pack_name) {
|
||||
x.title = x.bar_type.pack_name
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
)
|
||||
if (currentLoadingBars.value.length === 0) {
|
||||
showCard.value = false
|
||||
} else if (currentLoadingBarCount < currentLoadingBars.value.length) {
|
||||
@@ -175,6 +175,11 @@ const refreshInfo = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
await refreshInfo()
|
||||
const unlistenLoading = await loading_listener(async () => {
|
||||
await refreshInfo()
|
||||
})
|
||||
|
||||
const selectProfile = (profile) => {
|
||||
selectedProfile.value = profile
|
||||
showProfiles.value = false
|
||||
|
||||
Reference in New Issue
Block a user