mirror of
https://github.com/filebrowser/filebrowser.git
synced 2024-06-07 23:00:43 +00:00
refactor: migrate frontend tooling to vite 4 (#2645)
--------- Co-authored-by: Oleg Lobanov <oleg@lobanov.me>
This commit is contained in:
parent
184b7c14f2
commit
8838a09cf5
3
.gitignore
vendored
3
.gitignore
vendored
@ -29,3 +29,6 @@ yarn-error.log*
|
||||
*.sw*
|
||||
bin/
|
||||
build/
|
||||
|
||||
/frontend/dist/*
|
||||
!/frontend/dist/.gitkeep
|
||||
|
20
frontend/.eslintrc.json
Normal file
20
frontend/.eslintrc.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended",
|
||||
"@vue/eslint-config-prettier"
|
||||
],
|
||||
"rules": {
|
||||
"vue/multi-word-component-names": "off",
|
||||
"vue/no-reserved-component-names": "warn",
|
||||
"vue/no-mutating-props": "warn"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
}
|
||||
}
|
3
frontend/.prettierrc.json
Normal file
3
frontend/.prettierrc.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"trailingComma": "es5"
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
presets: ["@vue/app"],
|
||||
};
|
4
frontend/dist/.gitignore
vendored
4
frontend/dist/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
0
frontend/dist/.gitkeep
vendored
Normal file
0
frontend/dist/.gitkeep
vendored
Normal file
192
frontend/index.html
Normal file
192
frontend/index.html
Normal file
@ -0,0 +1,192 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, user-scalable=no"
|
||||
/>
|
||||
|
||||
<title>File Browser</title>
|
||||
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/img/icons/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/img/icons/favicon-16x16.png"
|
||||
/>
|
||||
|
||||
<!-- Add to home screen for Android and modern mobile browsers -->
|
||||
<link
|
||||
rel="manifest"
|
||||
id="manifestPlaceholder"
|
||||
crossorigin="use-credentials"
|
||||
/>
|
||||
<meta name="theme-color" content="#2979ff" />
|
||||
|
||||
<!-- Add to home screen for Safari on iOS/iPadOS -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||
<meta name="apple-mobile-web-app-title" content="assets" />
|
||||
<link rel="apple-touch-icon" href="/img/icons/apple-touch-icon.png" />
|
||||
|
||||
<!-- Add to home screen for Windows -->
|
||||
<meta
|
||||
name="msapplication-TileImage"
|
||||
content="/img/icons/mstile-144x144.png"
|
||||
/>
|
||||
<meta name="msapplication-TileColor" content="#2979ff" />
|
||||
|
||||
<!-- Inject Some Variables and generate the manifest json -->
|
||||
<script>
|
||||
// We can assign JSON directly
|
||||
window.FileBrowser = {
|
||||
AuthMethod: "json",
|
||||
BaseURL: "",
|
||||
CSS: false,
|
||||
Color: "",
|
||||
DisableExternal: false,
|
||||
DisableUsedPercentage: false,
|
||||
EnableExec: true,
|
||||
EnableThumbs: true,
|
||||
LoginPage: true,
|
||||
Name: "",
|
||||
NoAuth: false,
|
||||
ReCaptcha: false,
|
||||
ResizePreview: true,
|
||||
Signup: false,
|
||||
StaticURL: "",
|
||||
Theme: "",
|
||||
TusSettings: { chunkSize: 10485760, retryCount: 5 },
|
||||
Version: "(untracked)",
|
||||
};
|
||||
// Global function to prepend static url
|
||||
window.__prependStaticUrl = (url) => {
|
||||
return `${window.FileBrowser.StaticURL}/${url.replace(/^\/+/, "")}`;
|
||||
};
|
||||
var dynamicManifest = {
|
||||
name: window.FileBrowser.Name || "File Browser",
|
||||
short_name: window.FileBrowser.Name || "File Browser",
|
||||
icons: [
|
||||
{
|
||||
src: window.__prependStaticUrl(
|
||||
"/img/icons/android-chrome-192x192.png"
|
||||
),
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: window.__prependStaticUrl(
|
||||
"/img/icons/android-chrome-512x512.png"
|
||||
),
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
},
|
||||
],
|
||||
start_url: window.location.origin + window.FileBrowser.BaseURL,
|
||||
display: "standalone",
|
||||
background_color: "#ffffff",
|
||||
theme_color: window.FileBrowser.Color || "#455a64",
|
||||
};
|
||||
|
||||
const stringManifest = JSON.stringify(dynamicManifest);
|
||||
const blob = new Blob([stringManifest], { type: "application/json" });
|
||||
const manifestURL = URL.createObjectURL(blob);
|
||||
document
|
||||
.querySelector("#manifestPlaceholder")
|
||||
.setAttribute("href", manifestURL);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#loading {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
z-index: 9999;
|
||||
transition: 0.1s ease opacity;
|
||||
-webkit-transition: 0.1s ease opacity;
|
||||
}
|
||||
|
||||
#loading.done {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#loading .spinner {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
#loading .spinner > div {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-color: #333;
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
-webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
}
|
||||
|
||||
#loading .spinner .bounce1 {
|
||||
-webkit-animation-delay: -0.32s;
|
||||
animation-delay: -0.32s;
|
||||
}
|
||||
|
||||
#loading .spinner .bounce2 {
|
||||
-webkit-animation-delay: -0.16s;
|
||||
animation-delay: -0.16s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-bouncedelay {
|
||||
0%,
|
||||
80%,
|
||||
100% {
|
||||
-webkit-transform: scale(0);
|
||||
}
|
||||
40% {
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-bouncedelay {
|
||||
0%,
|
||||
80%,
|
||||
100% {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
}
|
||||
40% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
<div id="loading">
|
||||
<div class="spinner">
|
||||
<div class="bounce1"></div>
|
||||
<div class="bounce2"></div>
|
||||
<div class="bounce3"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
10
frontend/jsconfig.json
Normal file
10
frontend/jsconfig.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
29108
frontend/package-lock.json
generated
29108
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -2,71 +2,58 @@
|
||||
"name": "filebrowser-frontend",
|
||||
"version": "2.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitignore' -exec rm -r {} + && vue-cli-service build --no-clean",
|
||||
"lint": "npx vue-cli-service lint --no-fix --max-warnings=0",
|
||||
"fix": "npx vue-cli-service lint",
|
||||
"watch": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitignore' -exec rm -r {} + && vue-cli-service build --watch --no-clean"
|
||||
"dev": "vite dev",
|
||||
"serve": "vite serve",
|
||||
"build": "vite build",
|
||||
"watch": "vite build --watch",
|
||||
"clean": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitkeep' -exec rm -r {} +",
|
||||
"lint": "eslint --ext .vue,.js src/",
|
||||
"lint:fix": "eslint --ext .vue,.js --fix src/",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"dependencies": {
|
||||
"ace-builds": "^1.4.7",
|
||||
"clipboard": "^2.0.4",
|
||||
"core-js": "^3.9.1",
|
||||
"css-vars-ponyfill": "^2.4.3",
|
||||
"js-base64": "^2.5.1",
|
||||
"ace-builds": "^1.23.4",
|
||||
"clipboard": "^2.0.11",
|
||||
"core-js": "^3.32.0",
|
||||
"css-vars-ponyfill": "^2.4.8",
|
||||
"filesize": "^10.0.8",
|
||||
"js-base64": "^3.7.5",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"material-icons": "^1.10.5",
|
||||
"material-icons": "^1.13.9",
|
||||
"moment": "^2.29.4",
|
||||
"normalize.css": "^8.0.1",
|
||||
"noty": "^3.2.0-beta",
|
||||
"pretty-bytes": "^6.0.0",
|
||||
"pretty-bytes": "^6.1.1",
|
||||
"qrcode.vue": "^1.7.0",
|
||||
"tus-js-client": "^3.1.0",
|
||||
"tus-js-client": "^3.1.1",
|
||||
"utif": "^3.1.0",
|
||||
"vue": "^2.6.10",
|
||||
"vue": "^2.7.14",
|
||||
"vue-async-computed": "^3.9.0",
|
||||
"vue-i18n": "^8.15.3",
|
||||
"vue-lazyload": "^1.3.3",
|
||||
"vue-router": "^3.1.3",
|
||||
"vue-i18n": "^8.28.2",
|
||||
"vue-lazyload": "^1.3.5",
|
||||
"vue-router": "^3.6.5",
|
||||
"vue-simple-progress": "^1.1.1",
|
||||
"vuex": "^3.1.2",
|
||||
"vuex": "^3.6.2",
|
||||
"vuex-router-sync": "^5.0.0",
|
||||
"whatwg-fetch": "^3.6.2"
|
||||
"whatwg-fetch": "^3.6.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^4.1.2",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-service": "^4.1.2",
|
||||
"@vue/eslint-config-prettier": "^6.0.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"compression-webpack-plugin": "^6.0.3",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
"prettier": "^2.2.1",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended",
|
||||
"@vue/prettier"
|
||||
],
|
||||
"rules": {},
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
"autoprefixer": {}
|
||||
}
|
||||
"@vitejs/plugin-legacy": "^4.1.1",
|
||||
"@vitejs/plugin-vue2": "^2.2.0",
|
||||
"@vue/eslint-config-prettier": "^8.0.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "^8.46.0",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"eslint-plugin-vue": "^9.16.1",
|
||||
"jsdom": "^22.1.0",
|
||||
"postcss": "^8.4.27",
|
||||
"prettier": "^3.0.1",
|
||||
"terser": "^5.19.2",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-compression2": "^0.10.3"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
|
5
frontend/postcss.config.cjs
Normal file
5
frontend/postcss.config.cjs
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
0
frontend/public/.gitkeep
Normal file
0
frontend/public/.gitkeep
Normal file
@ -1,144 +1,193 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, user-scalable=no"
|
||||
/>
|
||||
|
||||
[{[ if .ReCaptcha -]}]
|
||||
[{[ if .ReCaptcha -]}]
|
||||
<script src="[{[ .ReCaptchaHost ]}]/recaptcha/api.js?render=explicit"></script>
|
||||
[{[ end ]}]
|
||||
[{[ end ]}]
|
||||
|
||||
<title>[{[ if .Name -]}][{[ .Name ]}][{[ else ]}]File Browser[{[ end ]}]</title>
|
||||
<title>
|
||||
[{[ if .Name -]}][{[ .Name ]}][{[ else ]}]File Browser[{[ end ]}]
|
||||
</title>
|
||||
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="[{[ .StaticURL ]}]/img/icons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="[{[ .StaticURL ]}]/img/icons/favicon-16x16.png">
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="[{[ .StaticURL ]}]/img/icons/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="[{[ .StaticURL ]}]/img/icons/favicon-16x16.png"
|
||||
/>
|
||||
|
||||
<!-- Add to home screen for Android and modern mobile browsers -->
|
||||
<link rel="manifest" id="manifestPlaceholder" crossorigin="use-credentials">
|
||||
<meta name="theme-color" content="[{[ if .Color -]}][{[ .Color ]}][{[ else ]}]#2979ff[{[ end ]}]">
|
||||
<!-- Add to home screen for Android and modern mobile browsers -->
|
||||
<link
|
||||
rel="manifest"
|
||||
id="manifestPlaceholder"
|
||||
crossorigin="use-credentials"
|
||||
/>
|
||||
<meta
|
||||
name="theme-color"
|
||||
content="[{[ if .Color -]}][{[ .Color ]}][{[ else ]}]#2979ff[{[ end ]}]"
|
||||
/>
|
||||
|
||||
<!-- Add to home screen for Safari on iOS/iPadOS -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="assets">
|
||||
<link rel="apple-touch-icon" href="[{[ .StaticURL ]}]/img/icons/apple-touch-icon.png">
|
||||
<!-- Add to home screen for Safari on iOS/iPadOS -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||
<meta name="apple-mobile-web-app-title" content="assets" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
href="[{[ .StaticURL ]}]/img/icons/apple-touch-icon.png"
|
||||
/>
|
||||
|
||||
<!-- Add to home screen for Windows -->
|
||||
<meta name="msapplication-TileImage" content="[{[ .StaticURL ]}]/img/icons/mstile-144x144.png">
|
||||
<meta name="msapplication-TileColor" content="[{[ if .Color -]}][{[ .Color ]}][{[ else ]}]#2979ff[{[ end ]}]">
|
||||
<!-- Add to home screen for Windows -->
|
||||
<meta
|
||||
name="msapplication-TileImage"
|
||||
content="[{[ .StaticURL ]}]/img/icons/mstile-144x144.png"
|
||||
/>
|
||||
<meta
|
||||
name="msapplication-TileColor"
|
||||
content="[{[ if .Color -]}][{[ .Color ]}][{[ else ]}]#2979ff[{[ end ]}]"
|
||||
/>
|
||||
|
||||
<!-- Inject Some Variables and generate the manifest json -->
|
||||
<script>
|
||||
window.FileBrowser = JSON.parse('[{[ .Json ]}]');
|
||||
<!-- Inject Some Variables and generate the manifest json -->
|
||||
<script>
|
||||
// We can assign JSON directly
|
||||
window.FileBrowser = [{[ .Json ]}];
|
||||
// Global function to prepend static url
|
||||
window.__prependStaticUrl = (url) => {
|
||||
return `${window.FileBrowser.StaticURL}/${url.replace(/^\/+/, "")}`;
|
||||
};
|
||||
var dynamicManifest = {
|
||||
name: window.FileBrowser.Name || "File Browser",
|
||||
short_name: window.FileBrowser.Name || "File Browser",
|
||||
icons: [
|
||||
{
|
||||
src: window.__prependStaticUrl("/img/icons/android-chrome-192x192.png"),
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
},
|
||||
{
|
||||
src: window.__prependStaticUrl("/img/icons/android-chrome-512x512.png"),
|
||||
sizes: "512x512",
|
||||
type: "image/png",
|
||||
},
|
||||
],
|
||||
start_url: window.location.origin + window.FileBrowser.BaseURL,
|
||||
display: "standalone",
|
||||
background_color: "#ffffff",
|
||||
theme_color: window.FileBrowser.Color || "#455a64",
|
||||
};
|
||||
|
||||
var fullStaticURL = window.location.origin + window.FileBrowser.StaticURL;
|
||||
var dynamicManifest = {
|
||||
"name": window.FileBrowser.Name || 'File Browser',
|
||||
"short_name": window.FileBrowser.Name || 'File Browser',
|
||||
"icons": [
|
||||
{
|
||||
"src": fullStaticURL + "/img/icons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": fullStaticURL + "/img/icons/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
const stringManifest = JSON.stringify(dynamicManifest);
|
||||
const blob = new Blob([stringManifest], { type: "application/json" });
|
||||
const manifestURL = URL.createObjectURL(blob);
|
||||
document
|
||||
.querySelector("#manifestPlaceholder")
|
||||
.setAttribute("href", manifestURL);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#loading {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
z-index: 9999;
|
||||
transition: 0.1s ease opacity;
|
||||
-webkit-transition: 0.1s ease opacity;
|
||||
}
|
||||
|
||||
#loading.done {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#loading .spinner {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
#loading .spinner > div {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-color: #333;
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
-webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
}
|
||||
|
||||
#loading .spinner .bounce1 {
|
||||
-webkit-animation-delay: -0.32s;
|
||||
animation-delay: -0.32s;
|
||||
}
|
||||
|
||||
#loading .spinner .bounce2 {
|
||||
-webkit-animation-delay: -0.16s;
|
||||
animation-delay: -0.16s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-bouncedelay {
|
||||
0%,
|
||||
80%,
|
||||
100% {
|
||||
-webkit-transform: scale(0);
|
||||
}
|
||||
],
|
||||
"start_url": window.location.origin + window.FileBrowser.BaseURL,
|
||||
"display": "standalone",
|
||||
"background_color": "#ffffff",
|
||||
"theme_color": window.FileBrowser.Color || "#455a64"
|
||||
}
|
||||
40% {
|
||||
-webkit-transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
const stringManifest = JSON.stringify(dynamicManifest);
|
||||
const blob = new Blob([stringManifest], {type: 'application/json'});
|
||||
const manifestURL = URL.createObjectURL(blob);
|
||||
document.querySelector('#manifestPlaceholder').setAttribute('href', manifestURL);
|
||||
</script>
|
||||
@keyframes sk-bouncedelay {
|
||||
0%,
|
||||
80%,
|
||||
100% {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
}
|
||||
40% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
<style>
|
||||
#loading {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
z-index: 9999;
|
||||
transition: .1s ease opacity;
|
||||
-webkit-transition: .1s ease opacity;
|
||||
}
|
||||
|
||||
#loading.done {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#loading .spinner {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
#loading .spinner > div {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-color: #333;
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
-webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
}
|
||||
|
||||
#loading .spinner .bounce1 {
|
||||
-webkit-animation-delay: -0.32s;
|
||||
animation-delay: -0.32s;
|
||||
}
|
||||
|
||||
#loading .spinner .bounce2 {
|
||||
-webkit-animation-delay: -0.16s;
|
||||
animation-delay: -0.16s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-bouncedelay {
|
||||
0%, 80%, 100% { -webkit-transform: scale(0) }
|
||||
40% { -webkit-transform: scale(1.0) }
|
||||
}
|
||||
|
||||
@keyframes sk-bouncedelay {
|
||||
0%, 80%, 100% {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
} 40% {
|
||||
-webkit-transform: scale(1.0);
|
||||
transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
<div id="loading">
|
||||
<div class="spinner">
|
||||
<div class="bounce1"></div>
|
||||
<div class="bounce2"></div>
|
||||
<div class="bounce3"></div>
|
||||
<div id="loading">
|
||||
<div class="spinner">
|
||||
<div class="bounce1"></div>
|
||||
<div class="bounce2"></div>
|
||||
<div class="bounce3"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
[{[ if .Theme -]}]
|
||||
<link rel="stylesheet" href="[{[ .StaticURL ]}]/themes/[{[ .Theme ]}].css" />
|
||||
[{[ end ]}]
|
||||
[{[ if .CSS -]}]
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
|
||||
[{[ if .Theme -]}]
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="[{[ .StaticURL ]}]/themes/[{[ .Theme ]}].css"
|
||||
/>
|
||||
[{[ end ]}] [{[ if .CSS -]}]
|
||||
<link rel="stylesheet" href="[{[ .StaticURL ]}]/custom.css" />
|
||||
[{[ end ]}]
|
||||
</body>
|
||||
[{[ end ]}]
|
||||
</body>
|
||||
</html>
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<script>
|
||||
// eslint-disable-next-line no-undef
|
||||
__webpack_public_path__ = window.FileBrowser.StaticURL + "/";
|
||||
// __webpack_public_path__ = window.FileBrowser.StaticURL + "/";
|
||||
|
||||
export default {
|
||||
name: "app",
|
||||
|
@ -10,12 +10,7 @@
|
||||
@mouseup="mouseUp"
|
||||
@wheel="wheelMove"
|
||||
>
|
||||
<img
|
||||
src=""
|
||||
class="image-ex-img image-ex-img-center"
|
||||
ref="imgex"
|
||||
@load="onLoad"
|
||||
/>
|
||||
<img class="image-ex-img image-ex-img-center" ref="imgex" @load="onLoad" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
@ -37,7 +37,7 @@
|
||||
<script>
|
||||
import { enableThumbs } from "@/utils/constants";
|
||||
import { mapMutations, mapGetters, mapState } from "vuex";
|
||||
import filesize from "filesize";
|
||||
import { filesize } from "filesize";
|
||||
import moment from "moment";
|
||||
import { files as api } from "@/api";
|
||||
import * as upload from "@/utils/upload";
|
||||
|
@ -34,7 +34,7 @@
|
||||
<script>
|
||||
import { logoURL } from "@/utils/constants";
|
||||
|
||||
import Action from "@/components/header/Action";
|
||||
import Action from "@/components/header/Action.vue";
|
||||
|
||||
export default {
|
||||
name: "header-bar",
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
import FileList from "./FileList";
|
||||
import FileList from "./FileList.vue";
|
||||
import { files as api } from "@/api";
|
||||
import buttons from "@/utils/buttons";
|
||||
import * as upload from "@/utils/upload";
|
||||
|
@ -81,7 +81,7 @@
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import filesize from "filesize";
|
||||
import { filesize } from "filesize";
|
||||
import moment from "moment";
|
||||
import { files as api } from "@/api";
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
import FileList from "./FileList";
|
||||
import FileList from "./FileList.vue";
|
||||
import { files as api } from "@/api";
|
||||
import buttons from "@/utils/buttons";
|
||||
import * as upload from "@/utils/upload";
|
||||
|
@ -6,20 +6,20 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Help from "./Help";
|
||||
import Info from "./Info";
|
||||
import Delete from "./Delete";
|
||||
import Rename from "./Rename";
|
||||
import Download from "./Download";
|
||||
import Move from "./Move";
|
||||
import Copy from "./Copy";
|
||||
import NewFile from "./NewFile";
|
||||
import NewDir from "./NewDir";
|
||||
import Replace from "./Replace";
|
||||
import ReplaceRename from "./ReplaceRename";
|
||||
import Share from "./Share";
|
||||
import Upload from "./Upload";
|
||||
import ShareDelete from "./ShareDelete";
|
||||
import Help from "./Help.vue";
|
||||
import Info from "./Info.vue";
|
||||
import Delete from "./Delete.vue";
|
||||
import Rename from "./Rename.vue";
|
||||
import Download from "./Download.vue";
|
||||
import Move from "./Move.vue";
|
||||
import Copy from "./Copy.vue";
|
||||
import NewFile from "./NewFile.vue";
|
||||
import NewDir from "./NewDir.vue";
|
||||
import Replace from "./Replace.vue";
|
||||
import ReplaceRename from "./ReplaceRename.vue";
|
||||
import Share from "./Share.vue";
|
||||
import Upload from "./Upload.vue";
|
||||
import ShareDelete from "./ShareDelete.vue";
|
||||
import { mapState } from "vuex";
|
||||
import buttons from "@/utils/buttons";
|
||||
|
||||
|
@ -67,10 +67,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Languages from "./Languages";
|
||||
import Rules from "./Rules";
|
||||
import Permissions from "./Permissions";
|
||||
import Commands from "./Commands";
|
||||
import Languages from "./Languages.vue";
|
||||
import Rules from "./Rules.vue";
|
||||
import Permissions from "./Permissions.vue";
|
||||
import Commands from "./Commands.vue";
|
||||
import { enableExec } from "@/utils/constants";
|
||||
|
||||
export default {
|
||||
|
@ -1,173 +1,242 @@
|
||||
@import "material-icons/iconfont/filled.css";
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto'), local('Roboto-Regular'), url(../assets/fonts/roboto/normal-cyrillic-ext.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto"),
|
||||
local("Roboto-Regular"),
|
||||
url(../assets/fonts/roboto/normal-cyrillic-ext.woff2) format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto'), local('Roboto-Regular'), url(../assets/fonts/roboto/normal-cyrillic.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto"),
|
||||
local("Roboto-Regular"),
|
||||
url(../assets/fonts/roboto/normal-cyrillic.woff2) format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto'), local('Roboto-Regular'), url(../assets/fonts/roboto/normal-greek-ext.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto"),
|
||||
local("Roboto-Regular"),
|
||||
url(../assets/fonts/roboto/normal-greek-ext.woff2) format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto'), local('Roboto-Regular'), url(../assets/fonts/roboto/normal-greek.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto"),
|
||||
local("Roboto-Regular"),
|
||||
url(../assets/fonts/roboto/normal-greek.woff2) format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto'), local('Roboto-Regular'), url(../assets/fonts/roboto/normal-vietnamese.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto"),
|
||||
local("Roboto-Regular"),
|
||||
url(../assets/fonts/roboto/normal-vietnamese.woff2) format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto'), local('Roboto-Regular'), url(../assets/fonts/roboto/normal-latin-ext.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
src:
|
||||
local("Roboto"),
|
||||
local("Roboto-Regular"),
|
||||
url(../assets/fonts/roboto/normal-latin-ext.woff2) format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Roboto'), local('Roboto-Regular'), url(../assets/fonts/roboto/normal-latin.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
src:
|
||||
local("Roboto"),
|
||||
local("Roboto-Regular"),
|
||||
url(../assets/fonts/roboto/normal-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../assets/fonts/roboto/medium-cyrillic-ext.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Medium"),
|
||||
local("Roboto-Medium"),
|
||||
url(../assets/fonts/roboto/medium-cyrillic-ext.woff2) format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../assets/fonts/roboto/medium-cyrillic.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Medium"),
|
||||
local("Roboto-Medium"),
|
||||
url(../assets/fonts/roboto/medium-cyrillic.woff2) format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../assets/fonts/roboto/medium-greek-ext.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Medium"),
|
||||
local("Roboto-Medium"),
|
||||
url(../assets/fonts/roboto/medium-greek-ext.woff2) format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../assets/fonts/roboto/medium-greek.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Medium"),
|
||||
local("Roboto-Medium"),
|
||||
url(../assets/fonts/roboto/medium-greek.woff2) format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../assets/fonts/roboto/medium-vietnamese.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Medium"),
|
||||
local("Roboto-Medium"),
|
||||
url(../assets/fonts/roboto/medium-vietnamese.woff2) format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../assets/fonts/roboto/medium-latin-ext.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
src:
|
||||
local("Roboto Medium"),
|
||||
local("Roboto-Medium"),
|
||||
url(../assets/fonts/roboto/medium-latin-ext.woff2) format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: local('Roboto Medium'), local('Roboto-Medium'), url(../assets/fonts/roboto/medium-latin.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
src:
|
||||
local("Roboto Medium"),
|
||||
local("Roboto-Medium"),
|
||||
url(../assets/fonts/roboto/medium-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../assets/fonts/roboto/bold-cyrillic-ext.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Bold"),
|
||||
local("Roboto-Bold"),
|
||||
url(../assets/fonts/roboto/bold-cyrillic-ext.woff2) format("woff2");
|
||||
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../assets/fonts/roboto/bold-cyrillic.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Bold"),
|
||||
local("Roboto-Bold"),
|
||||
url(../assets/fonts/roboto/bold-cyrillic.woff2) format("woff2");
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../assets/fonts/roboto/bold-greek-ext.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Bold"),
|
||||
local("Roboto-Bold"),
|
||||
url(../assets/fonts/roboto/bold-greek-ext.woff2) format("woff2");
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../assets/fonts/roboto/bold-greek.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Bold"),
|
||||
local("Roboto-Bold"),
|
||||
url(../assets/fonts/roboto/bold-greek.woff2) format("woff2");
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../assets/fonts/roboto/bold-vietnamese.woff2) format('woff2');
|
||||
src:
|
||||
local("Roboto Bold"),
|
||||
local("Roboto-Bold"),
|
||||
url(../assets/fonts/roboto/bold-vietnamese.woff2) format("woff2");
|
||||
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../assets/fonts/roboto/bold-latin-ext.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
src:
|
||||
local("Roboto Bold"),
|
||||
local("Roboto-Bold"),
|
||||
url(../assets/fonts/roboto/bold-latin-ext.woff2) format("woff2");
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F,
|
||||
U+A720-A7FF;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-family: "Roboto";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Roboto Bold'), local('Roboto-Bold'), url(../assets/fonts/roboto/bold-latin.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
src:
|
||||
local("Roboto Bold"),
|
||||
local("Roboto-Bold"),
|
||||
url(../assets/fonts/roboto/bold-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC,
|
||||
U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
@import '~material-icons/iconfont/filled.css';
|
||||
|
||||
.material-icons {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
@import "~normalize.css/normalize.css";
|
||||
@import "~noty/lib/noty.css";
|
||||
@import "~noty/lib/themes/mint.css";
|
||||
@import "normalize.css/normalize.css";
|
||||
@import "noty/lib/noty.css";
|
||||
@import "noty/lib/themes/mint.css";
|
||||
@import "./_variables.css";
|
||||
@import "./_buttons.css";
|
||||
@import "./_inputs.css";
|
||||
@ -14,6 +14,7 @@
|
||||
@import "./upload-files.css";
|
||||
@import "./dashboard.css";
|
||||
@import "./login.css";
|
||||
@import "./mobile.css";
|
||||
|
||||
.link {
|
||||
color: var(--blue);
|
||||
@ -27,9 +28,9 @@ main .spinner {
|
||||
}
|
||||
|
||||
main .spinner > div {
|
||||
width: .8em;
|
||||
height: .8em;
|
||||
margin: 0 .1em;
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
margin: 0 0.1em;
|
||||
font-size: 1em;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 100%;
|
||||
@ -71,7 +72,7 @@ main .spinner .bounce2 {
|
||||
transition: 0.2s ease all;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
color: #546E7A;
|
||||
color: #546e7a;
|
||||
border-radius: 50%;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
@ -88,12 +89,12 @@ main .spinner .bounce2 {
|
||||
|
||||
.action i {
|
||||
padding: 0.4em;
|
||||
transition: .1s ease-in-out all;
|
||||
transition: 0.1s ease-in-out all;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.action:hover {
|
||||
background-color: rgba(0, 0, 0, .1);
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.action ul {
|
||||
@ -109,8 +110,8 @@ main .spinner .bounce2 {
|
||||
|
||||
.action ul li {
|
||||
line-height: 1;
|
||||
padding: .7em;
|
||||
transition: .1s ease background-color;
|
||||
padding: 0.7em;
|
||||
transition: 0.1s ease background-color;
|
||||
}
|
||||
|
||||
.action ul li:hover {
|
||||
@ -139,7 +140,7 @@ main .spinner .bounce2 {
|
||||
background: var(--blue);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
font-size: .75em;
|
||||
font-size: 0.75em;
|
||||
width: 1.8em;
|
||||
height: 1.8em;
|
||||
text-align: center;
|
||||
@ -148,7 +149,6 @@ main .spinner .bounce2 {
|
||||
border: 2px solid white;
|
||||
}
|
||||
|
||||
|
||||
/* PREVIEWER */
|
||||
|
||||
#previewer {
|
||||
@ -179,7 +179,7 @@ main .spinner .bounce2 {
|
||||
}
|
||||
|
||||
#previewer header .action:hover {
|
||||
background-color: rgba(255, 255, 255, 0.3)
|
||||
background-color: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
#previewer header .action span {
|
||||
@ -220,14 +220,14 @@ main .spinner .bounce2 {
|
||||
}
|
||||
#previewer .preview .info .title i {
|
||||
display: block;
|
||||
margin-bottom: .1em;
|
||||
margin-bottom: 0.1em;
|
||||
font-size: 4em;
|
||||
}
|
||||
#previewer .preview .info .button {
|
||||
display: inline-block;
|
||||
}
|
||||
#previewer .preview .info .button:hover {
|
||||
background-color: rgba(255, 255, 255, 0.2)
|
||||
background-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
#previewer .preview .info .button i {
|
||||
display: block;
|
||||
@ -241,15 +241,15 @@ main .spinner .bounce2 {
|
||||
}
|
||||
|
||||
#previewer h2.message {
|
||||
color: rgba(255, 255, 255, 0.5)
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
#previewer>button {
|
||||
#previewer > button {
|
||||
margin: 0;
|
||||
position: fixed;
|
||||
top: calc(50% + 1.85em);
|
||||
transform: translateY(-50%);
|
||||
background-color: rgba(80, 80, 80, .5);
|
||||
background-color: rgba(80, 80, 80, 0.5);
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
@ -259,20 +259,20 @@ main .spinner .bounce2 {
|
||||
transition: 0.2s ease all;
|
||||
}
|
||||
|
||||
#previewer>button.hidden {
|
||||
#previewer > button.hidden {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#previewer>button>i {
|
||||
#previewer > button > i {
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
#previewer>button:first-of-type {
|
||||
#previewer > button:first-of-type {
|
||||
left: 0.5em;
|
||||
}
|
||||
|
||||
#previewer>button:last-of-type {
|
||||
#previewer > button:last-of-type {
|
||||
right: 0.5em;
|
||||
}
|
||||
|
||||
@ -321,7 +321,7 @@ body.rtl .breadcrumbs .chevron {
|
||||
}
|
||||
|
||||
#editor-container .breadcrumbs span {
|
||||
font-size: .75rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
#editor-container .breadcrumbs i {
|
||||
@ -339,7 +339,7 @@ body.rtl .breadcrumbs .chevron {
|
||||
|
||||
.noty_buttons button {
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid rgba(0,0,0,0.1);
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 0 0 0;
|
||||
font-size: 1rem;
|
||||
}
|
||||
@ -356,7 +356,7 @@ body.rtl .breadcrumbs .chevron {
|
||||
|
||||
.credits > span {
|
||||
display: block;
|
||||
margin: .3em 0;
|
||||
margin: 0.3em 0;
|
||||
}
|
||||
|
||||
.credits a,
|
||||
@ -365,7 +365,6 @@ body.rtl .breadcrumbs .chevron {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * *
|
||||
* ANIMATIONS *
|
||||
* * * * * * * * * * * * * * * */
|
||||
@ -393,20 +392,20 @@ body.rtl .breadcrumbs .chevron {
|
||||
.rules > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: .5rem 0;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
.rules input[type="checkbox"] {
|
||||
margin-right: .2rem;
|
||||
margin-right: 0.2rem;
|
||||
}
|
||||
|
||||
.rules input[type="text"] {
|
||||
border: 1px solid#ddd;
|
||||
padding: .2rem;
|
||||
padding: 0.2rem;
|
||||
}
|
||||
|
||||
.rules label {
|
||||
margin-right: .5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.rules button {
|
||||
@ -414,12 +413,10 @@ body.rtl .breadcrumbs .chevron {
|
||||
}
|
||||
|
||||
.rules button.delete {
|
||||
padding: .2rem .5rem;
|
||||
margin-left: .5rem;
|
||||
padding: 0.2rem 0.5rem;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
@import './mobile.css';
|
||||
|
||||
/* * * * * * * * * * * * * * * *
|
||||
* RTL overrides *
|
||||
* * * * * * * * * * * * * * * */
|
||||
|
@ -7,7 +7,7 @@ import i18n from "@/i18n";
|
||||
import Vue from "@/utils/vue";
|
||||
import { recaptcha, loginPage } from "@/utils/constants";
|
||||
import { login, validateLogin } from "@/utils/auth";
|
||||
import App from "@/App";
|
||||
import App from "@/App.vue";
|
||||
|
||||
cssVars();
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
import Vue from "vue";
|
||||
import Router from "vue-router";
|
||||
import Login from "@/views/Login";
|
||||
import Layout from "@/views/Layout";
|
||||
import Files from "@/views/Files";
|
||||
import Share from "@/views/Share";
|
||||
import Users from "@/views/settings/Users";
|
||||
import User from "@/views/settings/User";
|
||||
import Settings from "@/views/Settings";
|
||||
import GlobalSettings from "@/views/settings/Global";
|
||||
import ProfileSettings from "@/views/settings/Profile";
|
||||
import Shares from "@/views/settings/Shares";
|
||||
import Errors from "@/views/Errors";
|
||||
import Login from "@/views/Login.vue";
|
||||
import Layout from "@/views/Layout.vue";
|
||||
import Files from "@/views/Files.vue";
|
||||
import Share from "@/views/Share.vue";
|
||||
import Users from "@/views/settings/Users.vue";
|
||||
import User from "@/views/settings/User.vue";
|
||||
import Settings from "@/views/Settings.vue";
|
||||
import GlobalSettings from "@/views/settings/Global.vue";
|
||||
import ProfileSettings from "@/views/settings/Profile.vue";
|
||||
import Shares from "@/views/settings/Shares.vue";
|
||||
import Errors from "@/views/Errors.vue";
|
||||
import store from "@/store";
|
||||
import { baseURL, name } from "@/utils/constants";
|
||||
import i18n, { rtlLanguages } from "@/i18n";
|
||||
@ -33,7 +33,7 @@ const titles = {
|
||||
};
|
||||
|
||||
const router = new Router({
|
||||
base: baseURL,
|
||||
base: import.meta.env.PROD ? baseURL : "",
|
||||
mode: "history",
|
||||
routes: [
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
import store from "@/store";
|
||||
import router from "@/router";
|
||||
import { Base64 } from "js-base64";
|
||||
import { baseURL } from "@/utils/constants";
|
||||
import { fetchURL } from "@/api/utils";
|
||||
|
||||
export function parseToken(token) {
|
||||
const parts = token.split(".");
|
||||
@ -25,20 +25,24 @@ export async function validateLogin() {
|
||||
await renew(localStorage.getItem("jwt"));
|
||||
}
|
||||
} catch (_) {
|
||||
console.warn('Invalid JWT token in storage') // eslint-disable-line
|
||||
console.warn("Invalid JWT token in storage"); // eslint-disable-line
|
||||
}
|
||||
}
|
||||
|
||||
export async function login(username, password, recaptcha) {
|
||||
const data = { username, password, recaptcha };
|
||||
|
||||
const res = await fetch(`${baseURL}/api/login`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
const res = await fetchURL(
|
||||
`/api/login`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
false
|
||||
);
|
||||
|
||||
const body = await res.text();
|
||||
|
||||
@ -50,7 +54,7 @@ export async function login(username, password, recaptcha) {
|
||||
}
|
||||
|
||||
export async function renew(jwt) {
|
||||
const res = await fetch(`${baseURL}/api/renew`, {
|
||||
const res = await fetchURL(`/api/renew`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"X-Auth": jwt,
|
||||
@ -69,13 +73,17 @@ export async function renew(jwt) {
|
||||
export async function signup(username, password) {
|
||||
const data = { username, password };
|
||||
|
||||
const res = await fetch(`${baseURL}/api/signup`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
const res = await fetchURL(
|
||||
`/api/signup`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
false
|
||||
);
|
||||
|
||||
if (res.status !== 200) {
|
||||
throw new Error(res.status);
|
||||
|
@ -10,7 +10,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HeaderBar from "@/components/header/HeaderBar";
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
|
||||
const errors = {
|
||||
0: {
|
||||
|
@ -23,11 +23,11 @@
|
||||
import { files as api } from "@/api";
|
||||
import { mapState, mapMutations } from "vuex";
|
||||
|
||||
import HeaderBar from "@/components/header/HeaderBar";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs";
|
||||
import Errors from "@/views/Errors";
|
||||
import Preview from "@/views/files/Preview";
|
||||
import Listing from "@/views/files/Listing";
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import Errors from "@/views/Errors.vue";
|
||||
import Preview from "@/views/files/Preview.vue";
|
||||
import Listing from "@/views/files/Listing.vue";
|
||||
|
||||
function clean(path) {
|
||||
return path.endsWith("/") ? path.slice(0, -1) : path;
|
||||
@ -41,7 +41,7 @@ export default {
|
||||
Errors,
|
||||
Preview,
|
||||
Listing,
|
||||
Editor: () => import("@/views/files/Editor"),
|
||||
Editor: () => import("@/views/files/Editor.vue"),
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
|
@ -15,10 +15,10 @@
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters } from "vuex";
|
||||
import Sidebar from "@/components/Sidebar";
|
||||
import Prompts from "@/components/prompts/Prompts";
|
||||
import Shell from "@/components/Shell";
|
||||
import UploadFiles from "../components/prompts/UploadFiles";
|
||||
import Sidebar from "@/components/Sidebar.vue";
|
||||
import Prompts from "@/components/prompts/Prompts.vue";
|
||||
import Shell from "@/components/Shell.vue";
|
||||
import UploadFiles from "../components/prompts/UploadFiles.vue";
|
||||
import { enableExec } from "@/utils/constants";
|
||||
|
||||
export default {
|
||||
|
@ -52,7 +52,7 @@
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
|
||||
import HeaderBar from "@/components/header/HeaderBar";
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
|
||||
export default {
|
||||
name: "settings",
|
||||
|
@ -182,15 +182,15 @@
|
||||
<script>
|
||||
import { mapState, mapMutations, mapGetters } from "vuex";
|
||||
import { pub as api } from "@/api";
|
||||
import filesize from "filesize";
|
||||
import { filesize } from "filesize";
|
||||
import moment from "moment";
|
||||
|
||||
import HeaderBar from "@/components/header/HeaderBar";
|
||||
import Action from "@/components/header/Action";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs";
|
||||
import Errors from "@/views/Errors";
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
import Action from "@/components/header/Action.vue";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
import Errors from "@/views/Errors.vue";
|
||||
import QrcodeVue from "qrcode.vue";
|
||||
import Item from "@/components/files/ListingItem";
|
||||
import Item from "@/components/files/ListingItem.vue";
|
||||
import Clipboard from "clipboard";
|
||||
|
||||
export default {
|
||||
|
@ -26,13 +26,13 @@ import { theme } from "@/utils/constants";
|
||||
import buttons from "@/utils/buttons";
|
||||
import url from "@/utils/url";
|
||||
|
||||
import { version as ace_version } from "ace-builds";
|
||||
import ace from "ace-builds/src-min-noconflict/ace.js";
|
||||
import modelist from "ace-builds/src-min-noconflict/ext-modelist.js";
|
||||
import "ace-builds/webpack-resolver";
|
||||
|
||||
import HeaderBar from "@/components/header/HeaderBar";
|
||||
import Action from "@/components/header/Action";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs";
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
import Action from "@/components/header/Action.vue";
|
||||
import Breadcrumbs from "@/components/Breadcrumbs.vue";
|
||||
|
||||
export default {
|
||||
name: "editor",
|
||||
@ -86,6 +86,11 @@ export default {
|
||||
mounted: function () {
|
||||
const fileContent = this.req.content || "";
|
||||
|
||||
ace.config.set(
|
||||
"basePath",
|
||||
`https://cdn.jsdelivr.net/npm/ace-builds@${ace_version}/src-min-noconflict/`
|
||||
);
|
||||
|
||||
this.editor = ace.edit("editor", {
|
||||
value: fileContent,
|
||||
showPrintMargin: false,
|
||||
|
@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<header-bar showMenu showLogo>
|
||||
<search /> <title />
|
||||
<search />
|
||||
<title />
|
||||
<action
|
||||
class="search-button"
|
||||
icon="search"
|
||||
@ -274,10 +275,10 @@ import * as upload from "@/utils/upload";
|
||||
import css from "@/utils/css";
|
||||
import throttle from "lodash.throttle";
|
||||
|
||||
import HeaderBar from "@/components/header/HeaderBar";
|
||||
import Action from "@/components/header/Action";
|
||||
import Search from "@/components/Search";
|
||||
import Item from "@/components/files/ListingItem";
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
import Action from "@/components/header/Action.vue";
|
||||
import Search from "@/components/Search.vue";
|
||||
import Item from "@/components/files/ListingItem.vue";
|
||||
|
||||
export default {
|
||||
name: "listing",
|
||||
|
@ -148,9 +148,9 @@ import { files as api } from "@/api";
|
||||
import { resizePreview } from "@/utils/constants";
|
||||
import url from "@/utils/url";
|
||||
import throttle from "lodash.throttle";
|
||||
import HeaderBar from "@/components/header/HeaderBar";
|
||||
import Action from "@/components/header/Action";
|
||||
import ExtendedImage from "@/components/files/ExtendedImage";
|
||||
import HeaderBar from "@/components/header/HeaderBar.vue";
|
||||
import Action from "@/components/header/Action.vue";
|
||||
import ExtendedImage from "@/components/files/ExtendedImage.vue";
|
||||
|
||||
const mediaTypes = ["image", "video", "audio", "blob"];
|
||||
|
||||
|
@ -223,10 +223,10 @@
|
||||
import { mapState, mapMutations } from "vuex";
|
||||
import { settings as api } from "@/api";
|
||||
import { enableExec } from "@/utils/constants";
|
||||
import UserForm from "@/components/settings/UserForm";
|
||||
import Rules from "@/components/settings/Rules";
|
||||
import Themes from "@/components/settings/Themes";
|
||||
import Errors from "@/views/Errors";
|
||||
import UserForm from "@/components/settings/UserForm.vue";
|
||||
import Rules from "@/components/settings/Rules.vue";
|
||||
import Themes from "@/components/settings/Themes.vue";
|
||||
import Errors from "@/views/Errors.vue";
|
||||
|
||||
export default {
|
||||
name: "settings",
|
||||
|
@ -74,7 +74,7 @@
|
||||
<script>
|
||||
import { mapState, mapMutations } from "vuex";
|
||||
import { users as api } from "@/api";
|
||||
import Languages from "@/components/settings/Languages";
|
||||
import Languages from "@/components/settings/Languages.vue";
|
||||
import i18n, { rtlLanguages } from "@/i18n";
|
||||
|
||||
export default {
|
||||
|
@ -65,7 +65,7 @@ import { share as api, users } from "@/api";
|
||||
import { mapState, mapMutations } from "vuex";
|
||||
import moment from "moment";
|
||||
import Clipboard from "clipboard";
|
||||
import Errors from "@/views/Errors";
|
||||
import Errors from "@/views/Errors.vue";
|
||||
|
||||
export default {
|
||||
name: "shares",
|
||||
|
@ -63,8 +63,8 @@
|
||||
<script>
|
||||
import { mapState, mapMutations } from "vuex";
|
||||
import { users as api, settings } from "@/api";
|
||||
import UserForm from "@/components/settings/UserForm";
|
||||
import Errors from "@/views/Errors";
|
||||
import UserForm from "@/components/settings/UserForm.vue";
|
||||
import Errors from "@/views/Errors.vue";
|
||||
import deepClone from "lodash.clonedeep";
|
||||
|
||||
export default {
|
||||
|
@ -44,7 +44,7 @@
|
||||
<script>
|
||||
import { mapState, mapMutations } from "vuex";
|
||||
import { users as api } from "@/api";
|
||||
import Errors from "@/views/Errors";
|
||||
import Errors from "@/views/Errors.vue";
|
||||
|
||||
export default {
|
||||
name: "users",
|
||||
|
64
frontend/vite.config.js
Normal file
64
frontend/vite.config.js
Normal file
@ -0,0 +1,64 @@
|
||||
import { fileURLToPath, URL } from "node:url";
|
||||
|
||||
import { defineConfig } from "vite";
|
||||
import legacy from "@vitejs/plugin-legacy";
|
||||
import vue2 from "@vitejs/plugin-vue2";
|
||||
import { compression } from "vite-plugin-compression2";
|
||||
|
||||
const plugins = [
|
||||
vue2(),
|
||||
legacy({
|
||||
targets: ["ie >= 11"],
|
||||
additionalLegacyPolyfills: ["regenerator-runtime/runtime"],
|
||||
}),
|
||||
compression({ include: /\.js$/i, deleteOriginalAssets: true }),
|
||||
];
|
||||
|
||||
const resolve = {
|
||||
alias: {
|
||||
vue: "vue/dist/vue.esm.js",
|
||||
"@/": fileURLToPath(new URL("./src/", import.meta.url)),
|
||||
},
|
||||
};
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ command }) => {
|
||||
if (command === "serve") {
|
||||
return {
|
||||
plugins,
|
||||
resolve,
|
||||
server: {
|
||||
proxy: {
|
||||
"/api": "http://localhost:8080",
|
||||
},
|
||||
},
|
||||
};
|
||||
} else {
|
||||
// command === 'build'
|
||||
return {
|
||||
plugins,
|
||||
resolve,
|
||||
base: "",
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
index: fileURLToPath(
|
||||
new URL(`./public/index.html`, import.meta.url)
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
experimental: {
|
||||
renderBuiltUrl(filename, { hostType }) {
|
||||
if (hostType === "js") {
|
||||
return { runtime: `window.__prependStaticUrl("${filename}")` };
|
||||
} else if (hostType === "html") {
|
||||
return `[{[ .StaticURL ]}]/${filename}`;
|
||||
} else {
|
||||
return { relative: true };
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
});
|
@ -1,15 +0,0 @@
|
||||
const CompressionPlugin = require("compression-webpack-plugin");
|
||||
|
||||
module.exports = {
|
||||
runtimeCompiler: true,
|
||||
publicPath: "[{[ .StaticURL ]}]",
|
||||
parallel: 2,
|
||||
configureWebpack: {
|
||||
plugins: [
|
||||
new CompressionPlugin({
|
||||
include: /\.js$/,
|
||||
deleteOriginalAssets: true,
|
||||
}),
|
||||
],
|
||||
},
|
||||
};
|
@ -49,7 +49,9 @@ func (d *data) Check(path string) bool {
|
||||
|
||||
func handle(fn handleFunc, prefix string, store *storage.Storage, server *settings.Server) http.Handler {
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
for k, v := range globalHeaders {
|
||||
w.Header().Set(k, v)
|
||||
}
|
||||
|
||||
settings, err := store.Settings.Get()
|
||||
if err != nil {
|
||||
|
9
http/headers.go
Normal file
9
http/headers.go
Normal file
@ -0,0 +1,9 @@
|
||||
//go:build !dev
|
||||
// +build !dev
|
||||
|
||||
package http
|
||||
|
||||
// global headers to append to every response
|
||||
var globalHeaders = map[string]string{
|
||||
"Cache-Control": "no-cache, no-store, must-revalidate",
|
||||
}
|
15
http/headers_dev.go
Normal file
15
http/headers_dev.go
Normal file
@ -0,0 +1,15 @@
|
||||
//go:build dev
|
||||
// +build dev
|
||||
|
||||
package http
|
||||
|
||||
// global headers to append to every response
|
||||
// cross-origin headers are necessary to be able to
|
||||
// access them from a different URL during development
|
||||
var globalHeaders = map[string]string{
|
||||
"Cache-Control": "no-cache, no-store, must-revalidate",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
"Access-Control-Allow-Methods": "*",
|
||||
"Access-Control-Allow-Credentials": "true",
|
||||
}
|
@ -105,7 +105,7 @@ func getStaticHandlers(store *storage.Storage, server *settings.Server, assetsFs
|
||||
}
|
||||
|
||||
w.Header().Set("x-xss-protection", "1; mode=block")
|
||||
return handleWithStaticData(w, r, d, assetsFs, "index.html", "text/html; charset=utf-8")
|
||||
return handleWithStaticData(w, r, d, assetsFs, "public/index.html", "text/html; charset=utf-8")
|
||||
}, "", store, server)
|
||||
|
||||
static = handle(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||
|
Loading…
Reference in New Issue
Block a user