mirror of
				https://github.com/mickael-kerjean/filestash.git
				synced 2025-10-31 18:16:00 +08:00 
			
		
		
		
	feature (speed): improve loading speed
This commit is contained in:
		| @ -1,4 +1,4 @@ | |||||||
| const CACHENAME = "assets"; | let VERSION = null; | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * This Service Worker is an optional optimisation to load the app faster. |  * This Service Worker is an optional optimisation to load the app faster. | ||||||
| @ -41,7 +41,7 @@ self.addEventListener("fetch", async(event) => { | |||||||
|     if (!event.request.url.startsWith(location.origin + "/assets/")) return; |     if (!event.request.url.startsWith(location.origin + "/assets/")) return; | ||||||
|  |  | ||||||
|     event.respondWith((async() => { |     event.respondWith((async() => { | ||||||
|         const cache = await caches.open(CACHENAME); |         const cache = await caches.open(VERSION); | ||||||
|         const cachedResponse = await cache.match(event.request); |         const cachedResponse = await cache.match(event.request); | ||||||
|         if (cachedResponse) return cachedResponse; |         if (cachedResponse) return cachedResponse; | ||||||
|         return fetch(event.request); |         return fetch(event.request); | ||||||
| @ -51,19 +51,42 @@ self.addEventListener("fetch", async(event) => { | |||||||
| self.addEventListener("message", (event) => { | self.addEventListener("message", (event) => { | ||||||
|     if (event.data.type === "preload") handlePreloadMessage( |     if (event.data.type === "preload") handlePreloadMessage( | ||||||
|         event.data.payload, |         event.data.payload, | ||||||
|  |         event.data.clear, | ||||||
|  |         event.data.version, | ||||||
|         () => event.source.postMessage({ type: "preload", status: "ok" }), |         () => event.source.postMessage({ type: "preload", status: "ok" }), | ||||||
|         (err) => event.source.postMessage({ type: "preload", status: "error", msg: err.message }), |         (err) => event.source.postMessage({ type: "preload", status: "error", msg: err.message }), | ||||||
|     ); |     ); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| async function handlePreloadMessage(chunks, resolve, reject, id) { | async function handlePreloadMessage(chunks, clear, version, resolve, reject) { | ||||||
|  |     VERSION = version; | ||||||
|     const cleanup = []; |     const cleanup = []; | ||||||
|     try { |     try { | ||||||
|         await caches.delete(CACHENAME); |         let execHTTP = true; | ||||||
|         const cache = await caches.open(CACHENAME); |         await caches.keys().then(async(names) => { | ||||||
|         await Promise.all(chunks.map((urls) => { |             for (let i=0; i<names.length; i++) { | ||||||
|             return preload({ urls, cache, cleanup }); |                 if (names[i] === VERSION && !clear) { | ||||||
|         })); |                     execHTTP = false; | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |                 await caches.delete(names[i]); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         if (execHTTP) { | ||||||
|  |             const cache = await caches.open(VERSION); | ||||||
|  |             chunks = await Promise.all(chunks.map(async(urls) => { | ||||||
|  |                 const missing = []; | ||||||
|  |                 await Promise.all(urls.map(async(url) => { | ||||||
|  |                     if (!await cache.match(location.origin + url)) missing.push(url); | ||||||
|  |                 })); | ||||||
|  |                 return missing; | ||||||
|  |             })); | ||||||
|  |             if (chunks.filter((urls) => urls.length > 0).length > 0) { | ||||||
|  |                 await Promise.all(chunks.map((urls) => { | ||||||
|  |                     return preload({ urls, cache, cleanup }); | ||||||
|  |                 })); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         resolve(); |         resolve(); | ||||||
|     } catch (err) { |     } catch (err) { | ||||||
|         console.log("ERR", err); |         console.log("ERR", err); | ||||||
| @ -88,7 +111,7 @@ async function preload({ urls, cache, cleanup }) { | |||||||
|         await cache.put( |         await cache.put( | ||||||
|             location.origin + url, |             location.origin + url, | ||||||
|             new Response( |             new Response( | ||||||
|                 decoder(new Blob([Uint8Array.from(atob(event.data), (c) => c.charCodeAt(0))]).stream()), |                 decoder(new Blob([base128Decode(event.data)]).stream()), | ||||||
|                 { headers: { "Content-Type": mime } }, |                 { headers: { "Content-Type": mime } }, | ||||||
|             ), |             ), | ||||||
|         ); |         ); | ||||||
| @ -117,3 +140,22 @@ async function preload({ urls, cache, cleanup }) { | |||||||
|         }; |         }; | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function base128Decode(s) { // encoder is in server/ctrl/static.go -> encodeB128 | ||||||
|  |     const out = new Uint8Array(Math.floor((s.length * 7) / 8) + 1); | ||||||
|  |     let acc = 0; | ||||||
|  |     let bits = 0; | ||||||
|  |     let oi = 0; | ||||||
|  |     for (let i = 0; i < s.length; i++) { | ||||||
|  |         const ch = s.charCodeAt(i); | ||||||
|  |         const digit = ch & 0x7F; // undo 0x80 masking for NUL/LF/CR | ||||||
|  |         acc = (acc << 7) | digit; | ||||||
|  |         bits += 7; | ||||||
|  |         while (bits >= 8) { | ||||||
|  |             bits -= 8; | ||||||
|  |             out[oi++] = (acc >> bits) & 0xFF; | ||||||
|  |             acc &= (1 << bits) - 1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return out.subarray(0, oi); | ||||||
|  | } | ||||||
|  | |||||||
| @ -57,7 +57,12 @@ | |||||||
|                              resolve(); |                              resolve(); | ||||||
|                          }); |                          }); | ||||||
|                  }); |                  }); | ||||||
|                  register.active.postMessage({ "type": "preload", "payload": URLS }); |                  register.active.postMessage({ | ||||||
|  |                      "type": "preload", | ||||||
|  |                      "payload": URLS, | ||||||
|  |                      "version": "{{ .version }}".substring(0, 7) + "::{{ .hash }}", | ||||||
|  |                      "clear": {{ .clear }}, | ||||||
|  |                  }); | ||||||
|                  await new Promise((resolve, reject) => navigator.serviceWorker.addEventListener("message", (event) => { |                  await new Promise((resolve, reject) => navigator.serviceWorker.addEventListener("message", (event) => { | ||||||
|                      if (event.data && event.data.type === "preload") { |                      if (event.data && event.data.type === "preload") { | ||||||
|                          if (event.data.status !== "ok") console.log(`turboload failure data=${JSON.stringify(event.data)}`); |                          if (event.data.status !== "ok") console.log(`turboload failure data=${JSON.stringify(event.data)}`); | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ func PluginExportHandler(ctx *App, res http.ResponseWriter, req *http.Request) { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	SendSuccessResult(res, plgExports) | 	SendSuccessResultWithEtagAndGzip(res, req, plgExports) | ||||||
| } | } | ||||||
|  |  | ||||||
| func PluginStaticHandler(ctx *App, res http.ResponseWriter, req *http.Request) { | func PluginStaticHandler(ctx *App, res http.ResponseWriter, req *http.Request) { | ||||||
|  | |||||||
| @ -2,8 +2,8 @@ package ctrl | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
|  | 	"compress/gzip" | ||||||
| 	_ "embed" | 	_ "embed" | ||||||
| 	"encoding/base64" |  | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| @ -205,32 +205,42 @@ func ServeFile(chroot string) func(*App, http.ResponseWriter, *http.Request) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func ServeIndex(indexPath string) func(*App, http.ResponseWriter, *http.Request) { | func ServeIndex(indexPath string) func(*App, http.ResponseWriter, *http.Request) { | ||||||
|  | 	// STEP1: pull the data from the embed | ||||||
|  | 	file, err := WWWPublic.Open(indexPath) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return func(ctx *App, res http.ResponseWriter, req *http.Request) { | ||||||
|  | 			http.NotFound(res, req) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	defer file.Close() | ||||||
|  |  | ||||||
|  | 	// STEP2: compile the template | ||||||
|  | 	b, err := io.ReadAll(file) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return func(ctx *App, res http.ResponseWriter, req *http.Request) { | ||||||
|  | 			SendErrorResult(res, err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	tmpl := template.Must(template.New(indexPath).Parse(string(b))) | ||||||
|  | 	tmpl = template.Must(tmpl.Parse(string(TmplLoader))) | ||||||
|  |  | ||||||
| 	return func(ctx *App, res http.ResponseWriter, req *http.Request) { | 	return func(ctx *App, res http.ResponseWriter, req *http.Request) { | ||||||
| 		head := res.Header() | 		head := res.Header() | ||||||
|  | 		var out io.Writer = res | ||||||
| 		// STEP1: pull the data from the embed | 		if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") { | ||||||
| 		file, err := WWWPublic.Open(indexPath) | 			head.Set("Content-Encoding", "gzip") | ||||||
| 		if err != nil { | 			gz := gzip.NewWriter(res) | ||||||
| 			http.NotFound(res, req) | 			defer gz.Close() | ||||||
| 			return | 			out = gz | ||||||
| 		} |  | ||||||
| 		defer file.Close() |  | ||||||
|  |  | ||||||
| 		// STEP2: compile the template |  | ||||||
| 		b, err := io.ReadAll(file) |  | ||||||
| 		if err != nil { |  | ||||||
| 			SendErrorResult(res, err) |  | ||||||
| 			return |  | ||||||
| 		} | 		} | ||||||
| 		head.Set("Content-Type", "text/html") | 		head.Set("Content-Type", "text/html") | ||||||
| 		res.WriteHeader(http.StatusOK) | 		tmpl.Execute(out, map[string]any{ | ||||||
| 		tmpl := template.Must(template.New(indexPath).Parse(string(b))) |  | ||||||
| 		tmpl = template.Must(tmpl.Parse(string(TmplLoader))) |  | ||||||
| 		tmpl.Execute(res, map[string]any{ |  | ||||||
| 			"base":    WithBase("/"), | 			"base":    WithBase("/"), | ||||||
| 			"version": BUILD_REF, | 			"version": BUILD_REF, | ||||||
| 			"license": LICENSE, | 			"license": LICENSE, | ||||||
| 			"preload": preload(), | 			"preload": preload(), | ||||||
|  | 			"clear":   req.Header.Get("Cache-Control") == "no-cache", | ||||||
|  | 			"hash":    signature(), | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -265,7 +275,7 @@ func ServeBundle(ctx *App, res http.ResponseWriter, req *http.Request) { | |||||||
| 		fmt.Fprintf(res, "id: %s\n", urls[i]) | 		fmt.Fprintf(res, "id: %s\n", urls[i]) | ||||||
| 		fmt.Fprintf(res, "data: ") | 		fmt.Fprintf(res, "data: ") | ||||||
| 		b, _ := io.ReadAll(file) | 		b, _ := io.ReadAll(file) | ||||||
| 		res.Write([]byte(base64.StdEncoding.EncodeToString(b))) | 		res.Write([]byte(encodeB128(b))) | ||||||
| 		fmt.Fprintf(res, "\n\n") | 		fmt.Fprintf(res, "\n\n") | ||||||
| 		res.(http.Flusher).Flush() | 		res.(http.Flusher).Flush() | ||||||
| 		file.Close() | 		file.Close() | ||||||
| @ -274,6 +284,34 @@ func ServeBundle(ctx *App, res http.ResponseWriter, req *http.Request) { | |||||||
| 	res.(http.Flusher).Flush() | 	res.(http.Flusher).Flush() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func encodeB128(src []byte) string { // decoder is in public/assets/sw.js | ||||||
|  | 	if len(src) == 0 { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	out := make([]rune, 0, len(src)+len(src)/7) // N + N/7 runes (+tail) | ||||||
|  | 	var bits uint32 | ||||||
|  | 	var n int // bits held in 'bits' | ||||||
|  | 	emit := func(d byte) { | ||||||
|  | 		if d == 0x00 || d == 0x0A || d == 0x0D { // NUL, LF, CR | ||||||
|  | 			out = append(out, rune(0x80|d)) // 2-byte UTF-8, still decodable as d&0x7F | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		out = append(out, rune(d)) // ASCII, 1-byte UTF-8 | ||||||
|  | 	} | ||||||
|  | 	for _, b := range src { | ||||||
|  | 		bits = (bits << 8) | uint32(b) | ||||||
|  | 		n += 8 | ||||||
|  | 		for n >= 7 { | ||||||
|  | 			n -= 7 | ||||||
|  | 			emit(byte((bits >> n) & 0x7F)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if n > 0 { // tail | ||||||
|  | 		emit(byte((bits << (7 - n)) & 0x7F)) | ||||||
|  | 	} | ||||||
|  | 	return string(out) | ||||||
|  | } | ||||||
|  |  | ||||||
| func applyPatch(filePath string) (file *bytes.Buffer) { | func applyPatch(filePath string) (file *bytes.Buffer) { | ||||||
| 	var ( | 	var ( | ||||||
| 		outputBuffer bytes.Buffer | 		outputBuffer bytes.Buffer | ||||||
| @ -329,10 +367,7 @@ func preload() string { | |||||||
| 			"/assets/" + BUILD_REF + "/lib/vendor/rxjs/rxjs.min.js", | 			"/assets/" + BUILD_REF + "/lib/vendor/rxjs/rxjs.min.js", | ||||||
| 			"/assets/" + BUILD_REF + "/lib/vendor/rxjs/rxjs-ajax.min.js", | 			"/assets/" + BUILD_REF + "/lib/vendor/rxjs/rxjs-ajax.min.js", | ||||||
| 			"/assets/" + BUILD_REF + "/lib/vendor/rxjs/rxjs-shared.min.js", | 			"/assets/" + BUILD_REF + "/lib/vendor/rxjs/rxjs-shared.min.js", | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			"/assets/" + BUILD_REF + "/boot/ctrl_boot_frontoffice.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/locales/index.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/css/designsystem.css", | 			"/assets/" + BUILD_REF + "/css/designsystem.css", | ||||||
| 			"/assets/" + BUILD_REF + "/css/designsystem_input.css", | 			"/assets/" + BUILD_REF + "/css/designsystem_input.css", | ||||||
| 			"/assets/" + BUILD_REF + "/css/designsystem_textarea.css", | 			"/assets/" + BUILD_REF + "/css/designsystem_textarea.css", | ||||||
| @ -348,13 +383,50 @@ func preload() string { | |||||||
| 			"/assets/" + BUILD_REF + "/css/designsystem_skeleton.css", | 			"/assets/" + BUILD_REF + "/css/designsystem_skeleton.css", | ||||||
| 			"/assets/" + BUILD_REF + "/css/designsystem_utils.css", | 			"/assets/" + BUILD_REF + "/css/designsystem_utils.css", | ||||||
| 			"/assets/" + BUILD_REF + "/css/designsystem_alert.css", | 			"/assets/" + BUILD_REF + "/css/designsystem_alert.css", | ||||||
|  |  | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/modal.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_submenu.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/modal_share.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_filesystem.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/ctrl_filespage.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_form.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/viewerpage/component_menubar.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_upload.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/components/decorator_shell_filemanager.css", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"/assets/" + BUILD_REF + "/boot/ctrl_boot_frontoffice.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/boot/router_frontoffice.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/boot/common.js", | ||||||
| 			"/assets/" + BUILD_REF + "/components/loader.js", | 			"/assets/" + BUILD_REF + "/components/loader.js", | ||||||
| 			"/assets/" + BUILD_REF + "/components/modal.js", | 			"/assets/" + BUILD_REF + "/components/modal.js", | ||||||
| 			"/assets/" + BUILD_REF + "/components/modal.css", | 			"/assets/" + BUILD_REF + "/components/modal.css", | ||||||
| 			"/assets/" + BUILD_REF + "/components/notification.js", | 			"/assets/" + BUILD_REF + "/components/notification.js", | ||||||
| 			"/assets/" + BUILD_REF + "/components/notification.css", | 			"/assets/" + BUILD_REF + "/components/notification.css", | ||||||
| 			"/assets/" + BUILD_REF + "/boot/router_frontoffice.js", | 			"/assets/" + BUILD_REF + "/components/sidebar.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/components/sidebar.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/components/dropdown.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/components/decorator_shell_filemanager.js", | ||||||
| 			"/assets/" + BUILD_REF + "/helpers/loader.js", | 			"/assets/" + BUILD_REF + "/helpers/loader.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/helpers/log.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/helpers/sdk.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/locales/index.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/lib/store.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/lib/form.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/lib/path.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/lib/random.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/model/config.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/model/chromecast.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/model/session.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/model_acl.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/cache.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/thing.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/viewerpage/component_menubar.js", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"/assets/" + BUILD_REF + "/components/form.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/components/icon.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/lib/settings.js", | ||||||
| 			"/assets/" + BUILD_REF + "/lib/skeleton/index.js", | 			"/assets/" + BUILD_REF + "/lib/skeleton/index.js", | ||||||
| 			"/assets/" + BUILD_REF + "/lib/rx.js", | 			"/assets/" + BUILD_REF + "/lib/rx.js", | ||||||
| 			"/assets/" + BUILD_REF + "/lib/ajax.js", | 			"/assets/" + BUILD_REF + "/lib/ajax.js", | ||||||
| @ -364,80 +436,63 @@ func preload() string { | |||||||
| 			"/assets/" + BUILD_REF + "/lib/skeleton/router.js", | 			"/assets/" + BUILD_REF + "/lib/skeleton/router.js", | ||||||
| 			"/assets/" + BUILD_REF + "/lib/skeleton/lifecycle.js", | 			"/assets/" + BUILD_REF + "/lib/skeleton/lifecycle.js", | ||||||
| 			"/assets/" + BUILD_REF + "/lib/error.js", | 			"/assets/" + BUILD_REF + "/lib/error.js", | ||||||
| 			"/assets/" + BUILD_REF + "/model/config.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/model/plugin.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/model/chromecast.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/model/session.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/helpers/log.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/boot/common.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/helpers/sdk.js", |  | ||||||
|  |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/breadcrumb.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/breadcrumb.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/form.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/sidebar.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/sidebar.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/dropdown.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/icon.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/lib/store.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/lib/random.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/lib/form.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/lib/path.js", |  | ||||||
|  |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/decorator_shell_filemanager.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/decorator_shell_filemanager.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/ctrl_error.js", |  | ||||||
| 		}, |  | ||||||
| 		{ |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/ctrl_connectpage.js", | 			"/assets/" + BUILD_REF + "/pages/ctrl_connectpage.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/ctrl_connectpage.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/ctrl_error.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/ctrl_filespage.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/ctrl_viewerpage.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/ctrl_viewerpage.css", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/ctrl_logout.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_form.js", | 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_form.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_forkme.js", | 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_forkme.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_poweredby.js", | 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_poweredby.js", | ||||||
| 			"/assets/" + BUILD_REF + "/lib/path.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/lib/form.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/lib/settings.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/components/form.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/model/session.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/ctrl_error.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/connectpage/model_backend.js", | 			"/assets/" + BUILD_REF + "/pages/connectpage/model_backend.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/connectpage/model_config.js", | 			"/assets/" + BUILD_REF + "/pages/connectpage/model_config.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_form_state.js", | 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_form_state.js", | ||||||
| 			"/assets/" + BUILD_REF + "/lib/random.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_filesystem.js", | ||||||
| 			"/assets/" + BUILD_REF + "/components/icon.js", |  | ||||||
|  |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/ctrl_connectpage.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/connectpage/ctrl_form.css", |  | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			"/assets/" + BUILD_REF + "/pages/ctrl_filespage.js", | 			"/assets/" + BUILD_REF + "/components/breadcrumb.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/ctrl_filespage.css", | 			"/assets/" + BUILD_REF + "/components/breadcrumb.css", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_filesystem.js", | 			"/assets/" + BUILD_REF + "/components/skeleton.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_submenu.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_newitem.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_upload.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_upload.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/cache.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/state_config.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/state_config.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/thing.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/state_newthing.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/helper.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/helper.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/model_files.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/model_files.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/model_virtual_layer.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/model_virtual_layer.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/modal_share.js", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/modal_tag.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/modal_tag.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/modal_tag.css", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/modal_rename.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/modal_rename.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/modal_delete.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/modal_delete.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/state_selection.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/state_selection.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/model_acl.js", | 			"/assets/" + BUILD_REF + "/pages/filespage/state_newthing.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_newitem.js", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_filesystem.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/thing.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/modal.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_submenu.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/modal_share.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/modal_tag.css", |  | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_newitem.css", | 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_newitem.css", | ||||||
| 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_upload.css", | 			"/assets/" + BUILD_REF + "/pages/viewerpage/mimetype.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/viewerpage/model_files.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/viewerpage/common.js", | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/ctrl_submenu.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/thing.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/filespage/modal_share.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/pages/viewerpage/application_downloader.js", | ||||||
|  | 			"/assets/" + BUILD_REF + "/model/plugin.js", | ||||||
| 		}, | 		}, | ||||||
| 	}) | 	}) | ||||||
| 	return string(out) | 	return string(out) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func signature() string { | ||||||
|  | 	text := BUILD_REF | ||||||
|  | 	patches := Hooks.Get.StaticPatch() | ||||||
|  | 	for i := 0; i < len(patches); i++ { | ||||||
|  | 		text += string(patches[i]) | ||||||
|  | 	} | ||||||
|  | 	entries, _ := os.ReadDir(GetAbsolutePath(PLUGIN_PATH)) | ||||||
|  | 	for _, e := range entries { | ||||||
|  | 		stat, _ := e.Info() | ||||||
|  | 		text += fmt.Sprintf("[%s][%d][%s]", stat.Name(), stat.Size(), stat.ModTime().String()) | ||||||
|  | 	} | ||||||
|  | 	return strings.ToLower(QuickHash(text, 3)) | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 MickaelK
					MickaelK