Loading bars (#113)

* Loading bars

* remove print

* remove print

* remove class

* Fix overlay
This commit is contained in:
Geometrically
2023-05-10 11:19:01 -07:00
committed by GitHub
parent dee8b50e69
commit 9be0d16f75
6 changed files with 170 additions and 17 deletions

View File

@@ -2,12 +2,13 @@
import { onMounted } from 'vue'
import { RouterView, RouterLink } from 'vue-router'
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 InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
import { get } from '@/helpers/settings'
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
import RunningAppBar from '@/components/ui/RunningAppBar.vue'
import ModrinthLoadingIndicator from '@/components/modrinth-loading-indicator'
const themeStore = useTheming()
@@ -16,6 +17,8 @@ onMounted(async () => {
themeStore.setThemeState(settings)
themeStore.collapsedNavigation = collapsed_navigation
})
const loading = useLoading()
</script>
<template>
@@ -106,9 +109,13 @@ onMounted(async () => {
</section>
</div>
<div class="router-view">
<ModrinthLoadingIndicator
offset-height="var(--appbar-height)"
offset-width="var(--sidebar-width)"
/>
<RouterView v-slot="{ Component }">
<template v-if="Component">
<Suspense>
<Suspense @pending="loading.startLoading()" @resolve="loading.stopLoading()">
<component :is="Component"></component>
</Suspense>
</template>
@@ -120,18 +127,21 @@ onMounted(async () => {
<style lang="scss" scoped>
.container {
--appbar-height: 3.25rem;
--sidebar-width: 5rem;
height: 100vh;
display: flex;
flex-direction: row;
overflow: hidden;
.view {
width: var(--view-width);
&.expanded {
width: var(--expanded-view-width);
--sidebar-width: 13rem;
}
width: calc(100% - var(--sidebar-width));
.appbar {
display: flex;
justify-content: space-between;
@@ -219,9 +229,11 @@ onMounted(async () => {
background: var(--color-raised-bg);
&.expanded {
width: 13rem;
max-width: 13rem;
min-width: 13rem;
--sidebar-width: 13rem;
width: var(--sidebar-width);
max-width: var(--sidebar-width);
min-width: var(--sidebar-width);
}
}

View 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,
}
}

View File

@@ -1,7 +0,0 @@
<script setup></script>
<template>
<div>
<p>Add Instance</p>
</div>
</template>

View File

@@ -47,7 +47,7 @@ await getInstances()
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
const unlisten = await profile_listener(async (e) => {
if (e.event === 'edited') {
if (e.event === 'created' || e.event === 'removed') {
await getInstances()
await Promise.all([getFeaturedModpacks(), getFeaturedMods()])
}

View 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
},
},
})

View File

@@ -1,5 +1,6 @@
import { useSearch } from './search'
import { useTheming } from './theme'
import { useBreadcrumbs } from './breadcrumbs'
import { useLoading } from './loading'
export { useSearch, useTheming, useBreadcrumbs }
export { useSearch, useTheming, useBreadcrumbs, useLoading }