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