feat: make uploadsLimit into user setting
This commit is contained in:
parent
be62f56782
commit
2cc8ea5dae
@ -37,11 +37,13 @@ import { useI18n } from "vue-i18n";
|
|||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { useFileStore } from "@/stores/file";
|
import { useFileStore } from "@/stores/file";
|
||||||
import { useLayoutStore } from "@/stores/layout";
|
import { useLayoutStore } from "@/stores/layout";
|
||||||
|
import { useAuthStore } from "@/stores/auth";
|
||||||
|
|
||||||
import * as upload from "@/utils/upload";
|
import * as upload from "@/utils/upload";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
const fileStore = useFileStore();
|
const fileStore = useFileStore();
|
||||||
const layoutStore = useLayoutStore();
|
const layoutStore = useLayoutStore();
|
||||||
@ -54,6 +56,11 @@ const uploadInput = (event: Event) => {
|
|||||||
if (files === null) return;
|
if (files === null) return;
|
||||||
|
|
||||||
let folder_upload = !!files[0].webkitRelativePath;
|
let folder_upload = !!files[0].webkitRelativePath;
|
||||||
|
let uploadsLimit = 1
|
||||||
|
if (authStore.user!=null){
|
||||||
|
uploadsLimit = authStore.user.uploadsLimit
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const uploadFiles: UploadList = [];
|
const uploadFiles: UploadList = [];
|
||||||
for (let i = 0; i < files.length; i++) {
|
for (let i = 0; i < files.length; i++) {
|
||||||
@ -77,19 +84,19 @@ const uploadInput = (event: Event) => {
|
|||||||
action: (event: Event) => {
|
action: (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
layoutStore.closeHovers();
|
layoutStore.closeHovers();
|
||||||
upload.handleFiles(uploadFiles, path, false);
|
upload.handleFiles(uploadFiles, path, uploadsLimit);
|
||||||
},
|
},
|
||||||
confirm: (event: Event) => {
|
confirm: (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
layoutStore.closeHovers();
|
layoutStore.closeHovers();
|
||||||
upload.handleFiles(uploadFiles, path, true);
|
upload.handleFiles(uploadFiles, path, uploadsLimit, true);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
upload.handleFiles(uploadFiles, path);
|
upload.handleFiles(uploadFiles, path, uploadsLimit);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openUpload = (isFolder: boolean) => {
|
const openUpload = (isFolder: boolean) => {
|
||||||
|
|||||||
@ -236,7 +236,8 @@
|
|||||||
"userManagement": "User Management",
|
"userManagement": "User Management",
|
||||||
"userUpdated": "User updated!",
|
"userUpdated": "User updated!",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
"users": "Users"
|
"users": "Users",
|
||||||
|
"uploadsLimit":"Limit of concurrent uploads"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Help",
|
"help": "Help",
|
||||||
|
|||||||
@ -236,7 +236,8 @@
|
|||||||
"userManagement": "用户管理",
|
"userManagement": "用户管理",
|
||||||
"userUpdated": "用户已更新!",
|
"userUpdated": "用户已更新!",
|
||||||
"username": "用户名",
|
"username": "用户名",
|
||||||
"users": "用户"
|
"users": "用户",
|
||||||
|
"uploadsLimit":"上传并行任务数限制"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "帮助",
|
"help": "帮助",
|
||||||
|
|||||||
@ -236,7 +236,8 @@
|
|||||||
"userManagement": "使用者管理",
|
"userManagement": "使用者管理",
|
||||||
"userUpdated": "使用者已更新!",
|
"userUpdated": "使用者已更新!",
|
||||||
"username": "使用者名稱",
|
"username": "使用者名稱",
|
||||||
"users": "使用者"
|
"users": "使用者",
|
||||||
|
"uploadsLimit":"上傳並行任務數限制"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "幫助",
|
"help": "幫助",
|
||||||
|
|||||||
@ -4,8 +4,6 @@ import { files as api } from "@/api";
|
|||||||
import throttle from "lodash/throttle";
|
import throttle from "lodash/throttle";
|
||||||
import buttons from "@/utils/buttons";
|
import buttons from "@/utils/buttons";
|
||||||
|
|
||||||
// TODO: make this into a user setting
|
|
||||||
const UPLOADS_LIMIT = 5;
|
|
||||||
|
|
||||||
const beforeUnload = (event: Event) => {
|
const beforeUnload = (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -145,7 +143,7 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
removeJob(id: number) {
|
removeJob(id: number) {
|
||||||
delete this.uploads[id];
|
delete this.uploads[id];
|
||||||
},
|
},
|
||||||
upload(item: UploadItem) {
|
upload(item: UploadItem,uploadsLimit:number) {
|
||||||
const uploadsCount = Object.keys(this.uploads).length;
|
const uploadsCount = Object.keys(this.uploads).length;
|
||||||
|
|
||||||
const isQueueEmpty = this.queue.length == 0;
|
const isQueueEmpty = this.queue.length == 0;
|
||||||
@ -157,17 +155,17 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.addJob(item);
|
this.addJob(item);
|
||||||
this.processUploads();
|
this.processUploads(uploadsLimit);
|
||||||
},
|
},
|
||||||
finishUpload(item: UploadItem) {
|
finishUpload(item: UploadItem,uploadsLimit:number) {
|
||||||
this.setProgress({ id: item.id, loaded: item.file.size > 0 });
|
this.setProgress({ id: item.id, loaded: item.file.size > 0 });
|
||||||
this.removeJob(item.id);
|
this.removeJob(item.id);
|
||||||
this.processUploads();
|
this.processUploads(uploadsLimit);
|
||||||
},
|
},
|
||||||
async processUploads() {
|
async processUploads(uploadsLimit:number) {
|
||||||
const uploadsCount = Object.keys(this.uploads).length;
|
const uploadsCount = Object.keys(this.uploads).length;
|
||||||
|
|
||||||
const isBellowLimit = uploadsCount < UPLOADS_LIMIT;
|
const isBellowLimit = uploadsCount < uploadsLimit;
|
||||||
const isQueueEmpty = this.queue.length == 0;
|
const isQueueEmpty = this.queue.length == 0;
|
||||||
const isUploadsEmpty = uploadsCount == 0;
|
const isUploadsEmpty = uploadsCount == 0;
|
||||||
|
|
||||||
@ -204,7 +202,7 @@ export const useUploadStore = defineStore("upload", {
|
|||||||
.catch(this.setError);
|
.catch(this.setError);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.finishUpload(item);
|
this.finishUpload(item,uploadsLimit);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setUploadSpeed(value: number) {
|
setUploadSpeed(value: number) {
|
||||||
|
|||||||
1
frontend/src/types/settings.d.ts
vendored
1
frontend/src/types/settings.d.ts
vendored
@ -20,6 +20,7 @@ interface SettingsDefaults {
|
|||||||
commands: any[];
|
commands: any[];
|
||||||
hideDotfiles: boolean;
|
hideDotfiles: boolean;
|
||||||
dateFormat: boolean;
|
dateFormat: boolean;
|
||||||
|
uploadsLimit:number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SettingsBranding {
|
interface SettingsBranding {
|
||||||
|
|||||||
2
frontend/src/types/user.d.ts
vendored
2
frontend/src/types/user.d.ts
vendored
@ -13,6 +13,7 @@ interface IUser {
|
|||||||
dateFormat: boolean;
|
dateFormat: boolean;
|
||||||
viewMode: ViewModeType;
|
viewMode: ViewModeType;
|
||||||
sorting?: Sorting;
|
sorting?: Sorting;
|
||||||
|
uploadsLimit:number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ViewModeType = "list" | "mosaic" | "mosaic gallery";
|
type ViewModeType = "list" | "mosaic" | "mosaic gallery";
|
||||||
@ -30,6 +31,7 @@ interface IUserForm {
|
|||||||
hideDotfiles?: boolean;
|
hideDotfiles?: boolean;
|
||||||
singleClick?: boolean;
|
singleClick?: boolean;
|
||||||
dateFormat?: boolean;
|
dateFormat?: boolean;
|
||||||
|
uploadsLimit:number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Permissions {
|
interface Permissions {
|
||||||
|
|||||||
@ -123,7 +123,8 @@ function detectType(mimetype: string): ResourceType {
|
|||||||
export function handleFiles(
|
export function handleFiles(
|
||||||
files: UploadList,
|
files: UploadList,
|
||||||
base: string,
|
base: string,
|
||||||
overwrite = false
|
uploadsLimit:number,
|
||||||
|
overwrite = false,
|
||||||
) {
|
) {
|
||||||
const uploadStore = useUploadStore();
|
const uploadStore = useUploadStore();
|
||||||
|
|
||||||
@ -149,6 +150,6 @@ export function handleFiles(
|
|||||||
...(!file.isDir && { type: detectType((file.file as File).type) }),
|
...(!file.isDir && { type: detectType((file.file as File).type) }),
|
||||||
};
|
};
|
||||||
|
|
||||||
uploadStore.upload(item);
|
uploadStore.upload(item,uploadsLimit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -731,25 +731,30 @@ const drop = async (event: DragEvent) => {
|
|||||||
|
|
||||||
let conflict = upload.checkConflict(files, items);
|
let conflict = upload.checkConflict(files, items);
|
||||||
|
|
||||||
|
let uploadsLimit = 1
|
||||||
|
if (authStore.user!=null){
|
||||||
|
uploadsLimit = authStore.user.uploadsLimit
|
||||||
|
}
|
||||||
|
|
||||||
if (conflict) {
|
if (conflict) {
|
||||||
layoutStore.showHover({
|
layoutStore.showHover({
|
||||||
prompt: "replace",
|
prompt: "replace",
|
||||||
action: (event: Event) => {
|
action: (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
layoutStore.closeHovers();
|
layoutStore.closeHovers();
|
||||||
upload.handleFiles(files, path, false);
|
upload.handleFiles(files, path,uploadsLimit);
|
||||||
},
|
},
|
||||||
confirm: (event: Event) => {
|
confirm: (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
layoutStore.closeHovers();
|
layoutStore.closeHovers();
|
||||||
upload.handleFiles(files, path, true);
|
upload.handleFiles(files, path,uploadsLimit, true,);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
upload.handleFiles(files, path);
|
upload.handleFiles(files, path,uploadsLimit);
|
||||||
};
|
};
|
||||||
|
|
||||||
const uploadInput = (event: Event) => {
|
const uploadInput = (event: Event) => {
|
||||||
@ -776,25 +781,30 @@ const uploadInput = (event: Event) => {
|
|||||||
let path = route.path.endsWith("/") ? route.path : route.path + "/";
|
let path = route.path.endsWith("/") ? route.path : route.path + "/";
|
||||||
let conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
|
let conflict = upload.checkConflict(uploadFiles, fileStore.req!.items);
|
||||||
|
|
||||||
|
let uploadsLimit = 1
|
||||||
|
if (authStore.user!=null){
|
||||||
|
uploadsLimit = authStore.user.uploadsLimit
|
||||||
|
}
|
||||||
|
|
||||||
if (conflict) {
|
if (conflict) {
|
||||||
layoutStore.showHover({
|
layoutStore.showHover({
|
||||||
prompt: "replace",
|
prompt: "replace",
|
||||||
action: (event: Event) => {
|
action: (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
layoutStore.closeHovers();
|
layoutStore.closeHovers();
|
||||||
upload.handleFiles(uploadFiles, path, false);
|
upload.handleFiles(uploadFiles, path, uploadsLimit);
|
||||||
},
|
},
|
||||||
confirm: (event: Event) => {
|
confirm: (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
layoutStore.closeHovers();
|
layoutStore.closeHovers();
|
||||||
upload.handleFiles(uploadFiles, path, true);
|
upload.handleFiles(uploadFiles, path, uploadsLimit,true);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
upload.handleFiles(uploadFiles, path);
|
upload.handleFiles(uploadFiles, path,uploadsLimit);
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetOpacity = () => {
|
const resetOpacity = () => {
|
||||||
|
|||||||
@ -19,11 +19,18 @@
|
|||||||
<input type="checkbox" name="dateFormat" v-model="dateFormat" />
|
<input type="checkbox" name="dateFormat" v-model="dateFormat" />
|
||||||
{{ t("settings.setDateFormat") }}
|
{{ t("settings.setDateFormat") }}
|
||||||
</p>
|
</p>
|
||||||
|
<h3>{{ t("settings.uploadsLimit") }}</h3>
|
||||||
|
<vue-number-input
|
||||||
|
controls
|
||||||
|
v-model.number="uploadsLimit"
|
||||||
|
:min="1" :max="10"
|
||||||
|
/>
|
||||||
<h3>{{ t("settings.language") }}</h3>
|
<h3>{{ t("settings.language") }}</h3>
|
||||||
<languages
|
<languages
|
||||||
class="input input--block"
|
class="input input--block"
|
||||||
v-model:locale="locale"
|
v-model:locale="locale"
|
||||||
></languages>
|
></languages>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-action">
|
<div class="card-action">
|
||||||
@ -98,6 +105,7 @@ const hideDotfiles = ref<boolean>(false);
|
|||||||
const singleClick = ref<boolean>(false);
|
const singleClick = ref<boolean>(false);
|
||||||
const dateFormat = ref<boolean>(false);
|
const dateFormat = ref<boolean>(false);
|
||||||
const locale = ref<string>("");
|
const locale = ref<string>("");
|
||||||
|
const uploadsLimit = ref<number>(0);
|
||||||
|
|
||||||
const passwordClass = computed(() => {
|
const passwordClass = computed(() => {
|
||||||
const baseClass = "input input--block";
|
const baseClass = "input input--block";
|
||||||
@ -120,6 +128,7 @@ onMounted(() => {
|
|||||||
hideDotfiles.value = authStore.user.hideDotfiles;
|
hideDotfiles.value = authStore.user.hideDotfiles;
|
||||||
singleClick.value = authStore.user.singleClick;
|
singleClick.value = authStore.user.singleClick;
|
||||||
dateFormat.value = authStore.user.dateFormat;
|
dateFormat.value = authStore.user.dateFormat;
|
||||||
|
uploadsLimit.value = authStore.user.uploadsLimit;
|
||||||
layoutStore.loading = false;
|
layoutStore.loading = false;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
@ -163,6 +172,7 @@ const updateSettings = async (event: Event) => {
|
|||||||
hideDotfiles: hideDotfiles.value,
|
hideDotfiles: hideDotfiles.value,
|
||||||
singleClick: singleClick.value,
|
singleClick: singleClick.value,
|
||||||
dateFormat: dateFormat.value,
|
dateFormat: dateFormat.value,
|
||||||
|
uploadsLimit:uploadsLimit.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
await api.update(data, [
|
await api.update(data, [
|
||||||
@ -170,6 +180,7 @@ const updateSettings = async (event: Event) => {
|
|||||||
"hideDotfiles",
|
"hideDotfiles",
|
||||||
"singleClick",
|
"singleClick",
|
||||||
"dateFormat",
|
"dateFormat",
|
||||||
|
"uploadsLimit",
|
||||||
]);
|
]);
|
||||||
authStore.updateUser(data);
|
authStore.updateUser(data);
|
||||||
$showSuccess(t("settings.settingsUpdated"));
|
$showSuccess(t("settings.settingsUpdated"));
|
||||||
|
|||||||
@ -30,6 +30,7 @@ type userInfo struct {
|
|||||||
LockPassword bool `json:"lockPassword"`
|
LockPassword bool `json:"lockPassword"`
|
||||||
HideDotfiles bool `json:"hideDotfiles"`
|
HideDotfiles bool `json:"hideDotfiles"`
|
||||||
DateFormat bool `json:"dateFormat"`
|
DateFormat bool `json:"dateFormat"`
|
||||||
|
UploadsLimit uint `json:"uploadsLimit"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type authToken struct {
|
type authToken struct {
|
||||||
@ -195,6 +196,7 @@ func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.Use
|
|||||||
Commands: user.Commands,
|
Commands: user.Commands,
|
||||||
HideDotfiles: user.HideDotfiles,
|
HideDotfiles: user.HideDotfiles,
|
||||||
DateFormat: user.DateFormat,
|
DateFormat: user.DateFormat,
|
||||||
|
UploadsLimit: user.GetUploadsLimit(),
|
||||||
},
|
},
|
||||||
RegisteredClaims: jwt.RegisteredClaims{
|
RegisteredClaims: jwt.RegisteredClaims{
|
||||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||||
|
|||||||
@ -15,8 +15,10 @@ import (
|
|||||||
type ViewMode string
|
type ViewMode string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ListViewMode ViewMode = "list"
|
ListViewMode ViewMode = "list"
|
||||||
MosaicViewMode ViewMode = "mosaic"
|
MosaicViewMode ViewMode = "mosaic"
|
||||||
|
DefaultUploadsLimit = uint(5)
|
||||||
|
MaxUploadsLimit = uint(10)
|
||||||
)
|
)
|
||||||
|
|
||||||
// User describes a user.
|
// User describes a user.
|
||||||
@ -36,6 +38,17 @@ type User struct {
|
|||||||
Rules []rules.Rule `json:"rules"`
|
Rules []rules.Rule `json:"rules"`
|
||||||
HideDotfiles bool `json:"hideDotfiles"`
|
HideDotfiles bool `json:"hideDotfiles"`
|
||||||
DateFormat bool `json:"dateFormat"`
|
DateFormat bool `json:"dateFormat"`
|
||||||
|
UploadsLimit uint `json:"uploadsLimit"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *User) GetUploadsLimit() uint {
|
||||||
|
if u.UploadsLimit == 0 {
|
||||||
|
return DefaultUploadsLimit
|
||||||
|
}
|
||||||
|
if u.UploadsLimit > MaxUploadsLimit {
|
||||||
|
return MaxUploadsLimit
|
||||||
|
}
|
||||||
|
return u.UploadsLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRules implements rules.Provider.
|
// GetRules implements rules.Provider.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user