feat: make uploadsLimit into user setting

This commit is contained in:
古大羊 2024-05-07 22:33:45 +08:00
parent be62f56782
commit 2cc8ea5dae
12 changed files with 73 additions and 25 deletions

View File

@ -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) => {

View File

@ -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",

View File

@ -236,7 +236,8 @@
"userManagement": "用户管理", "userManagement": "用户管理",
"userUpdated": "用户已更新!", "userUpdated": "用户已更新!",
"username": "用户名", "username": "用户名",
"users": "用户" "users": "用户",
"uploadsLimit":"上传并行任务数限制"
}, },
"sidebar": { "sidebar": {
"help": "帮助", "help": "帮助",

View File

@ -236,7 +236,8 @@
"userManagement": "使用者管理", "userManagement": "使用者管理",
"userUpdated": "使用者已更新!", "userUpdated": "使用者已更新!",
"username": "使用者名稱", "username": "使用者名稱",
"users": "使用者" "users": "使用者",
"uploadsLimit":"上傳並行任務數限制"
}, },
"sidebar": { "sidebar": {
"help": "幫助", "help": "幫助",

View File

@ -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) {

View File

@ -20,6 +20,7 @@ interface SettingsDefaults {
commands: any[]; commands: any[];
hideDotfiles: boolean; hideDotfiles: boolean;
dateFormat: boolean; dateFormat: boolean;
uploadsLimit:number;
} }
interface SettingsBranding { interface SettingsBranding {

View File

@ -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 {

View File

@ -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);
} }
} }

View File

@ -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 = () => {

View File

@ -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"));

View File

@ -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()),

View File

@ -17,6 +17,8 @@ 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.