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