diff --git a/backend/controllers/file.ts b/backend/controllers/file.ts
index 2eb591b..eeec46b 100644
--- a/backend/controllers/file.ts
+++ b/backend/controllers/file.ts
@@ -402,11 +402,13 @@ class FileController {
const userID = req.user._id;
let searchQuery = req.query.search || "";
const trashMode = req.query.trashMode === "true";
+ const mediaMode = req.query.mediaMode === "true";
const { fileList, folderList } = await fileService.getSuggestedList(
userID,
searchQuery,
- trashMode
+ trashMode,
+ mediaMode
);
return res.send({ folderList, fileList });
diff --git a/backend/db/utils/fileUtils/index.ts b/backend/db/utils/fileUtils/index.ts
index 496aafd..eaddd07 100644
--- a/backend/db/utils/fileUtils/index.ts
+++ b/backend/db/utils/fileUtils/index.ts
@@ -148,7 +148,8 @@ class DbUtil {
getFileSearchList = async (
userID: string,
searchQuery: RegExp,
- trashMode: boolean
+ trashMode: boolean,
+ mediaMode: boolean
) => {
let query: any = {
"metadata.owner": userID,
@@ -156,6 +157,8 @@ class DbUtil {
"metadata.trashed": trashMode ? true : null,
};
+ if (mediaMode) query = { ...query, "metadata.hasThumbnail": true };
+
const fileList = (await conn.db
.collection("fs.files")
.find(query)
diff --git a/backend/services/FileService/index.ts b/backend/services/FileService/index.ts
index 2b17e49..70a2596 100644
--- a/backend/services/FileService/index.ts
+++ b/backend/services/FileService/index.ts
@@ -128,6 +128,7 @@ class MongoFileService {
const storageType = query.storageType || undefined;
const folderSearch = query.folder_search || undefined;
const trashMode = query.trashMode === "true";
+ const mediaMode = query.mediaMode === "true";
sortBy = sortBySwitch(sortBy);
limit = parseInt(limit);
console.log("sortBy", sortBy, query.sortBy);
@@ -145,7 +146,8 @@ class MongoFileService {
startAtName,
storageType,
folderSearch,
- trashMode
+ trashMode,
+ mediaMode
);
const fileList = await dbUtilsFile.getList(queryObj, sortBy, limit);
@@ -206,23 +208,34 @@ class MongoFileService {
getSuggestedList = async (
userID: string,
searchQuery: any,
- trashMode: boolean
+ trashMode: boolean,
+ mediaMode: boolean
) => {
searchQuery = new RegExp(searchQuery, "i");
const fileList = await dbUtilsFile.getFileSearchList(
userID,
searchQuery,
- trashMode
+ trashMode,
+ mediaMode
);
+
+ if (!fileList) throw new NotFoundError("Suggested List Not Found Error");
+
+ if (mediaMode) {
+ return {
+ fileList,
+ folderList: [],
+ };
+ }
+
const folderList = await dbUtilsFolder.getFolderSearchList(
userID,
searchQuery,
trashMode
);
- if (!fileList || !folderList)
- throw new NotFoundError("Suggested List Not Found Error");
+ if (!folderList) throw new NotFoundError("Suggested List Not Found Error");
return {
fileList,
diff --git a/backend/utils/createQuery.ts b/backend/utils/createQuery.ts
index d6acc31..a560681 100644
--- a/backend/utils/createQuery.ts
+++ b/backend/utils/createQuery.ts
@@ -17,6 +17,7 @@ export interface QueryInterface {
};
"metadata.personalFile"?: boolean | null;
"metadata.trashed"?: boolean | null;
+ "metadata.hasThumbnail"?: boolean | null;
}
const createQuery = (
@@ -30,7 +31,8 @@ const createQuery = (
startAtName: string,
storageType: string,
folderSearch: boolean,
- trashMode: boolean
+ trashMode: boolean,
+ mediaMode: boolean
) => {
let query: QueryInterface = { "metadata.owner": owner };
@@ -71,6 +73,10 @@ const createQuery = (
query = { ...query, "metadata.trashed": null };
}
+ if (mediaMode) {
+ query = { ...query, "metadata.hasThumbnail": true };
+ }
+
// if (storageType === "s3") {
// query = {...query, "metadata.personalFile": true}
// }
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000..552444d
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,26 @@
+import globals from "globals";
+import pluginJs from "@eslint/js";
+import tseslint from "typescript-eslint";
+import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";
+import pluginReactHooks from "eslint-plugin-react-hooks";
+import pluginReact from "eslint-plugin-react";
+
+export default [
+ { files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"] },
+ { languageOptions: { parserOptions: { ecmaFeatures: { jsx: true } } } },
+ { languageOptions: { globals: globals.browser } },
+ pluginJs.configs.recommended,
+ ...tseslint.configs.recommended,
+ {
+ ...pluginReactConfig,
+ plugins: {
+ react: pluginReact,
+ "react-hooks": pluginReactHooks,
+ },
+ rules: {
+ "react/react-in-jsx-scope": "off",
+ "react-hooks/rules-of-hooks": "error",
+ "react-hooks/exhaustive-deps": "error",
+ },
+ },
+];
diff --git a/package.json b/package.json
index d0d1220..9c136bf 100755
--- a/package.json
+++ b/package.json
@@ -35,7 +35,8 @@
"dev-test": "concurrently \"vite\" \"nodemon server.js\"",
"dev-hot": "concurrently \"vite\" \"tsc -w -p ./backend/tsconfig.json\" \"npm run dev:backend\"",
"dev:backend": "nodemon dist/server/serverStart.js",
- "vite-build": "vite build"
+ "vite-build": "vite build",
+ "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'"
},
"dependencies": {
"@babel/core": "^7.8.4",
@@ -82,6 +83,7 @@
"core-js": "^3.6.4",
"diskusage": "^1.1.3",
"dotenv": "^8.2.0",
+ "eslint-plugin-react-hooks": "^4.6.2",
"express": "^4.19.2",
"fluent-ffmpeg": "^2.1.3",
"font-awesome": "^4.7.0",
@@ -117,22 +119,22 @@
"vite": "^5.2.13"
},
"devDependencies": {
+ "@eslint/js": "^9.6.0",
"@types/fluent-ffmpeg": "^2.1.24",
"@types/lodash": "^4.17.5",
- "@typescript-eslint/eslint-plugin": "^2.20.0",
- "@typescript-eslint/parser": "^2.20.0",
"concurrently": "^8.2.2",
"cross-env": "^6.0.3",
"dart-sass": "^1.25.0",
"env-cmd": "^10.1.0",
- "eslint": "^6.8.0",
- "eslint-plugin-import": "^2.20.1",
- "eslint-plugin-react": "^7.18.3",
+ "eslint": "^8.57.0",
+ "eslint-plugin-react": "^7.34.3",
+ "globals": "^15.7.0",
"jest": "^29.7.0",
"nodemon": "^3.1.3",
"sass": "^1.77.4",
"superagent-binary-parser": "^1.0.1",
"supertest": "^6.0.1",
- "tailwindcss": "^3.4.4"
+ "tailwindcss": "^3.4.4",
+ "typescript-eslint": "^7.14.1"
}
}
diff --git a/src/api/filesAPI.ts b/src/api/filesAPI.ts
index 1335016..a70e717 100644
--- a/src/api/filesAPI.ts
+++ b/src/api/filesAPI.ts
@@ -11,6 +11,7 @@ interface QueryKeyParams {
startAtName?: string;
startAt?: boolean;
trashMode?: boolean;
+ mediaMode?: boolean;
}
// GET
@@ -21,7 +22,14 @@ export const getFilesListAPI = async ({
}: QueryFunctionContext<[string, QueryKeyParams]>) => {
const [
_key,
- { parent = "/", search = "", sortBy = "date_desc", limit = 50, trashMode },
+ {
+ parent = "/",
+ search = "",
+ sortBy = "date_desc",
+ limit = 50,
+ trashMode,
+ mediaMode,
+ },
] = queryKey;
const queryParams: QueryKeyParams = {
@@ -30,6 +38,7 @@ export const getFilesListAPI = async ({
sortBy,
limit,
trashMode,
+ mediaMode,
};
if (pageParam?.startAtDate && pageParam?.startAtName) {
@@ -85,13 +94,14 @@ export const getFileThumbnailAPI = async (thumbnailID: string) => {
export const getSuggestedListAPI = async ({
queryKey,
}: QueryFunctionContext<
- [string, { searchText: string; trashMode: boolean }]
+ [string, { searchText: string; trashMode: boolean; mediaMode: boolean }]
>) => {
- const [_key, { searchText, trashMode }] = queryKey;
+ const [_key, { searchText, trashMode, mediaMode }] = queryKey;
const response = await axios.get(`/file-service/suggested-list`, {
params: {
search: searchText,
trashMode,
+ mediaMode,
},
});
return response.data;
diff --git a/src/components/ContextMenu/index.jsx b/src/components/ContextMenu/index.jsx
index bc939a4..7d89ebb 100644
--- a/src/components/ContextMenu/index.jsx
+++ b/src/components/ContextMenu/index.jsx
@@ -36,7 +36,7 @@ const ContextMenu = (props) => {
const { invalidateFoldersCache } = useFoldersClient();
const { invalidateQuickFilesCache } = useQuickFilesClient();
const { wrapperRef } = useClickOutOfBounds(props.closeContext);
- const { isTrash } = useUtils();
+ const { isTrash, isMedia } = useUtils();
const dispatch = useAppDispatch();
const liClassname =
"flex w-full px-[20px] py-[12px] items-center font-normal text-[#637381] justify-start no-underline animate hover:bg-[#f6f5fd] hover:text-[#3c85ee] hover:font-medium";
@@ -230,10 +230,10 @@ const ContextMenu = (props) => {
Media
+ +Drag and drop a file to get started
-
- You are searching in{" "}
-
- {props.parent === "/"
- ? "Home"
- : props.parentNameList.length !== 0
- ? props.parentNameList[props.parentNameList.length - 1]
- : "Unknown"}
- {" "}
-
-
-
- {" "}
-
- Show results from everywhere
-
-