refactor: Fix eslint warnings (#3698)
* Update dependencies and remove typescript version pinning (fixed upstream) * Fix esling warnings (disabled any and script lang checks) Rewrote clipboard copy (Fixes #3407) Run prettier --------- Co-authored-by: Oleg Lobanov <oleg@lobanov.me>pull/3712/head
parent
cc331383fb
commit
0201f9c5c4
|
@ -1,2 +1,3 @@
|
||||||
# Ignore artifacts:
|
# Ignore artifacts:
|
||||||
dist
|
dist
|
||||||
|
pnpm-lock.yaml
|
|
@ -19,14 +19,13 @@ export default [
|
||||||
|
|
||||||
{
|
{
|
||||||
rules: {
|
rules: {
|
||||||
"no-var": "warn",
|
|
||||||
"prefer-const": "warn",
|
|
||||||
// Note: you must disable the base rule as it can report incorrect errors
|
// Note: you must disable the base rule as it can report incorrect errors
|
||||||
"no-unused-expressions": "off",
|
"no-unused-expressions": "off",
|
||||||
"@typescript-eslint/no-unused-expressions": "warn",
|
"@typescript-eslint/no-unused-expressions": "off",
|
||||||
"@typescript-eslint/no-explicit-any": "warn",
|
// TODO: theres too many of these from before ts
|
||||||
"@typescript-eslint/ban-ts-comment": "warn",
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
"vue/block-lang": "warn",
|
// TODO: finish the ts conversion
|
||||||
|
"vue/block-lang": "off",
|
||||||
"vue/multi-word-component-names": "off",
|
"vue/multi-word-component-names": "off",
|
||||||
"vue/no-mutating-props": [
|
"vue/no-mutating-props": [
|
||||||
"error",
|
"error",
|
||||||
|
|
|
@ -19,64 +19,59 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chenfengyuan/vue-number-input": "^2.0.1",
|
"@chenfengyuan/vue-number-input": "^2.0.1",
|
||||||
"@vueuse/core": "^12.0.0",
|
"@vueuse/core": "^12.5.0",
|
||||||
"@vueuse/integrations": "^12.0.0",
|
"@vueuse/integrations": "^12.5.0",
|
||||||
"ace-builds": "^1.32.9",
|
"ace-builds": "^1.37.5",
|
||||||
"core-js": "^3.36.1",
|
"core-js": "^3.40.0",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"epubjs": "^0.3.93",
|
"epubjs": "^0.3.93",
|
||||||
"filesize": "^10.1.1",
|
"filesize": "^10.1.1",
|
||||||
"js-base64": "^3.7.7",
|
"js-base64": "^3.7.7",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"marked": "^15.0.3",
|
"marked": "^15.0.6",
|
||||||
"material-icons": "^1.13.12",
|
"material-icons": "^1.13.13",
|
||||||
"normalize.css": "^8.0.1",
|
"normalize.css": "^8.0.1",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.3.1",
|
||||||
"pretty-bytes": "^6.1.1",
|
"pretty-bytes": "^6.1.1",
|
||||||
"qrcode.vue": "^3.4.1",
|
"qrcode.vue": "^3.4.1",
|
||||||
"tus-js-client": "^4.1.0",
|
"tus-js-client": "^4.3.1",
|
||||||
"utif": "^3.1.0",
|
"utif": "^3.1.0",
|
||||||
"video.js": "^8.10.0",
|
"video.js": "^8.21.0",
|
||||||
"videojs-hotkeys": "^0.2.28",
|
"videojs-hotkeys": "^0.2.28",
|
||||||
"videojs-mobile-ui": "^1.1.1",
|
"videojs-mobile-ui": "^1.1.1",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
"vue-final-modal": "^4.5.4",
|
"vue-final-modal": "^4.5.4",
|
||||||
"vue-i18n": "^10.0.5",
|
"vue-i18n": "^11.0.1",
|
||||||
"vue-lazyload": "^3.0.0",
|
"vue-lazyload": "^3.0.0",
|
||||||
"vue-reader": "^1.2.14",
|
"vue-reader": "^1.2.17",
|
||||||
"vue-router": "^4.3.0",
|
"vue-router": "^4.3.0",
|
||||||
"vue-toastification": "^2.0.0-rc.5"
|
"vue-toastification": "^2.0.0-rc.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@intlify/unplugin-vue-i18n": "^6.0.0",
|
"@intlify/unplugin-vue-i18n": "^6.0.3",
|
||||||
"@playwright/test": "^1.42.1",
|
"@playwright/test": "^1.50.0",
|
||||||
"@tsconfig/node22": "^22.0.0",
|
"@tsconfig/node22": "^22.0.0",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^22.10.1",
|
"@types/node": "^22.10.10",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.17.0",
|
"@typescript-eslint/eslint-plugin": "^8.21.0",
|
||||||
"@vitejs/plugin-legacy": "^6.0.0",
|
"@vitejs/plugin-legacy": "^6.0.0",
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vue/eslint-config-prettier": "^10.1.0",
|
"@vue/eslint-config-prettier": "^10.2.0",
|
||||||
"@vue/eslint-config-typescript": "^14.1.4",
|
"@vue/eslint-config-typescript": "^14.3.0",
|
||||||
"@vue/tsconfig": "^0.7.0",
|
"@vue/tsconfig": "^0.7.0",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"concurrently": "^9.1.0",
|
"concurrently": "^9.1.2",
|
||||||
"eslint": "^9.16.0",
|
"eslint": "^9.19.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.2.3",
|
||||||
"eslint-plugin-vue": "^9.24.0",
|
"eslint-plugin-vue": "^9.24.0",
|
||||||
"jsdom": "^25.0.1",
|
"jsdom": "^26.0.0",
|
||||||
"postcss": "^8.4.38",
|
"postcss": "^8.5.1",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.4.2",
|
||||||
"terser": "^5.30.0",
|
"terser": "^5.37.0",
|
||||||
"vite": "^6.0.2",
|
"vite": "^6.0.11",
|
||||||
"vite-plugin-compression2": "^1.0.0",
|
"vite-plugin-compression2": "^1.0.0",
|
||||||
"vue-tsc": "^2.0.7"
|
"vue-tsc": "^2.2.0"
|
||||||
},
|
},
|
||||||
"pnpm": {
|
"packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0"
|
||||||
"overrides": {
|
|
||||||
"typescript": "~5.6.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packageManager": "pnpm@9.14.4+sha512.c8180b3fbe4e4bca02c94234717896b5529740a6cbadf19fa78254270403ea2f27d4e1d46a08a0f56c89b63dc8ebfd3ee53326da720273794e6200fcf0d184ab"
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -25,7 +25,7 @@ export async function create(user: IUser) {
|
||||||
throw new StatusError(await res.text(), res.status);
|
throw new StatusError(await res.text(), res.status);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(user: IUser, which = ["all"]) {
|
export async function update(user: Partial<IUser>, which = ["all"]) {
|
||||||
await fetchURL(`/api/users/${user.id}`, {
|
await fetchURL(`/api/users/${user.id}`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|
|
@ -34,7 +34,7 @@ const props = defineProps<{
|
||||||
|
|
||||||
const items = computed(() => {
|
const items = computed(() => {
|
||||||
const relativePath = route.path.replace(props.base, "");
|
const relativePath = route.path.replace(props.base, "");
|
||||||
let parts = relativePath.split("/");
|
const parts = relativePath.split("/");
|
||||||
|
|
||||||
if (parts[0] === "") {
|
if (parts[0] === "") {
|
||||||
parts.shift();
|
parts.shift();
|
||||||
|
@ -44,7 +44,7 @@ const items = computed(() => {
|
||||||
parts.pop();
|
parts.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
let breadcrumbs: BreadCrumb[] = [];
|
const breadcrumbs: BreadCrumb[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < parts.length; i++) {
|
for (let i = 0; i < parts.length; i++) {
|
||||||
if (i === 0) {
|
if (i === 0) {
|
||||||
|
|
|
@ -46,7 +46,7 @@ https://raw.githubusercontent.com/dzwillia/vue-simple-progress/master/src/compon
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// We're leaving this untouched as you can read in the beginning
|
// We're leaving this untouched as you can read in the beginning
|
||||||
var isNumber = function (n) {
|
const isNumber = function (n) {
|
||||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
pct() {
|
pct() {
|
||||||
var pct = (this.val / this.max) * 100;
|
let pct = (this.val / this.max) * 100;
|
||||||
pct = pct.toFixed(2);
|
pct = pct.toFixed(2);
|
||||||
return Math.min(pct, this.max);
|
return Math.min(pct, this.max);
|
||||||
},
|
},
|
||||||
|
@ -160,7 +160,7 @@ export default {
|
||||||
return isNumber(this.fontSize) ? this.fontSize : 13;
|
return isNumber(this.fontSize) ? this.fontSize : 13;
|
||||||
},
|
},
|
||||||
progress_style() {
|
progress_style() {
|
||||||
var style = {
|
const style = {
|
||||||
background: this.bgColor,
|
background: this.bgColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ export default {
|
||||||
return style;
|
return style;
|
||||||
},
|
},
|
||||||
bar_style() {
|
bar_style() {
|
||||||
var style = {
|
const style = {
|
||||||
background: this.barColor,
|
background: this.barColor,
|
||||||
width: this.pct + "%",
|
width: this.pct + "%",
|
||||||
height: this.size_px + "px",
|
height: this.size_px + "px",
|
||||||
|
@ -198,7 +198,7 @@ export default {
|
||||||
return style;
|
return style;
|
||||||
},
|
},
|
||||||
text_style() {
|
text_style() {
|
||||||
var style = {
|
const style = {
|
||||||
color: this.textFgColor,
|
color: this.textFgColor,
|
||||||
"font-size": this.text_font_size + "px",
|
"font-size": this.text_font_size + "px",
|
||||||
"text-align": this.textAlign,
|
"text-align": this.textAlign,
|
||||||
|
|
|
@ -163,7 +163,7 @@ export default {
|
||||||
this.canInput = false;
|
this.canInput = false;
|
||||||
event.target.innerHTML = "";
|
event.target.innerHTML = "";
|
||||||
|
|
||||||
let results = {
|
const results = {
|
||||||
text: `${cmd}\n\n`,
|
text: `${cmd}\n\n`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ export default {
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
results.text = results.text
|
results.text = results.text
|
||||||
// eslint-disable-next-line no-control-regex
|
|
||||||
.replace(/\u001b\[[0-9;]+m/g, "") // Filter ANSI color for now
|
.replace(/\u001b\[[0-9;]+m/g, "") // Filter ANSI color for now
|
||||||
.trimEnd();
|
.trimEnd();
|
||||||
this.canInput = true;
|
this.canInput = true;
|
||||||
|
|
|
@ -158,7 +158,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useLayoutStore, ["closeHovers", "showHover"]),
|
...mapActions(useLayoutStore, ["closeHovers", "showHover"]),
|
||||||
async fetchUsage() {
|
async fetchUsage() {
|
||||||
let path = this.$route.path.endsWith("/")
|
const path = this.$route.path.endsWith("/")
|
||||||
? this.$route.path
|
? this.$route.path
|
||||||
: this.$route.path + "/";
|
: this.$route.path + "/";
|
||||||
let usageStats = USAGE_DEFAULT;
|
let usageStats = USAGE_DEFAULT;
|
||||||
|
@ -166,7 +166,7 @@ export default {
|
||||||
return Object.assign(this.usage, usageStats);
|
return Object.assign(this.usage, usageStats);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
let usage = await api.usage(path);
|
const usage = await api.usage(path);
|
||||||
usageStats = {
|
usageStats = {
|
||||||
used: prettyBytes(usage.used, { binary: true }),
|
used: prettyBytes(usage.used, { binary: true }),
|
||||||
total: prettyBytes(usage.total, { binary: true }),
|
total: prettyBytes(usage.total, { binary: true }),
|
||||||
|
|
|
@ -102,10 +102,11 @@ const decodeUTIF = () => {
|
||||||
if (document?.location?.pathname === undefined) {
|
if (document?.location?.pathname === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let suff = document.location.pathname.split(".")?.pop()?.toLowerCase() ?? "";
|
const suff =
|
||||||
|
document.location.pathname.split(".")?.pop()?.toLowerCase() ?? "";
|
||||||
|
|
||||||
if (sufs.indexOf(suff) == -1) return false;
|
if (sufs.indexOf(suff) == -1) return false;
|
||||||
let xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
UTIF._xhrs.push(xhr);
|
UTIF._xhrs.push(xhr);
|
||||||
UTIF._imgs.push(imgex.value);
|
UTIF._imgs.push(imgex.value);
|
||||||
xhr.open("GET", props.src);
|
xhr.open("GET", props.src);
|
||||||
|
@ -230,7 +231,7 @@ const touchMove = (event: TouchEvent) => {
|
||||||
if (imgex.value === null) {
|
if (imgex.value === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let step = imgex.value.width / 5;
|
const step = imgex.value.width / 5;
|
||||||
if (event.targetTouches.length === 2) {
|
if (event.targetTouches.length === 2) {
|
||||||
moveDisabled.value = true;
|
moveDisabled.value = true;
|
||||||
if (disabledTimer.value) clearTimeout(disabledTimer.value);
|
if (disabledTimer.value) clearTimeout(disabledTimer.value);
|
||||||
|
@ -239,9 +240,9 @@ const touchMove = (event: TouchEvent) => {
|
||||||
props.moveDisabledTime
|
props.moveDisabledTime
|
||||||
);
|
);
|
||||||
|
|
||||||
let p1 = event.targetTouches[0];
|
const p1 = event.targetTouches[0];
|
||||||
let p2 = event.targetTouches[1];
|
const p2 = event.targetTouches[1];
|
||||||
let touchDistance = Math.sqrt(
|
const touchDistance = Math.sqrt(
|
||||||
Math.pow(p2.pageX - p1.pageX, 2) + Math.pow(p2.pageY - p1.pageY, 2)
|
Math.pow(p2.pageX - p1.pageX, 2) + Math.pow(p2.pageY - p1.pageY, 2)
|
||||||
);
|
);
|
||||||
if (!lastTouchDistance.value) {
|
if (!lastTouchDistance.value) {
|
||||||
|
@ -253,8 +254,8 @@ const touchMove = (event: TouchEvent) => {
|
||||||
setZoom();
|
setZoom();
|
||||||
} else if (event.targetTouches.length === 1) {
|
} else if (event.targetTouches.length === 1) {
|
||||||
if (moveDisabled.value) return;
|
if (moveDisabled.value) return;
|
||||||
let x = event.targetTouches[0].pageX - (lastX.value ?? 0);
|
const x = event.targetTouches[0].pageX - (lastX.value ?? 0);
|
||||||
let y = event.targetTouches[0].pageY - (lastY.value ?? 0);
|
const y = event.targetTouches[0].pageY - (lastY.value ?? 0);
|
||||||
if (Math.abs(x) >= step && Math.abs(y) >= step) return;
|
if (Math.abs(x) >= step && Math.abs(y) >= step) return;
|
||||||
lastX.value = event.targetTouches[0].pageX;
|
lastX.value = event.targetTouches[0].pageX;
|
||||||
lastY.value = event.targetTouches[0].pageY;
|
lastY.value = event.targetTouches[0].pageY;
|
||||||
|
@ -268,8 +269,8 @@ const doMove = (x: number, y: number) => {
|
||||||
}
|
}
|
||||||
const style = imgex.value.style;
|
const style = imgex.value.style;
|
||||||
|
|
||||||
let posX = pxStringToNumber(style.left) + x;
|
const posX = pxStringToNumber(style.left) + x;
|
||||||
let posY = pxStringToNumber(style.top) + y;
|
const posY = pxStringToNumber(style.top) + y;
|
||||||
|
|
||||||
style.left = posX + "px";
|
style.left = posX + "px";
|
||||||
style.top = posY + "px";
|
style.top = posY + "px";
|
||||||
|
|
|
@ -82,7 +82,7 @@ const isDraggable = computed(
|
||||||
const canDrop = computed(() => {
|
const canDrop = computed(() => {
|
||||||
if (!props.isDir || props.readOnly) return false;
|
if (!props.isDir || props.readOnly) return false;
|
||||||
|
|
||||||
for (let i of fileStore.selected) {
|
for (const i of fileStore.selected) {
|
||||||
if (fileStore.req?.items[i].url === props.url) {
|
if (fileStore.req?.items[i].url === props.url) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -156,9 +156,9 @@ const drop = async (event: Event) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let items: any[] = [];
|
const items: any[] = [];
|
||||||
|
|
||||||
for (let i of fileStore.selected) {
|
for (const i of fileStore.selected) {
|
||||||
if (fileStore.req) {
|
if (fileStore.req) {
|
||||||
items.push({
|
items.push({
|
||||||
from: fileStore.req?.items[i].url,
|
from: fileStore.req?.items[i].url,
|
||||||
|
@ -172,10 +172,10 @@ const drop = async (event: Event) => {
|
||||||
if (el === null) {
|
if (el === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let path = el.__vue__.url;
|
const path = el.__vue__.url;
|
||||||
let baseItems = (await api.fetch(path)).items;
|
const baseItems = (await api.fetch(path)).items;
|
||||||
|
|
||||||
let action = (overwrite: boolean, rename: boolean) => {
|
const action = (overwrite: boolean, rename: boolean) => {
|
||||||
api
|
api
|
||||||
.move(items, overwrite, rename)
|
.move(items, overwrite, rename)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -184,7 +184,7 @@ const drop = async (event: Event) => {
|
||||||
.catch($showError);
|
.catch($showError);
|
||||||
};
|
};
|
||||||
|
|
||||||
let conflict = upload.checkConflict(items, baseItems);
|
const conflict = upload.checkConflict(items, baseItems);
|
||||||
|
|
||||||
let overwrite = false;
|
let overwrite = false;
|
||||||
let rename = false;
|
let rename = false;
|
||||||
|
|
|
@ -73,11 +73,16 @@ const initVideoPlayer = async () => {
|
||||||
const langOpt = { language: "videoPlayerLocal" };
|
const langOpt = { language: "videoPlayerLocal" };
|
||||||
// support for playback at different speeds.
|
// support for playback at different speeds.
|
||||||
const playbackRatesOpt = { playbackRates: [0.5, 1, 1.5, 2, 2.5, 3] };
|
const playbackRatesOpt = { playbackRates: [0.5, 1, 1.5, 2, 2.5, 3] };
|
||||||
let options = getOptions(props.options, langOpt, srcOpt, playbackRatesOpt);
|
const options = getOptions(
|
||||||
|
props.options,
|
||||||
|
langOpt,
|
||||||
|
srcOpt,
|
||||||
|
playbackRatesOpt
|
||||||
|
);
|
||||||
player.value = videojs(videoPlayer.value!, options, () => {});
|
player.value = videojs(videoPlayer.value!, options, () => {});
|
||||||
|
|
||||||
// TODO: need to test on mobile
|
// TODO: need to test on mobile
|
||||||
// @ts-ignore
|
// @ts-expect-error no ts definition for mobileUi
|
||||||
player.value!.mobileUi();
|
player.value!.mobileUi();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error initializing video player:", error);
|
console.error("Error initializing video player:", error);
|
||||||
|
|
|
@ -82,10 +82,10 @@ export default {
|
||||||
...mapActions(useLayoutStore, ["showHover", "closeHovers"]),
|
...mapActions(useLayoutStore, ["showHover", "closeHovers"]),
|
||||||
copy: async function (event) {
|
copy: async function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let items = [];
|
const items = [];
|
||||||
|
|
||||||
// Create a new promise for each file.
|
// Create a new promise for each file.
|
||||||
for (let item of this.selected) {
|
for (const item of this.selected) {
|
||||||
items.push({
|
items.push({
|
||||||
from: this.req.items[item].url,
|
from: this.req.items[item].url,
|
||||||
to: this.dest + encodeURIComponent(this.req.items[item].name),
|
to: this.dest + encodeURIComponent(this.req.items[item].name),
|
||||||
|
@ -93,7 +93,7 @@ export default {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let action = async (overwrite, rename) => {
|
const action = async (overwrite, rename) => {
|
||||||
buttons.loading("copy");
|
buttons.loading("copy");
|
||||||
|
|
||||||
await api
|
await api
|
||||||
|
@ -122,8 +122,8 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let dstItems = (await api.fetch(this.dest)).items;
|
const dstItems = (await api.fetch(this.dest)).items;
|
||||||
let conflict = upload.checkConflict(items, dstItems);
|
const conflict = upload.checkConflict(items, dstItems);
|
||||||
|
|
||||||
let overwrite = false;
|
let overwrite = false;
|
||||||
let rename = false;
|
let rename = false;
|
||||||
|
|
|
@ -74,8 +74,8 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let promises = [];
|
const promises = [];
|
||||||
for (let index of this.selected) {
|
for (const index of this.selected) {
|
||||||
promises.push(api.remove(this.req.items[index].url));
|
promises.push(api.remove(this.req.items[index].url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default {
|
||||||
submit: async function () {
|
submit: async function () {
|
||||||
this.updateRequest(null);
|
this.updateRequest(null);
|
||||||
|
|
||||||
let uri = url.removeLastDir(this.$route.path) + "/";
|
const uri = url.removeLastDir(this.$route.path) + "/";
|
||||||
this.$router.push({ path: uri });
|
this.$router.push({ path: uri });
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -80,7 +80,7 @@ export default {
|
||||||
|
|
||||||
// Otherwise we add every directory to the
|
// Otherwise we add every directory to the
|
||||||
// move options.
|
// move options.
|
||||||
for (let item of req.items) {
|
for (const item of req.items) {
|
||||||
if (!item.isDir) continue;
|
if (!item.isDir) continue;
|
||||||
|
|
||||||
this.items.push({
|
this.items.push({
|
||||||
|
@ -93,12 +93,12 @@ export default {
|
||||||
// Retrieves the URL of the directory the user
|
// Retrieves the URL of the directory the user
|
||||||
// just clicked in and fill the options with its
|
// just clicked in and fill the options with its
|
||||||
// content.
|
// content.
|
||||||
let uri = event.currentTarget.dataset.url;
|
const uri = event.currentTarget.dataset.url;
|
||||||
|
|
||||||
files.fetch(uri).then(this.fillOptions).catch(this.$showError);
|
files.fetch(uri).then(this.fillOptions).catch(this.$showError);
|
||||||
},
|
},
|
||||||
touchstart(event) {
|
touchstart(event) {
|
||||||
let url = event.currentTarget.dataset.url;
|
const url = event.currentTarget.dataset.url;
|
||||||
|
|
||||||
// In 300 milliseconds, we shall reset the count.
|
// In 300 milliseconds, we shall reset the count.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
@ -124,7 +124,7 @@ export default {
|
||||||
|
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
|
|
||||||
for (let selected of this.selected) {
|
for (const selected of this.selected) {
|
||||||
sum += this.req.items[selected].size;
|
sum += this.req.items[selected].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,9 +81,9 @@ export default {
|
||||||
...mapActions(useLayoutStore, ["showHover", "closeHovers"]),
|
...mapActions(useLayoutStore, ["showHover", "closeHovers"]),
|
||||||
move: async function (event) {
|
move: async function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let items = [];
|
const items = [];
|
||||||
|
|
||||||
for (let item of this.selected) {
|
for (const item of this.selected) {
|
||||||
items.push({
|
items.push({
|
||||||
from: this.req.items[item].url,
|
from: this.req.items[item].url,
|
||||||
to: this.dest + encodeURIComponent(this.req.items[item].name),
|
to: this.dest + encodeURIComponent(this.req.items[item].name),
|
||||||
|
@ -91,7 +91,7 @@ export default {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let action = async (overwrite, rename) => {
|
const action = async (overwrite, rename) => {
|
||||||
buttons.loading("move");
|
buttons.loading("move");
|
||||||
|
|
||||||
await api
|
await api
|
||||||
|
@ -106,8 +106,8 @@ export default {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let dstItems = (await api.fetch(this.dest)).items;
|
const dstItems = (await api.fetch(this.dest)).items;
|
||||||
let conflict = upload.checkConflict(items, dstItems);
|
const conflict = upload.checkConflict(items, dstItems);
|
||||||
|
|
||||||
let overwrite = false;
|
let overwrite = false;
|
||||||
let rename = false;
|
let rename = false;
|
||||||
|
|
|
@ -196,13 +196,23 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useLayoutStore, ["closeHovers"]),
|
...mapActions(useLayoutStore, ["closeHovers"]),
|
||||||
copyToClipboard: function (text) {
|
copyToClipboard: function (text) {
|
||||||
copy(text).then(
|
copy({ text }).then(
|
||||||
() => {
|
() => {
|
||||||
// clipboard successfully set
|
// clipboard successfully set
|
||||||
this.$showSuccess(this.$t("success.linkCopied"));
|
this.$showSuccess(this.$t("success.linkCopied"));
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
// clipboard write failed
|
// clipboard write failed
|
||||||
|
copy({ text }, { permission: true }).then(
|
||||||
|
() => {
|
||||||
|
// clipboard successfully set
|
||||||
|
this.$showSuccess(this.$t("success.linkCopied"));
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
// clipboard write failed
|
||||||
|
this.$showError(e);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -48,10 +48,10 @@ const layoutStore = useLayoutStore();
|
||||||
|
|
||||||
// TODO: this is a copy of the same function in FileListing.vue
|
// TODO: this is a copy of the same function in FileListing.vue
|
||||||
const uploadInput = (event: Event) => {
|
const uploadInput = (event: Event) => {
|
||||||
let files = (event.currentTarget as HTMLInputElement)?.files;
|
const files = (event.currentTarget as HTMLInputElement)?.files;
|
||||||
if (files === null) return;
|
if (files === null) return;
|
||||||
|
|
||||||
let folder_upload = !!files[0].webkitRelativePath;
|
const folder_upload = !!files[0].webkitRelativePath;
|
||||||
|
|
||||||
const uploadFiles: UploadList = [];
|
const uploadFiles: UploadList = [];
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
@ -66,8 +66,8 @@ const uploadInput = (event: Event) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = route.path.endsWith("/") ? route.path : route.path + "/";
|
const path = route.path.endsWith("/") ? route.path : route.path + "/";
|
||||||
let conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
|
const conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
|
||||||
|
|
||||||
if (conflict) {
|
if (conflict) {
|
||||||
layoutStore.showHover({
|
layoutStore.showHover({
|
||||||
|
|
|
@ -13,7 +13,7 @@ export default {
|
||||||
name: "languages",
|
name: "languages",
|
||||||
props: ["locale"],
|
props: ["locale"],
|
||||||
data() {
|
data() {
|
||||||
let dataObj = {};
|
const dataObj = {};
|
||||||
const locales = {
|
const locales = {
|
||||||
he: "עברית",
|
he: "עברית",
|
||||||
hu: "Magyar",
|
hu: "Magyar",
|
||||||
|
|
|
@ -39,7 +39,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
remove(event, index) {
|
remove(event, index) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
let rules = [...this.rules];
|
const rules = [...this.rules];
|
||||||
rules.splice(index, 1);
|
rules.splice(index, 1);
|
||||||
this.$emit("update:rules", [...rules]);
|
this.$emit("update:rules", [...rules]);
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,7 +17,6 @@ defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
(e: "update:theme", val: string | null): void;
|
(e: "update:theme", val: string | null): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ watch(createUserDirData, () => {
|
||||||
if (props.user?.scope) {
|
if (props.user?.scope) {
|
||||||
props.user.scope = createUserDirData.value
|
props.user.scope = createUserDirData.value
|
||||||
? ""
|
? ""
|
||||||
: originalUserScope.value ?? "";
|
: (originalUserScope.value ?? "");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -63,8 +63,8 @@
|
||||||
local("Roboto"),
|
local("Roboto"),
|
||||||
local("Roboto-Regular"),
|
local("Roboto-Regular"),
|
||||||
url(../assets/fonts/roboto/normal-latin-ext.woff2) format("woff2");
|
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,
|
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF,
|
||||||
U+A720-A7FF;
|
U+2C60-2C7F, U+A720-A7FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
|
@ -142,8 +142,8 @@
|
||||||
local("Roboto Medium"),
|
local("Roboto Medium"),
|
||||||
local("Roboto-Medium"),
|
local("Roboto-Medium"),
|
||||||
url(../assets/fonts/roboto/medium-latin-ext.woff2) format("woff2");
|
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,
|
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF,
|
||||||
U+A720-A7FF;
|
U+2C60-2C7F, U+A720-A7FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
|
@ -221,8 +221,8 @@
|
||||||
local("Roboto Bold"),
|
local("Roboto Bold"),
|
||||||
local("Roboto-Bold"),
|
local("Roboto-Bold"),
|
||||||
url(../assets/fonts/roboto/bold-latin-ext.woff2) format("woff2");
|
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,
|
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF,
|
||||||
U+A720-A7FF;
|
U+2C60-2C7F, U+A720-A7FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
|
|
|
@ -142,7 +142,7 @@ export const i18n = createI18n({
|
||||||
|
|
||||||
export const isRtl = (locale?: string) => {
|
export const isRtl = (locale?: string) => {
|
||||||
// see below
|
// see below
|
||||||
// @ts-ignore
|
// @ts-expect-error incorrect type when legacy
|
||||||
return rtlLanguages.includes(locale || i18n.global.locale.value);
|
return rtlLanguages.includes(locale || i18n.global.locale.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ export function setLocale(locale: string) {
|
||||||
dayjs.locale(locale);
|
dayjs.locale(locale);
|
||||||
// according to doc u only need .value if legacy: false but they lied
|
// according to doc u only need .value if legacy: false but they lied
|
||||||
// https://vue-i18n.intlify.dev/guide/essentials/scope.html#local-scope-1
|
// https://vue-i18n.intlify.dev/guide/essentials/scope.html#local-scope-1
|
||||||
//@ts-ignore
|
// @ts-expect-error incorrect type when legacy
|
||||||
i18n.global.locale.value = locale;
|
i18n.global.locale.value = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ export async function validateLogin() {
|
||||||
await renew(<string>localStorage.getItem("jwt"));
|
await renew(<string>localStorage.getItem("jwt"));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn("Invalid JWT token in storage"); // eslint-disable-line
|
console.warn("Invalid JWT token in storage");
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ function loading(button: string) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (el === undefined || el === null) {
|
if (el === undefined || el === null) {
|
||||||
console.log("Error getting button " + button); // eslint-disable-line
|
console.log("Error getting button " + button);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ function done(button: string) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (el === undefined || el === null) {
|
if (el === undefined || el === null) {
|
||||||
console.log("Error getting button " + button); // eslint-disable-line
|
console.log("Error getting button " + button);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ function success(button: string) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (el === undefined || el === null) {
|
if (el === undefined || el === null) {
|
||||||
console.log("Error getting button " + button); // eslint-disable-line
|
console.log("Error getting button " + button);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,39 +1,36 @@
|
||||||
// Based on code by the following links:
|
// Based on code by the following links:
|
||||||
// https://stackoverflow.com/a/74528564
|
// https://stackoverflow.com/a/74528564
|
||||||
// https://web.dev/articles/async-clipboard
|
// https://web.dev/articles/async-clipboard
|
||||||
export function copy(text: string) {
|
|
||||||
|
interface ClipboardArgs {
|
||||||
|
text?: string;
|
||||||
|
data?: ClipboardItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ClipboardOpts {
|
||||||
|
permission?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function copy(data: ClipboardArgs, opts?: ClipboardOpts) {
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
if (
|
if (
|
||||||
// Clipboard API requires secure context
|
// Clipboard API requires secure context
|
||||||
window.isSecureContext &&
|
window.isSecureContext &&
|
||||||
typeof navigator.clipboard !== "undefined" &&
|
typeof navigator.clipboard !== "undefined"
|
||||||
// @ts-ignore
|
|
||||||
navigator.permissions !== "undefined"
|
|
||||||
) {
|
) {
|
||||||
navigator.permissions
|
if (opts?.permission) {
|
||||||
// @ts-ignore
|
getPermission("clipboard-write")
|
||||||
.query({ name: "clipboard-write" })
|
.then(() => writeToClipboard(data).then(resolve).catch(reject))
|
||||||
.then((permission) => {
|
.catch(reject);
|
||||||
if (permission.state === "granted" || permission.state === "prompt") {
|
|
||||||
// simple writeText should work for all modern browsers
|
|
||||||
navigator.clipboard.writeText(text).then(resolve).catch(reject);
|
|
||||||
} else {
|
} else {
|
||||||
reject(new Error("Permission not granted!"));
|
writeToClipboard(data).then(resolve).catch(reject);
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
// Firefox doesn't support clipboard-write permission
|
|
||||||
if (navigator.userAgent.indexOf("Firefox") != -1) {
|
|
||||||
navigator.clipboard.writeText(text).then(resolve).catch(reject);
|
|
||||||
} else {
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (
|
} else if (
|
||||||
document.queryCommandSupported &&
|
document.queryCommandSupported &&
|
||||||
document.queryCommandSupported("copy")
|
document.queryCommandSupported("copy") &&
|
||||||
|
data.text // old method only supports text
|
||||||
) {
|
) {
|
||||||
const textarea = createTemporaryTextarea(text);
|
const textarea = createTemporaryTextarea(data.text);
|
||||||
const body = document.activeElement || document.body;
|
const body = document.activeElement || document.body;
|
||||||
try {
|
try {
|
||||||
body.appendChild(textarea);
|
body.appendChild(textarea);
|
||||||
|
@ -54,6 +51,35 @@ export function copy(text: string) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPermission(name: string) {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
typeof navigator.permissions !== "undefined" &&
|
||||||
|
navigator.permissions
|
||||||
|
// @ts-expect-error chrome specific api
|
||||||
|
.query({ name })
|
||||||
|
.then((permission) => {
|
||||||
|
if (permission.state === "granted" || permission.state === "prompt") {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(new Error("Permission denied!"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeToClipboard(data: ClipboardArgs) {
|
||||||
|
if (data.text) {
|
||||||
|
return navigator.clipboard.writeText(data.text);
|
||||||
|
}
|
||||||
|
if (data.data) {
|
||||||
|
return navigator.clipboard.write(data.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
reject(new Error("No data was supplied!"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const styles = {
|
const styles = {
|
||||||
fontSize: "12pt",
|
fontSize: "12pt",
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
|
@ -69,10 +95,10 @@ const styles = {
|
||||||
background: "transparent",
|
background: "transparent",
|
||||||
};
|
};
|
||||||
|
|
||||||
const createTemporaryTextarea = (text: string) => {
|
function createTemporaryTextarea(text: string) {
|
||||||
const textarea = document.createElement("textarea");
|
const textarea = document.createElement("textarea");
|
||||||
textarea.value = text;
|
textarea.value = text;
|
||||||
textarea.setAttribute("readonly", "");
|
textarea.setAttribute("readonly", "");
|
||||||
Object.assign(textarea.style, styles);
|
Object.assign(textarea.style, styles);
|
||||||
return textarea;
|
return textarea;
|
||||||
};
|
}
|
||||||
|
|
|
@ -6,13 +6,16 @@ export default function getRule(rules: string[]) {
|
||||||
let result = null;
|
let result = null;
|
||||||
const find = Array.prototype.find;
|
const find = Array.prototype.find;
|
||||||
|
|
||||||
find.call(document.styleSheets, (styleSheet) => {
|
find.call(document.styleSheets, (styleSheet: CSSStyleSheet) => {
|
||||||
result = find.call(styleSheet.cssRules, (cssRule) => {
|
result = find.call(styleSheet.cssRules, (cssRule: CSSRule) => {
|
||||||
let found = false;
|
let found = false;
|
||||||
|
|
||||||
if (cssRule instanceof window.CSSStyleRule) {
|
// faster than checking instanceof for every element
|
||||||
|
if (cssRule.constructor.name === "CSSStyleRule") {
|
||||||
for (let i = 0; i < rules.length; i++) {
|
for (let i = 0; i < rules.length; i++) {
|
||||||
if (cssRule.selectorText.toLowerCase() === rules[i]) {
|
if (
|
||||||
|
(cssRule as CSSStyleRule).selectorText.toLowerCase() === rules[i]
|
||||||
|
) {
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,5 +27,5 @@ export default function getRule(rules: string[]) {
|
||||||
return result != null;
|
return result != null;
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result as CSSStyleRule | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,6 +325,7 @@ const token = ref<string>("");
|
||||||
const audio = ref<HTMLAudioElement>();
|
const audio = ref<HTMLAudioElement>();
|
||||||
const tag = ref<boolean>(false);
|
const tag = ref<boolean>(false);
|
||||||
|
|
||||||
|
const $showError = inject<IToastError>("$showError")!;
|
||||||
const $showSuccess = inject<IToastSuccess>("$showSuccess")!;
|
const $showSuccess = inject<IToastSuccess>("$showSuccess")!;
|
||||||
|
|
||||||
const { t } = useI18n({});
|
const { t } = useI18n({});
|
||||||
|
@ -463,9 +464,9 @@ const download = () => {
|
||||||
if (req.value === null) return false;
|
if (req.value === null) return false;
|
||||||
layoutStore.closeHovers();
|
layoutStore.closeHovers();
|
||||||
|
|
||||||
let files: string[] = [];
|
const files: string[] = [];
|
||||||
|
|
||||||
for (let i of fileStore.selected) {
|
for (const i of fileStore.selected) {
|
||||||
files.push(req.value.items[i].path);
|
files.push(req.value.items[i].path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,13 +489,23 @@ const linkSelected = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const copyToClipboard = (text: string) => {
|
const copyToClipboard = (text: string) => {
|
||||||
copy(text).then(
|
copy({ text }).then(
|
||||||
() => {
|
() => {
|
||||||
// clipboard successfully set
|
// clipboard successfully set
|
||||||
$showSuccess(t("success.linkCopied"));
|
$showSuccess(t("success.linkCopied"));
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
// clipboard write failed
|
// clipboard write failed
|
||||||
|
copy({ text }, { permission: true }).then(
|
||||||
|
() => {
|
||||||
|
// clipboard successfully set
|
||||||
|
$showSuccess(t("success.linkCopied"));
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
// clipboard write failed
|
||||||
|
$showError(e);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -108,7 +108,7 @@ onMounted(() => {
|
||||||
showPrintMargin: false,
|
showPrintMargin: false,
|
||||||
readOnly: fileStore.req?.type === "textImmutable",
|
readOnly: fileStore.req?.type === "textImmutable",
|
||||||
theme: "ace/theme/chrome",
|
theme: "ace/theme/chrome",
|
||||||
mode: modelist.getModeForPath(fileStore.req?.name).mode,
|
mode: modelist.getModeForPath(fileStore.req!.name).mode,
|
||||||
wrap: true,
|
wrap: true,
|
||||||
enableBasicAutocompletion: true,
|
enableBasicAutocompletion: true,
|
||||||
enableLiveAutocompletion: true,
|
enableLiveAutocompletion: true,
|
||||||
|
@ -173,7 +173,7 @@ const close = () => {
|
||||||
|
|
||||||
fileStore.updateRequest(null);
|
fileStore.updateRequest(null);
|
||||||
|
|
||||||
let uri = url.removeLastDir(route.path) + "/";
|
const uri = url.removeLastDir(route.path) + "/";
|
||||||
router.push({ path: uri });
|
router.push({ path: uri });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -523,12 +523,12 @@ const keyEvent = (event: KeyboardEvent) => {
|
||||||
break;
|
break;
|
||||||
case "a":
|
case "a":
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
for (let file of items.value.files) {
|
for (const file of items.value.files) {
|
||||||
if (fileStore.selected.indexOf(file.index) === -1) {
|
if (fileStore.selected.indexOf(file.index) === -1) {
|
||||||
fileStore.selected.push(file.index);
|
fileStore.selected.push(file.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let dir of items.value.dirs) {
|
for (const dir of items.value.dirs) {
|
||||||
if (fileStore.selected.indexOf(dir.index) === -1) {
|
if (fileStore.selected.indexOf(dir.index) === -1) {
|
||||||
fileStore.selected.push(dir.index);
|
fileStore.selected.push(dir.index);
|
||||||
}
|
}
|
||||||
|
@ -551,9 +551,9 @@ const copyCut = (event: Event | KeyboardEvent): void => {
|
||||||
|
|
||||||
if (fileStore.req === null) return;
|
if (fileStore.req === null) return;
|
||||||
|
|
||||||
let items = [];
|
const items = [];
|
||||||
|
|
||||||
for (let i of fileStore.selected) {
|
for (const i of fileStore.selected) {
|
||||||
items.push({
|
items.push({
|
||||||
from: fileStore.req.items[i].url,
|
from: fileStore.req.items[i].url,
|
||||||
name: fileStore.req.items[i].name,
|
name: fileStore.req.items[i].name,
|
||||||
|
@ -575,9 +575,9 @@ const paste = (event: Event) => {
|
||||||
if ((event.target as HTMLElement).tagName?.toLowerCase() === "input") return;
|
if ((event.target as HTMLElement).tagName?.toLowerCase() === "input") return;
|
||||||
|
|
||||||
// TODO router location should it be
|
// TODO router location should it be
|
||||||
let items: any[] = [];
|
const items: any[] = [];
|
||||||
|
|
||||||
for (let item of clipboardStore.items) {
|
for (const item of clipboardStore.items) {
|
||||||
const from = item.from.endsWith("/") ? item.from.slice(0, -1) : item.from;
|
const from = item.from.endsWith("/") ? item.from.slice(0, -1) : item.from;
|
||||||
const to = route.path + encodeURIComponent(item.name);
|
const to = route.path + encodeURIComponent(item.name);
|
||||||
items.push({ from, to, name: item.name });
|
items.push({ from, to, name: item.name });
|
||||||
|
@ -614,7 +614,7 @@ const paste = (event: Event) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let conflict = upload.checkConflict(items, fileStore.req!.items);
|
const conflict = upload.checkConflict(items, fileStore.req!.items);
|
||||||
|
|
||||||
let overwrite = false;
|
let overwrite = false;
|
||||||
let rename = false;
|
let rename = false;
|
||||||
|
@ -640,14 +640,13 @@ const paste = (event: Event) => {
|
||||||
|
|
||||||
const colunmsResize = () => {
|
const colunmsResize = () => {
|
||||||
// Update the columns size based on the window width.
|
// Update the columns size based on the window width.
|
||||||
let items_ = css(["#listing.mosaic .item", ".mosaic#listing .item"]);
|
const items_ = css(["#listing.mosaic .item", ".mosaic#listing .item"]);
|
||||||
if (items_ === null) return;
|
if (items_ === null) return;
|
||||||
|
|
||||||
let columns = Math.floor(
|
let columns = Math.floor(
|
||||||
(document.querySelector("main")?.offsetWidth ?? 0) / columnWidth.value
|
(document.querySelector("main")?.offsetWidth ?? 0) / columnWidth.value
|
||||||
);
|
);
|
||||||
if (columns === 0) columns = 1;
|
if (columns === 0) columns = 1;
|
||||||
// @ts-ignore never type error
|
|
||||||
items_.style.width = `calc(${100 / columns}% - 1em)`;
|
items_.style.width = `calc(${100 / columns}% - 1em)`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -677,11 +676,10 @@ const dragEnter = () => {
|
||||||
|
|
||||||
// When the user starts dragging an item, put every
|
// When the user starts dragging an item, put every
|
||||||
// file on the listing with 50% opacity.
|
// file on the listing with 50% opacity.
|
||||||
let items = document.getElementsByClassName("item");
|
const items = document.getElementsByClassName("item");
|
||||||
|
|
||||||
// @ts-ignore
|
Array.from(items).forEach((file: Element) => {
|
||||||
Array.from(items).forEach((file: HTMLElement) => {
|
(file as HTMLElement).style.opacity = "0.5";
|
||||||
file.style.opacity = "0.5";
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -698,7 +696,7 @@ const drop = async (event: DragEvent) => {
|
||||||
dragCounter.value = 0;
|
dragCounter.value = 0;
|
||||||
resetOpacity();
|
resetOpacity();
|
||||||
|
|
||||||
let dt = event.dataTransfer;
|
const dt = event.dataTransfer;
|
||||||
let el: HTMLElement | null = event.target as HTMLElement;
|
let el: HTMLElement | null = event.target as HTMLElement;
|
||||||
|
|
||||||
if (fileStore.req === null || dt === null || dt.files.length <= 0) return;
|
if (fileStore.req === null || dt === null || dt.files.length <= 0) return;
|
||||||
|
@ -709,7 +707,7 @@ const drop = async (event: DragEvent) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let files: UploadList = (await upload.scanFiles(dt)) as UploadList;
|
const files: UploadList = (await upload.scanFiles(dt)) as UploadList;
|
||||||
let items = fileStore.req.items;
|
let items = fileStore.req.items;
|
||||||
let path = route.path.endsWith("/") ? route.path : route.path + "/";
|
let path = route.path.endsWith("/") ? route.path : route.path + "/";
|
||||||
|
|
||||||
|
@ -729,7 +727,7 @@ const drop = async (event: DragEvent) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let conflict = upload.checkConflict(files, items);
|
const conflict = upload.checkConflict(files, items);
|
||||||
|
|
||||||
if (conflict) {
|
if (conflict) {
|
||||||
layoutStore.showHover({
|
layoutStore.showHover({
|
||||||
|
@ -753,10 +751,10 @@ const drop = async (event: DragEvent) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const uploadInput = (event: Event) => {
|
const uploadInput = (event: Event) => {
|
||||||
let files = (event.currentTarget as HTMLInputElement)?.files;
|
const files = (event.currentTarget as HTMLInputElement)?.files;
|
||||||
if (files === null) return;
|
if (files === null) return;
|
||||||
|
|
||||||
let folder_upload = !!files[0].webkitRelativePath;
|
const folder_upload = !!files[0].webkitRelativePath;
|
||||||
|
|
||||||
const uploadFiles: UploadList = [];
|
const uploadFiles: UploadList = [];
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
@ -771,8 +769,8 @@ const uploadInput = (event: Event) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = route.path.endsWith("/") ? route.path : route.path + "/";
|
const path = route.path.endsWith("/") ? route.path : route.path + "/";
|
||||||
let conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
|
const conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
|
||||||
|
|
||||||
if (conflict) {
|
if (conflict) {
|
||||||
layoutStore.showHover({
|
layoutStore.showHover({
|
||||||
|
@ -796,7 +794,7 @@ const uploadInput = (event: Event) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetOpacity = () => {
|
const resetOpacity = () => {
|
||||||
let items = document.getElementsByClassName("item");
|
const items = document.getElementsByClassName("item");
|
||||||
|
|
||||||
Array.from(items).forEach((file: Element) => {
|
Array.from(items).forEach((file: Element) => {
|
||||||
(file as HTMLElement).style.opacity = "1";
|
(file as HTMLElement).style.opacity = "1";
|
||||||
|
@ -822,7 +820,6 @@ const sort = async (by: string) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (authStore.user?.id) {
|
if (authStore.user?.id) {
|
||||||
// @ts-ignore
|
|
||||||
await users.update({ id: authStore.user?.id, sorting: { by, asc } }, [
|
await users.update({ id: authStore.user?.id, sorting: { by, asc } }, [
|
||||||
"sorting",
|
"sorting",
|
||||||
]);
|
]);
|
||||||
|
@ -873,10 +870,10 @@ const download = () => {
|
||||||
confirm: (format: any) => {
|
confirm: (format: any) => {
|
||||||
layoutStore.closeHovers();
|
layoutStore.closeHovers();
|
||||||
|
|
||||||
let files = [];
|
const files = [];
|
||||||
|
|
||||||
if (fileStore.selectedCount > 0 && fileStore.req !== null) {
|
if (fileStore.selectedCount > 0 && fileStore.req !== null) {
|
||||||
for (let i of fileStore.selected) {
|
for (const i of fileStore.selected) {
|
||||||
files.push(fileStore.req.items[i].url);
|
files.push(fileStore.req.items[i].url);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -899,13 +896,12 @@ const switchView = async () => {
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
id: authStore.user?.id,
|
id: authStore.user?.id,
|
||||||
viewMode: modes[authStore.user?.viewMode ?? "list"] || "list",
|
viewMode: (modes[authStore.user?.viewMode ?? "list"] ||
|
||||||
|
"list") as ViewModeType,
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
users.update(data, ["viewMode"]).catch($showError);
|
users.update(data, ["viewMode"]).catch($showError);
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
authStore.updateUser(data);
|
authStore.updateUser(data);
|
||||||
|
|
||||||
setItemWeight();
|
setItemWeight();
|
||||||
|
|
|
@ -353,7 +353,7 @@ const updatePreview = async () => {
|
||||||
autoPlay.value = false;
|
autoPlay.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let dirs = route.fullPath.split("/");
|
const dirs = route.fullPath.split("/");
|
||||||
name.value = decodeURIComponent(dirs[dirs.length - 1]);
|
name.value = decodeURIComponent(dirs[dirs.length - 1]);
|
||||||
|
|
||||||
if (!listing.value) {
|
if (!listing.value) {
|
||||||
|
@ -422,7 +422,7 @@ const toggleNavigation = throttle(function () {
|
||||||
const close = () => {
|
const close = () => {
|
||||||
fileStore.updateRequest(null);
|
fileStore.updateRequest(null);
|
||||||
|
|
||||||
let uri = url.removeLastDir(route.path) + "/";
|
const uri = url.removeLastDir(route.path) + "/";
|
||||||
router.push({ path: uri });
|
router.push({ path: uri });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,7 @@ const formattedChunkSize = computed({
|
||||||
// Define funcs
|
// Define funcs
|
||||||
const capitalize = (name: string, where: string | RegExp = "_") => {
|
const capitalize = (name: string, where: string | RegExp = "_") => {
|
||||||
if (where === "caps") where = /(?=[A-Z])/;
|
if (where === "caps") where = /(?=[A-Z])/;
|
||||||
let split = name.split(where);
|
const split = name.split(where);
|
||||||
name = "";
|
name = "";
|
||||||
|
|
||||||
for (let i = 0; i < split.length; i++) {
|
for (let i = 0; i < split.length; i++) {
|
||||||
|
@ -294,7 +294,7 @@ const capitalize = (name: string, where: string | RegExp = "_") => {
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
if (settings.value === null) return false;
|
if (settings.value === null) return false;
|
||||||
let newSettings: ISettings = {
|
const newSettings: ISettings = {
|
||||||
...settings.value,
|
...settings.value,
|
||||||
shell:
|
shell:
|
||||||
settings.value?.shell
|
settings.value?.shell
|
||||||
|
@ -376,7 +376,7 @@ onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
layoutStore.loading = true;
|
layoutStore.loading = true;
|
||||||
const original: ISettings = await api.get();
|
const original: ISettings = await api.get();
|
||||||
let newSettings: ISettings = { ...original, commands: {} };
|
const newSettings: ISettings = { ...original, commands: {} };
|
||||||
|
|
||||||
const keys = Object.keys(original.commands) as Array<keyof SettingsCommand>;
|
const keys = Object.keys(original.commands) as Array<keyof SettingsCommand>;
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
|
|
|
@ -87,12 +87,12 @@ onMounted(async () => {
|
||||||
layoutStore.loading = true;
|
layoutStore.loading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let newLinks = await api.list();
|
const newLinks = await api.list();
|
||||||
if (authStore.user?.perm.admin) {
|
if (authStore.user?.perm.admin) {
|
||||||
let userMap = new Map<number, string>();
|
const userMap = new Map<number, string>();
|
||||||
for (let user of await users.getAll())
|
for (const user of await users.getAll())
|
||||||
userMap.set(user.id, user.username);
|
userMap.set(user.id, user.username);
|
||||||
for (let link of newLinks) {
|
for (const link of newLinks) {
|
||||||
if (link.userID && userMap.has(link.userID))
|
if (link.userID && userMap.has(link.userID))
|
||||||
link.username = userMap.get(link.userID);
|
link.username = userMap.get(link.userID);
|
||||||
}
|
}
|
||||||
|
@ -108,13 +108,23 @@ onMounted(async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const copyToClipboard = (text: string) => {
|
const copyToClipboard = (text: string) => {
|
||||||
copy(text).then(
|
copy({ text }).then(
|
||||||
() => {
|
() => {
|
||||||
// clipboard successfully set
|
// clipboard successfully set
|
||||||
$showSuccess(t("success.linkCopied"));
|
$showSuccess(t("success.linkCopied"));
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
// clipboard write failed
|
// clipboard write failed
|
||||||
|
copy({ text }, { permission: true }).then(
|
||||||
|
() => {
|
||||||
|
// clipboard successfully set
|
||||||
|
$showSuccess(t("success.linkCopied"));
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
// clipboard write failed
|
||||||
|
$showError(e);
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,7 +90,7 @@ const fetchData = async () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (isNew.value) {
|
if (isNew.value) {
|
||||||
let { defaults, createUserDir: _createUserDir } = await settings.get();
|
const { defaults, createUserDir: _createUserDir } = await settings.get();
|
||||||
createUserDir.value = _createUserDir;
|
createUserDir.value = _createUserDir;
|
||||||
user.value = {
|
user.value = {
|
||||||
...defaults,
|
...defaults,
|
||||||
|
|
Loading…
Reference in New Issue