replace progressbar with inhouse

This commit is contained in:
2023-02-26 13:21:01 +10:00
parent c1dbde2fb7
commit b718212702
7 changed files with 213 additions and 17 deletions

View File

@@ -0,0 +1,84 @@
<template>
<div>
<div
class="sm-progress-container"
:style="{ opacity: `${progressStore.opacity || 0}` }">
<div
class="sm-progress"
:style="{
width: `${(progressStore.status || 0) * 100}%`,
}"></div>
</div>
<div
class="sm-spinner"
:style="{ opacity: `${progressStore.spinner || 0}` }">
<div class="sm-spinner-icon"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { useProgressStore } from "../store/ProgressStore";
const progressStore = useProgressStore();
</script>
<style lang="scss">
.sm-progress-container {
position: fixed;
background-color: $border-color;
height: 2px;
top: 0;
left: 0;
right: 0;
z-index: 2000;
transition: opacity 0.2s ease-in-out;
.sm-progress {
background-color: $primary-color-dark;
width: 0%;
height: 100%;
transition: width 0.2s ease-in-out;
box-shadow: 0 0 10px $primary-color-dark, 0 0 4px $primary-color-dark;
opacity: 1;
}
}
.sm-spinner {
position: fixed;
top: 10px;
right: 10px;
transition: opacity 0.2s ease-in-out;
.sm-spinner-icon {
width: 18px;
height: 18px;
box-sizing: border-box;
border: solid 2px transparent;
border-top-color: #29d;
border-left-color: #29d;
border-radius: 50%;
-webkit-animation: sm-progress-spinner 500ms linear infinite;
animation: sm-progress-spinner 500ms linear infinite;
}
}
@-webkit-keyframes sm-progress-spinner {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes sm-progress-spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>

View File

@@ -1,7 +1,5 @@
import { useUserStore } from "../store/UserStore";
import { ProgressFinisher, useProgress } from "@marcoschulte/vue3-progress";
const progresses = [] as ProgressFinisher[];
import { useProgressStore } from "../store/ProgressStore";
interface ApiProgressData {
loaded: number;
total: number;
@@ -82,7 +80,8 @@ export const api = {
let receivedData = false;
progresses.push(useProgress().start());
const progressStore = useProgressStore();
progressStore.start();
fetch(url, fetchOptions)
.then((response) => {
@@ -177,7 +176,7 @@ export const api = {
});
})
.finally(() => {
progresses.pop()?.finish();
progressStore.finish();
});
});
},

View File

@@ -1,8 +1,8 @@
import { createWebHistory, createRouter } from "vue-router";
import { useUserStore } from "@/store/UserStore";
import { useApplicationStore } from "../store/ApplicationStore";
import { useProgressStore } from "../store/ProgressStore";
import { api } from "../helpers/api";
import { useProgress } from "@marcoschulte/vue3-progress";
const progresses = [];
@@ -377,8 +377,11 @@ const router = createRouter({
router.beforeEach(async (to, from, next) => {
const userStore = useUserStore();
const applicationStore = useApplicationStore();
const progressStore = useProgressStore();
// progressStore.reset();
progressStore.start();
progresses.push(useProgress().start());
applicationStore.clearDynamicTitle();
// Check Token
@@ -451,7 +454,7 @@ router.beforeEach(async (to, from, next) => {
}
if (to.meta.middleware == "authenticated" && !userStore.id) {
progresses.pop()?.finish();
progressStore.finish();
next({ name: "login", query: { redirect: to.fullPath } });
} else {
next();
@@ -459,7 +462,8 @@ router.beforeEach(async (to, from, next) => {
});
router.afterEach((to, from) => {
progresses.pop()?.finish();
const progressStore = useProgressStore();
progressStore.finish();
});
export default router;

View File

@@ -0,0 +1,115 @@
import { defineStore } from "pinia";
import { clamp } from "../helpers/utils";
export interface ProgressStore {
spinner: number;
status: number;
opacity: number;
queue: number;
timeoutID: number | null;
}
export const useProgressStore = defineStore({
id: "progress",
state: (): ProgressStore => ({
spinner: 0,
status: 0,
opacity: 0,
queue: 0,
timeoutID: null,
}),
actions: {
start() {
if (this.queue == 0) {
this.set(0);
const work = () => {
window.setTimeout(() => {
if (this.status != null) {
this._trickle();
work();
}
}, 200);
};
work();
if (this.opacity == 0) {
if (this.timeoutID != null) {
window.clearTimeout(this.timeoutID);
}
this.timeoutID = window.setTimeout(() => {
this._show();
this.timeoutID = null;
}, 200);
}
if (this.spinner == 0) {
this.spinner = 1;
}
}
++this.queue;
},
set(number: number) {
this.status = clamp(number, 0.08, 1);
},
finish() {
if (this.queue > 0) {
--this.queue;
}
},
_trickle() {
const n = this.status;
if (this.queue == 0 && this.timeoutID == null) {
this.timeoutID = window.setTimeout(() => {
this.set(1);
this.timeoutID = null;
this.timeoutID = window.setTimeout(() => {
this._hide();
this.timeoutID = null;
}, 500);
}, 200);
}
if (n == 0) {
this.start();
} else if (n < 1) {
let amount = 0;
if (n >= 0 && n < 0.2) {
amount = 0.1;
} else if (n >= 0.2 && n < 0.5) {
amount = 0.04;
} else if (n >= 0.5 && n < 0.8) {
amount = 0.02;
} else if (n >= 0.8 && n < 0.99) {
amount = 0.005;
} else {
amount = 0;
}
this.set(clamp(n + amount, 0, 0.994));
}
},
_show() {
this.opacity = 1;
},
_hide() {
this.opacity = 0;
if (this.spinner == 1) {
this.spinner = 0;
}
},
},
});

View File

@@ -8,13 +8,14 @@
</router-view>
</main>
<SMFooter />
<vue3-progress-bar></vue3-progress-bar>
<SMProgress />
<DialogWrapper :transition-attrs="{ name: 'fade' }" />
</template>
<script setup lang="ts">
import SMNavbar from "../components/SMNavbar.vue";
import SMFooter from "../components/SMFooter.vue";
import SMProgress from "../components/SMProgress.vue";
import { DialogWrapper } from "vue3-promise-dialog";
</script>