diff --git a/package-lock.json b/package-lock.json
index fa536c3..db9a3a8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,7 +5,6 @@
"packages": {
"": {
"dependencies": {
- "@marcoschulte/vue3-progress": "^0.0.7",
"@tinymce/tinymce-vue": "^4.0.7",
"@vitejs/plugin-vue": "^4.0.0",
"@vuepic/vue-datepicker": "^3.6.4",
@@ -520,11 +519,6 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
- "node_modules/@marcoschulte/vue3-progress": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/@marcoschulte/vue3-progress/-/vue3-progress-0.0.7.tgz",
- "integrity": "sha512-gcvZW9gJ/isTD0sjorgvLOuoS2U5r5djMoLOwuN4YvhOvgOyYGWoQF1hubhouE/dVDPvWHmZsD0gvf6YD0x7fg=="
- },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
diff --git a/package.json b/package.json
index 4835f3f..44a54b9 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,6 @@
"vitest": "^0.28.5"
},
"dependencies": {
- "@marcoschulte/vue3-progress": "^0.0.7",
"@tinymce/tinymce-vue": "^4.0.7",
"@vitejs/plugin-vue": "^4.0.0",
"@vuepic/vue-datepicker": "^3.6.4",
diff --git a/resources/js/components/SMProgress.vue b/resources/js/components/SMProgress.vue
new file mode 100644
index 0000000..25e61c6
--- /dev/null
+++ b/resources/js/components/SMProgress.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
diff --git a/resources/js/helpers/api.ts b/resources/js/helpers/api.ts
index 47c9a4a..2bef9d5 100644
--- a/resources/js/helpers/api.ts
+++ b/resources/js/helpers/api.ts
@@ -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();
});
});
},
diff --git a/resources/js/router/index.js b/resources/js/router/index.js
index 03b5cd1..56bd202 100644
--- a/resources/js/router/index.js
+++ b/resources/js/router/index.js
@@ -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;
diff --git a/resources/js/store/ProgressStore.ts b/resources/js/store/ProgressStore.ts
new file mode 100644
index 0000000..ec3bbf3
--- /dev/null
+++ b/resources/js/store/ProgressStore.ts
@@ -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;
+ }
+ },
+ },
+});
diff --git a/resources/js/views/App.vue b/resources/js/views/App.vue
index 9446e81..d3d6e25 100644
--- a/resources/js/views/App.vue
+++ b/resources/js/views/App.vue
@@ -8,13 +8,14 @@
-
+