You've already forked AstralRinth
forked from didirus/AstralRinth
Loading bars (#113)
* Loading bars * remove print * remove print * remove class * Fix overlay
This commit is contained in:
@@ -2,12 +2,13 @@
|
|||||||
import { onMounted } from 'vue'
|
import { onMounted } from 'vue'
|
||||||
import { RouterView, RouterLink } from 'vue-router'
|
import { RouterView, RouterLink } from 'vue-router'
|
||||||
import { HomeIcon, SearchIcon, LibraryIcon, PlusIcon, SettingsIcon, Button } from 'omorphia'
|
import { HomeIcon, SearchIcon, LibraryIcon, PlusIcon, SettingsIcon, Button } from 'omorphia'
|
||||||
import { useTheming } from '@/store/state'
|
import { useLoading, useTheming } from '@/store/state'
|
||||||
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
import AccountsCard from '@/components/ui/AccountsCard.vue'
|
||||||
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
|
||||||
import { get } from '@/helpers/settings'
|
import { get } from '@/helpers/settings'
|
||||||
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
|
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
|
||||||
import RunningAppBar from '@/components/ui/RunningAppBar.vue'
|
import RunningAppBar from '@/components/ui/RunningAppBar.vue'
|
||||||
|
import ModrinthLoadingIndicator from '@/components/modrinth-loading-indicator'
|
||||||
|
|
||||||
const themeStore = useTheming()
|
const themeStore = useTheming()
|
||||||
|
|
||||||
@@ -16,6 +17,8 @@ onMounted(async () => {
|
|||||||
themeStore.setThemeState(settings)
|
themeStore.setThemeState(settings)
|
||||||
themeStore.collapsedNavigation = collapsed_navigation
|
themeStore.collapsedNavigation = collapsed_navigation
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const loading = useLoading()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -106,9 +109,13 @@ onMounted(async () => {
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div class="router-view">
|
<div class="router-view">
|
||||||
|
<ModrinthLoadingIndicator
|
||||||
|
offset-height="var(--appbar-height)"
|
||||||
|
offset-width="var(--sidebar-width)"
|
||||||
|
/>
|
||||||
<RouterView v-slot="{ Component }">
|
<RouterView v-slot="{ Component }">
|
||||||
<template v-if="Component">
|
<template v-if="Component">
|
||||||
<Suspense>
|
<Suspense @pending="loading.startLoading()" @resolve="loading.stopLoading()">
|
||||||
<component :is="Component"></component>
|
<component :is="Component"></component>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</template>
|
</template>
|
||||||
@@ -120,18 +127,21 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.container {
|
.container {
|
||||||
|
--appbar-height: 3.25rem;
|
||||||
|
--sidebar-width: 5rem;
|
||||||
|
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.view {
|
.view {
|
||||||
width: var(--view-width);
|
|
||||||
|
|
||||||
&.expanded {
|
&.expanded {
|
||||||
width: var(--expanded-view-width);
|
--sidebar-width: 13rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
width: calc(100% - var(--sidebar-width));
|
||||||
|
|
||||||
.appbar {
|
.appbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -219,9 +229,11 @@ onMounted(async () => {
|
|||||||
background: var(--color-raised-bg);
|
background: var(--color-raised-bg);
|
||||||
|
|
||||||
&.expanded {
|
&.expanded {
|
||||||
width: 13rem;
|
--sidebar-width: 13rem;
|
||||||
max-width: 13rem;
|
|
||||||
min-width: 13rem;
|
width: var(--sidebar-width);
|
||||||
|
max-width: var(--sidebar-width);
|
||||||
|
min-width: var(--sidebar-width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
134
theseus_gui/src/components/modrinth-loading-indicator.js
Normal file
134
theseus_gui/src/components/modrinth-loading-indicator.js
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
import { computed, defineComponent, h, onBeforeUnmount, ref, watch } from 'vue'
|
||||||
|
import { useLoading } from '@/store/state.js'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
throttle: {
|
||||||
|
type: Number,
|
||||||
|
default: 50,
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: 500,
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
default: 3,
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default:
|
||||||
|
'repeating-linear-gradient(to right, var(--color-brand) 0%, var(--color-brand) 100%)',
|
||||||
|
},
|
||||||
|
offsetWidth: {
|
||||||
|
type: String,
|
||||||
|
default: '208px',
|
||||||
|
},
|
||||||
|
offsetHeight: {
|
||||||
|
type: String,
|
||||||
|
default: '52px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const indicator = useLoadingIndicator({
|
||||||
|
duration: props.duration,
|
||||||
|
throttle: props.throttle,
|
||||||
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => indicator.clear)
|
||||||
|
|
||||||
|
const loading = useLoading()
|
||||||
|
|
||||||
|
watch(loading, (newValue) => {
|
||||||
|
if (newValue.loading) {
|
||||||
|
indicator.start()
|
||||||
|
} else {
|
||||||
|
indicator.finish()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
h(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
style: {
|
||||||
|
position: 'fixed',
|
||||||
|
top: props.offsetHeight,
|
||||||
|
right: 0,
|
||||||
|
left: props.offsetWidth,
|
||||||
|
pointerEvents: 'none',
|
||||||
|
width: `calc((100vw - ${props.offsetWidth}) * ${indicator.progress.value / 100})`,
|
||||||
|
height: `${props.height}px`,
|
||||||
|
opacity: indicator.isLoading.value ? 1 : 0,
|
||||||
|
background: props.color || undefined,
|
||||||
|
backgroundSize: `${(100 / indicator.progress.value) * 100}% auto`,
|
||||||
|
transition: 'width 0.1s, height 0.4s, opacity 0.4s',
|
||||||
|
zIndex: 99,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
slots
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
function useLoadingIndicator(opts) {
|
||||||
|
const progress = ref(0)
|
||||||
|
const isLoading = ref(false)
|
||||||
|
const step = computed(() => 10000 / opts.duration)
|
||||||
|
|
||||||
|
let _timer = null
|
||||||
|
let _throttle = null
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
clear()
|
||||||
|
progress.value = 0
|
||||||
|
if (opts.throttle) {
|
||||||
|
_throttle = setTimeout(() => {
|
||||||
|
isLoading.value = true
|
||||||
|
_startTimer()
|
||||||
|
}, opts.throttle)
|
||||||
|
} else {
|
||||||
|
isLoading.value = true
|
||||||
|
_startTimer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function finish() {
|
||||||
|
progress.value = 100
|
||||||
|
_hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
clearInterval(_timer)
|
||||||
|
clearTimeout(_throttle)
|
||||||
|
_timer = null
|
||||||
|
_throttle = null
|
||||||
|
}
|
||||||
|
|
||||||
|
function _increase(num) {
|
||||||
|
progress.value = Math.min(100, progress.value + num)
|
||||||
|
}
|
||||||
|
|
||||||
|
function _hide() {
|
||||||
|
clear()
|
||||||
|
setTimeout(() => {
|
||||||
|
isLoading.value = false
|
||||||
|
setTimeout(() => {
|
||||||
|
progress.value = 0
|
||||||
|
}, 400)
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
function _startTimer() {
|
||||||
|
_timer = setInterval(() => {
|
||||||
|
_increase(step.value)
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
progress,
|
||||||
|
isLoading,
|
||||||
|
start,
|
||||||
|
finish,
|
||||||
|
clear,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<script setup></script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<p>Add Instance</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -47,7 +47,7 @@ await getInstances()
|
|||||||
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
|
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
|
||||||
|
|
||||||
const unlisten = await profile_listener(async (e) => {
|
const unlisten = await profile_listener(async (e) => {
|
||||||
if (e.event === 'edited') {
|
if (e.event === 'created' || e.event === 'removed') {
|
||||||
await getInstances()
|
await getInstances()
|
||||||
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
|
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
|
||||||
}
|
}
|
||||||
|
|||||||
13
theseus_gui/src/store/loading.js
Normal file
13
theseus_gui/src/store/loading.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useLoading = defineStore('loadingStore', {
|
||||||
|
state: () => ({ loading: false }),
|
||||||
|
actions: {
|
||||||
|
startLoading() {
|
||||||
|
this.loading = true
|
||||||
|
},
|
||||||
|
stopLoading() {
|
||||||
|
this.loading = false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useSearch } from './search'
|
import { useSearch } from './search'
|
||||||
import { useTheming } from './theme'
|
import { useTheming } from './theme'
|
||||||
import { useBreadcrumbs } from './breadcrumbs'
|
import { useBreadcrumbs } from './breadcrumbs'
|
||||||
|
import { useLoading } from './loading'
|
||||||
|
|
||||||
export { useSearch, useTheming, useBreadcrumbs }
|
export { useSearch, useTheming, useBreadcrumbs, useLoading }
|
||||||
|
|||||||
Reference in New Issue
Block a user