added media mode and linter

This commit is contained in:
subnub
2024-07-01 02:51:23 -04:00
parent 006f8227d7
commit e36aeaa6aa
25 changed files with 473 additions and 200 deletions
+13 -3
View File
@@ -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;
+4 -4
View File
@@ -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) => {
<span className={spanClassname}>
<MultiSelectIcon className="w-[19px] h-[20px]" />
</span>
Multi select
Multi-select
</a>
</li>
{!isTrash && (
{!isTrash && !isMedia && (
<li onClick={renameItem} className={liClassname}>
<a className="flex">
<span className={spanClassname}>
@@ -263,7 +263,7 @@ const ContextMenu = (props) => {
</a>
</li>
) : undefined}
{!isTrash && (
{!isTrash && !isMedia && (
<li onClick={openMoveItemModal} className={liClassname}>
<a className="flex" data-modal="destination__modal">
<span className={spanClassname}>
+3 -1
View File
@@ -73,7 +73,9 @@ const DataForm = memo(() => {
>
{!isLoading && (
<div>
<MultiSelectBar />
<div className="fixed bottom-0 flex justify-center items-center right-0 left-0">
<MultiSelectBar />
</div>
<QuickAccess />
+4 -2
View File
@@ -66,8 +66,10 @@ const FileItem = React.memo((props) => {
);
// TODO: See if we can memoize this
const fileClick = () => {
if (multiSelectMode) {
const fileClick = (e) => {
const multiSelectKey = e.metaKey || e.ctrlKey;
if (multiSelectMode | multiSelectKey) {
dispatch(
setMultiSelectMode({
type: "file",
+1 -1
View File
@@ -103,7 +103,7 @@ const Files = memo(() => {
{!listView ? (
<div
className={classNames(
"grid grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fit,minmax(185px,185px))] gap-[20px]",
"grid grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fill,minmax(160px,1fr))] gap-[16px]",
files?.pages[0]?.length > 1
? "justify-center xs:justify-normal"
: "justify-normal"
+48 -44
View File
@@ -38,52 +38,56 @@ const FolderItem = React.memo((props) => {
...contextMenuState
} = useContextMenu();
const folderClick = useCallback(() => {
if (multiSelectMode) {
dispatch(
setMultiSelectMode({
type: "folder",
id: folder._id,
file: null,
folder: folder,
})
);
return;
}
const currentDate = Date.now();
if (!elementSelected) {
dispatch(
setMainSelect({
file: null,
id: folder._id,
type: "folder",
folder: folder,
})
);
lastSelected.current = Date.now();
return;
}
const isMobile = mobilecheck();
if (isMobile || currentDate - lastSelected.current < 1500) {
if (isTrash) {
navigate(`/folder-trash/${folder._id}`);
} else {
navigate(`/folder/${folder._id}`);
const folderClick = useCallback(
(e) => {
const multiSelectKey = e.metaKey || e.ctrlKey;
if (multiSelectMode || multiSelectKey) {
dispatch(
setMultiSelectMode({
type: "folder",
id: folder._id,
file: null,
folder: folder,
})
);
return;
}
}
const currentDate = Date.now();
lastSelected.current = Date.now();
}, [
startSetSelectedItem,
mobilecheck,
navigate,
folder._id,
elementSelected,
multiSelectMode,
]);
if (!elementSelected) {
dispatch(
setMainSelect({
file: null,
id: folder._id,
type: "folder",
folder: folder,
})
);
lastSelected.current = Date.now();
return;
}
const isMobile = mobilecheck();
if (isMobile || currentDate - lastSelected.current < 1500) {
if (isTrash) {
navigate(`/folder-trash/${folder._id}`);
} else {
navigate(`/folder/${folder._id}`);
}
}
lastSelected.current = Date.now();
},
[
startSetSelectedItem,
mobilecheck,
navigate,
folder._id,
elementSelected,
multiSelectMode,
]
);
return (
<div
+1 -1
View File
@@ -116,7 +116,7 @@ const Folders = memo(() => {
<div
className={classNames(
"grid grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fit,minmax(185px,185px))] gap-[20px]",
"grid grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fill,minmax(160px,1fr))] gap-[16px]",
folders?.length > 1
? "justify-center xs:justify-normal"
: "justify-normal"
+24 -1
View File
@@ -8,10 +8,11 @@ import AddNewDropdown from "../AddNewDropdown";
import HomeListIcon from "../../icons/HomeListIcon";
import TrashIcon from "../../icons/TrashIcon";
import classNames from "classnames";
import PhotoIcon from "../../icons/PhotoIcon";
const LeftSection = (props) => {
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const { isHome, isTrash } = useUtils();
const { isHome, isTrash, isMedia } = useUtils();
const navigate = useNavigate();
const addNewDisabled = useRef(false);
@@ -35,6 +36,10 @@ const LeftSection = (props) => {
navigate("/trash");
};
const goMedia = () => {
navigate("/media");
};
return (
<div
className="menu__block p-6 hidden mobileMode:block border-r w-[270px] min-w-[270px]"
@@ -80,6 +85,24 @@ const LeftSection = (props) => {
</ul>
</div>
</div>
<div className="border-t border-[#E8EEF2] pr-[20px] pt-3 pb-3">
<ul className="m-0 list-none p-0 cursor-pointer ">
<li>
<a
onClick={goMedia}
className={classNames(
"flex items-center text-[#3c85ee] font-medium no-underline animate",
isMedia ? "text-[#3c85ee]" : "text-[#637381]"
)}
>
<span>
<PhotoIcon className="w-[20px] h-[20px]" />
</span>
<p className="ml-3">Media</p>
</a>
</li>
</ul>
</div>
<div className="border-t border-[#E8EEF2] pr-[20px] pt-4">
<ul className="m-0 list-none p-0 cursor-pointer ">
<li>
+6 -88
View File
@@ -5,106 +5,24 @@ import PopupWindow from "../PopupWindow";
import React, { memo } from "react";
import LeftSection from "../LeftSection";
import { useSelector } from "react-redux";
import { useUtils } from "../../hooks/utils";
import Medias from "../Medias";
const MainSection = memo(() => {
const moverID = useSelector((state) => state.mover.id);
const showPopup = useSelector((state) => state.popupFile.showPopup);
const { isMedia } = useUtils();
return (
<div>
{/* <div
className="overlay"
style={
props.leftSectionMode === "open" || props.rightSectionMode === "open"
? { display: "block" }
: { display: "none" }
}
></div>
<div className="small__switcher--content">
<a onClick={props.switchLeftSectionMode} className="menu__button">
<i className="fas fa-bars"></i>
</a>
<a onClick={props.switchRightSectionMode} className="image__viewer">
<i className="fas fa-images"></i>
</a>
</div> */}
<div
className="flex h-full"
// style={
// props.routeType === "search"
// ? { flexDirection: "column" }
// : { flexDirection: "row" }
// }
>
{/* {true ? undefined : (
<div className="file__control--panel empty__control--panel">
<div className="file__get--started">
<div className="get__started--image">
<img src="/assets/get_startedfile.svg" alt="get" />
</div>
<h6>All your files in one place</h6>
<p>Drag and drop a file to get started</p>
</div>
</div>
)} */}
{/* {props.routeType === "search" ? (
<div
className="file__control--panel folder__view"
style={{ paddingBottom: "0", marginBottom: "-50px" }}
>
<div className="results__files">
<h2>
<span className="counter__result">
{props.files.length + props.folders.length >= 50
? "50+"
: props.files.length + props.folders.length}
</span>{" "}
<span className="result__word">results</span> for{" "}
<span className="result__search--word">
{props.cachedSearch}
</span>
</h2>
<p className="searching__result">
You are searching in{" "}
<span className="root__parent">
{props.parent === "/"
? "Home"
: props.parentNameList.length !== 0
? props.parentNameList[props.parentNameList.length - 1]
: "Unknown"}
</span>{" "}
<span className="spacer">
<img
style={{
height: "11px",
marginTop: "2px",
display: "none",
}}
src="/assets/smallspacer.svg"
alt="spacer"
/>
</span>
<span className="current__folder"></span>{" "}
<a
href="#"
style={{ display: "none" }}
className="search__filter--global"
>
Show results from everywhere
</a>
</p>
</div>
</div>
) : undefined} */}
<div className="flex h-full">
{showPopup ? <PopupWindow /> : undefined}
{moverID.length === 0 ? undefined : <MoverMenu />}
<div className="flex flex-row h-screen w-screen pt-16">
<LeftSection goHome={() => {}} />
<LeftSection />
<DataForm />
{!isMedia ? <DataForm /> : <Medias />}
<RightSection />
</div>
+119
View File
@@ -0,0 +1,119 @@
import React, { useRef } from "react";
import { FileInterface } from "../../types/file";
import { useThumbnail } from "../../hooks/files";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { setMainSelect, setMultiSelectMode } from "../../reducers/selected";
import mobilecheck from "../../utils/mobileCheck";
import { setPopupFile } from "../../actions/popupFile";
import classNames from "classnames";
import { useContextMenu } from "../../hooks/contextMenu";
import ContextMenu from "../ContextMenu";
import PlayButtonIcon from "../../icons/PlayIcon";
type MediaItemType = {
file: FileInterface;
};
const MediaItem: React.FC<MediaItemType> = ({ file }) => {
const elementSelected = useAppSelector((state) => {
if (state.selected.mainSection.type !== "file") return false;
return state.selected.mainSection.id === file._id;
});
const elementMultiSelected = useAppSelector((state) => {
if (!state.selected.multiSelectMode) return false;
const selected = state.selected.multiSelectMap[file._id];
return selected && selected.type === "file";
});
const multiSelectMode = useAppSelector(
(state) => state.selected.multiSelectMode
);
const {
onContextMenu,
closeContextMenu,
onTouchStart,
onTouchMove,
onTouchEnd,
clickStopPropagation,
...contextMenuState
} = useContextMenu();
const lastSelected = useRef(0);
const dispatch = useAppDispatch();
const { image, imageOnError } = useThumbnail(
file.metadata.hasThumbnail,
file.metadata.thumbnailID
);
// TODO: See if we can memoize this and remove any
const mediaItemClick = (e: any) => {
const multiSelectKey = e.metaKey || e.ctrlKey;
if (multiSelectMode || multiSelectKey) {
dispatch(
setMultiSelectMode({
type: "file",
id: file._id,
file: file,
folder: null,
})
);
return;
}
const currentDate = Date.now();
if (!elementSelected) {
// dispatch(startSetSelectedItem(file._id, true, true));
dispatch(
setMainSelect({ file, id: file._id, type: "file", folder: null })
);
lastSelected.current = Date.now();
return;
}
const isMobile = mobilecheck();
if (isMobile || currentDate - lastSelected.current < 1500) {
dispatch(setPopupFile({ showPopup: true, ...file }));
}
lastSelected.current = Date.now();
};
return (
<div
className={classNames(
"h-[100px] bg-black overflow-hidden rounded-md cursor-pointer relative",
{
"border-4 border-[#3c85ee]": elementSelected || elementMultiSelected,
}
)}
onClick={mediaItemClick}
onContextMenu={onContextMenu}
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
onTouchEnd={onTouchEnd}
>
{contextMenuState.selected && (
<div onClick={clickStopPropagation}>
<ContextMenu
gridMode={true}
quickItemMode={false}
contextSelected={contextMenuState}
closeContext={closeContextMenu}
file={file}
/>
</div>
)}
{file.metadata.isVideo && (
<div className="w-full h-full absolute flex justify-center items-center text-white">
<PlayButtonIcon className="w-[50px] h-[50px]" />
</div>
)}
<img
className="object-cover h-full w-full"
src={image}
onError={imageOnError}
/>
</div>
);
};
export default MediaItem;
+52
View File
@@ -0,0 +1,52 @@
import classNames from "classnames";
import React, { useEffect, useMemo, useState } from "react";
import MediaItem from "../MediaItem";
import { useFiles, useThumbnail } from "../../hooks/files";
import MultiSelectBar from "../MultiSelectBar";
import { useInfiniteScroll } from "../../hooks/infiniteScroll";
const Medias = () => {
const {
data: files,
isFetchingNextPage,
fetchNextPage: filesFetchNextPage,
} = useFiles();
const [initialLoad, setInitialLoad] = useState(true);
const { sentinelRef, reachedIntersect } = useInfiniteScroll();
useEffect(() => {
if (initialLoad) {
setInitialLoad(false);
return;
} else if (!files) {
return;
}
if (reachedIntersect && !isFetchingNextPage) {
filesFetchNextPage();
}
}, [reachedIntersect, initialLoad, isFetchingNextPage]);
return (
<div className="w-full p-[17px_15px] mobileMode:p-[17px_40px] overflow-y-scroll">
<div className="fixed bottom-0 flex justify-center items-center right-0 left-0">
<MultiSelectBar />
</div>
<div
className={classNames(
"grid grid-cols-[repeat(auto-fill,minmax(100px,1fr))] gap-[10px]"
)}
>
{files?.pages.map((filePage, index) => (
<React.Fragment key={index}>
{filePage.map((file) => (
<MediaItem file={file} key={file._id} />
))}
</React.Fragment>
))}
</div>
<div ref={sentinelRef} className="h-1"></div>
</div>
);
};
export default Medias;
+29 -8
View File
@@ -1,7 +1,6 @@
import React, { useEffect, useMemo, useRef } from "react";
import React, { useCallback, useEffect, useMemo, useRef } from "react";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { resetMultiSelect } from "../../reducers/selected";
import Swal from "sweetalert2";
import {
deleteMultiAPI,
restoreMultiAPI,
@@ -19,7 +18,7 @@ import {
import RestoreIcon from "../../icons/RestoreIcon";
import { useUtils } from "../../hooks/utils";
const MultiSelectBar = () => {
const MultiSelectBar: React.FC = () => {
const dispatch = useAppDispatch();
const ignoreFirstMount = useRef(true);
const multiSelectMode = useAppSelector(
@@ -35,7 +34,7 @@ const MultiSelectBar = () => {
const { invalidateFoldersCache } = useFoldersClient();
const { invalidateQuickFilesCache } = useQuickFilesClient();
const { isTrash } = useUtils();
const { isTrash, isMedia } = useUtils();
useEffect(() => {
if (ignoreFirstMount.current) {
@@ -45,9 +44,26 @@ const MultiSelectBar = () => {
}
}, [isTrash]);
const closeMultiSelect = () => {
const closeMultiSelect = useCallback(() => {
dispatch(resetMultiSelect());
};
}, []);
const handleKeyDown = useCallback(
(e: KeyboardEvent) => {
if (e.key === "Escape" || e.key === "Esc") {
closeMultiSelect();
}
},
[closeMultiSelect]
);
useEffect(() => {
document.addEventListener("keydown", handleKeyDown);
return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}, []);
const trashItems = async () => {
const result = await trashItemsPopup();
@@ -91,7 +107,7 @@ const MultiSelectBar = () => {
return (
<div className="flex justify-center items-center">
<div className="border border-[#ebe9f9] bg-[#ebe9f9] rounded-full p-2 px-5 text-black text-sm mb-4 max-w-[600px] w-full mt-4">
<div className="border border-[#ebe9f9] bg-[#ebe9f9] rounded-full p-2 px-5 text-black text-sm mb-4 max-w-[600px] w-full mt-4 min-w-[300px] shadow-lg">
<div className="flex flex-row items-center justify-between">
<div className="flex flex-row items-center">
<img
@@ -109,7 +125,12 @@ const MultiSelectBar = () => {
className="ml-4 cursor-pointer"
onClick={trashItems}
/>
<Moveicon className="ml-4 cursor-pointer" onClick={() => {}} />
{!isMedia && (
<Moveicon
className="ml-4 cursor-pointer"
onClick={() => {}}
/>
)}
</React.Fragment>
)}
{isTrash && (
+1 -1
View File
@@ -39,7 +39,7 @@ const QuickAccess = memo(() => {
<div
className={classNames(
"grid animate-movement grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fit,minmax(185px,185px))] gap-[20px]",
"grid animate-movement grid-cols-[repeat(auto-fit,minmax(40%,45%))] xs:grid-cols-[repeat(auto-fill,minmax(160px,1fr))] gap-[16px]",
quickfilesList?.length > 1
? "justify-center xs:justify-normal"
: "justify-normal",
+4 -3
View File
@@ -61,9 +61,10 @@ const QuickAccessItem = memo((props: QuickAccessItemProps) => {
[file.filename]
);
// TODO: See if we can memoize this
const quickItemClick = () => {
if (multiSelectMode) {
// TODO: See if we can memoize this and remove any
const quickItemClick = (e: any) => {
const multiSelectKey = e.metaKey || e.ctrlKey;
if (multiSelectMode || multiSelectKey) {
dispatch(
setMultiSelectMode({
type: "quick-item",
+23 -6
View File
@@ -10,6 +10,7 @@ import { FileInterface } from "../../types/file";
import { setPopupFile } from "../../actions/popupFile";
import Spinner from "../Spinner";
import classNames from "classnames";
import { is } from "@babel/types";
const SearchBar = memo(() => {
const [searchText, setSearchText] = useState("");
@@ -18,7 +19,7 @@ const SearchBar = memo(() => {
const { data: searchSuggestions, isLoading: isLoadingSearchSuggestions } =
useSearchSuggestions(debouncedSearchText);
const navigate = useNavigate();
const { isTrash } = useUtils();
const { isTrash, isMedia } = useUtils();
const debouncedSetSearchText = useMemo(
() => debounce(setDebouncedSearchText, 500),
@@ -44,18 +45,24 @@ const SearchBar = memo(() => {
e.preventDefault();
setSearchText("");
setDebouncedSearchText("");
if (!isTrash) {
if (isMedia) {
if (searchText.length) {
navigate(`/search/${searchText}`);
navigate(`/search-media/${searchText}`);
} else {
navigate("/home");
navigate("/media");
}
} else {
} else if (isTrash) {
if (searchText.length) {
navigate(`/search-trash/${searchText}`);
} else {
navigate("/trash");
}
} else {
if (searchText.length) {
navigate(`/search/${searchText}`);
} else {
navigate("/home");
}
}
};
@@ -78,6 +85,16 @@ const SearchBar = memo(() => {
resetState();
};
const searchTextPlaceholder = useMemo(() => {
if (isMedia) {
return "Search Media";
} else if (isTrash) {
return "Search Trash";
} else {
return "Search";
}
}, [isMedia, isTrash]);
return (
<form
onSubmit={onSearch}
@@ -102,7 +119,7 @@ const SearchBar = memo(() => {
type="text"
onChange={onChangeSearch}
value={searchText}
placeholder={!isTrash ? "Search" : "Search Trash"}
placeholder={searchTextPlaceholder}
className="w-full min-h-[42px] border border-[#BEC9D3] pl-[45px] pr-[15px] text-[16px] text-black rounded-[5px]"
/>
<div
+20 -10
View File
@@ -20,7 +20,8 @@ export const useFiles = (enabled = true) => {
const params = useParams();
// TODO: Remove any
const sortBy = useSelector((state: any) => state.filter.sortBy);
const { isTrash } = useUtils();
const { isTrash, isMedia } = useUtils();
const limit = isMedia ? 100 : 50;
const filesReactQuery = useInfiniteQuery(
[
"files",
@@ -28,8 +29,9 @@ export const useFiles = (enabled = true) => {
parent: params.id || "/",
search: params.query || "",
sortBy,
limit: undefined,
limit,
trashMode: isTrash,
mediaMode: isMedia,
},
],
getFilesListAPI,
@@ -58,7 +60,8 @@ export const useFilesClient = () => {
// TODO: Remove any
const sortBy = useSelector((state: any) => state.filter.sortBy);
const filesReactClientQuery = useQueryClient();
const { isTrash } = useUtils();
const { isTrash, isMedia } = useUtils();
const limit = isMedia ? 100 : 50;
const invalidateFilesCache = () => {
filesReactClientQuery.invalidateQueries({
@@ -68,8 +71,9 @@ export const useFilesClient = () => {
parent: params.id || "/",
search: params.query || "",
sortBy,
limit: undefined,
limit,
trashMode: isTrash,
mediaMode: isMedia,
},
],
});
@@ -113,7 +117,7 @@ export const useThumbnail = (
hasThumbnail: false,
image: undefined,
});
const { isHome } = useUtils();
const { isHome, isMedia } = useUtils();
const listView = useAppSelector((state) => state.filter.listView);
const imageOnError = useCallback(() => {
@@ -123,11 +127,11 @@ export const useThumbnail = (
});
}, []);
const getThumbnail = useCallback(async () => {
console.log("getting thumbnail", thumbnailID);
try {
if (!thumbnailID || requestedThumbnail.current) return;
if (isQuickFile && !isHome) return;
if (!isQuickFile && listView) return;
console.log("getting thumbnail", thumbnailID);
if (!isQuickFile && listView && !isMedia) return;
requestedThumbnail.current = true;
const thumbnailData = await getFileThumbnailAPI(thumbnailID);
setState({
@@ -143,26 +147,32 @@ export const useThumbnail = (
getFileThumbnailAPI,
imageOnError,
listView,
requestedThumbnail.current,
isHome,
isQuickFile,
]);
useEffect(() => {
if (!hasThumbnail || !thumbnailID) return;
getThumbnail();
}, [hasThumbnail, getThumbnail]);
return () => {
requestedThumbnail.current = false;
};
}, [hasThumbnail, getThumbnail, thumbnailID]);
return { ...state, imageOnError };
};
export const useSearchSuggestions = (searchText: string) => {
const { isTrash } = useUtils();
const { isTrash, isMedia } = useUtils();
const searchQuery = useQuery(
[
"search",
{
searchText,
trashMode: isTrash,
mediaMode: isMedia,
},
],
getSuggestedListAPI,
+23 -12
View File
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useLocation, useParams } from "react-router-dom";
import { useLocation } from "react-router-dom";
export const useUtils = () => {
const location = useLocation();
@@ -17,7 +17,15 @@ export const useUtils = () => {
);
}, [location.pathname]);
return { isHome, isTrash };
const isMedia = useMemo(() => {
console.log("location", location.pathname);
return (
location.pathname === "/media" ||
location.pathname.includes("/search-media")
);
}, [location.pathname]);
return { isHome, isTrash, isMedia };
};
export const useClickOutOfBounds = (outOfBoundsCallback: () => any) => {
@@ -42,7 +50,7 @@ export const useClickOutOfBounds = (outOfBoundsCallback: () => any) => {
document.removeEventListener("mousedown", outOfBoundsClickCheck);
document.removeEventListener("touchstart", outOfBoundsClickCheck);
};
}, [outOfBoundsCallback]);
}, [outOfBoundsCallback, outOfBoundsClickCheck]);
return {
wrapperRef,
@@ -53,16 +61,19 @@ export const useDragAndDrop = (fileDroppedCallback: (file: any) => any) => {
const [isDraggingFile, setIsDraggingFile] = useState(false);
const isDraggingFileRef = useRef(false);
const onDragDropEvent = useCallback((e: any) => {
e.preventDefault();
e.stopPropagation();
isDraggingFileRef.current = false;
setIsDraggingFile(false);
const onDragDropEvent = useCallback(
(e: any) => {
e.preventDefault();
e.stopPropagation();
isDraggingFileRef.current = false;
setIsDraggingFile(false);
const fileInput = e.dataTransfer;
const fileInput = e.dataTransfer;
fileDroppedCallback(fileInput);
}, []);
fileDroppedCallback(fileInput);
},
[fileDroppedCallback]
);
const onDragEvent = useCallback((e: any) => {
e.preventDefault();
e.stopPropagation();
@@ -92,7 +103,7 @@ export const useDragAndDrop = (fileDroppedCallback: (file: any) => any) => {
window.removeEventListener("dragover", stopDrag);
window.removeEventListener("focus", stopDrag);
};
}, []);
}, [stopDrag]);
return {
isDraggingFile,
+13
View File
@@ -0,0 +1,13 @@
const PhotoIcon: React.FC<React.SVGProps<SVGSVGElement>> = (props) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" {...props}>
<title>image</title>
<path
d="M8.5,13.5L11,16.5L14.5,12L19,18H5M21,19V5C21,3.89 20.1,3 19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19Z"
fill="currentColor"
/>
</svg>
);
};
export default PhotoIcon;
+18
View File
@@ -66,6 +66,24 @@ const AppRouter = () => {
</PrivateRoute>
}
/>
<Route
key={1}
path="/media"
element={
<PrivateRoute>
<Homepage2 />
</PrivateRoute>
}
/>
<Route
key={1}
path="/search-media/:query"
element={
<PrivateRoute>
<Homepage2 />
</PrivateRoute>
}
/>
<Route
key={1}
path="/trash"