added navigation scroll restore logic

This commit is contained in:
subnub
2024-12-28 00:17:59 -05:00
parent 84407a340c
commit e4fdc51743
7 changed files with 427 additions and 323 deletions
+97 -83
View File
@@ -3,103 +3,117 @@ import Folders from "../Folders/Folders";
import { useFiles, useQuickFiles, useUploader } from "../../hooks/files";
import { useInfiniteScroll } from "../../hooks/infiniteScroll";
import Files from "../Files/Files";
import { memo, useCallback, useEffect, useState } from "react";
import { memo, useCallback, useEffect, useRef, useState } from "react";
import Spinner from "../Spinner/Spinner";
import { useAppDispatch } from "../../hooks/store";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { useParams } from "react-router-dom";
import classNames from "classnames";
import { useDragAndDrop } from "../../hooks/utils";
import MultiSelectBar from "../MultiSelectBar/MultiSelectBar";
import { useFolders } from "../../hooks/folders";
const DataForm = memo(() => {
const {
fetchNextPage: filesFetchNextPage,
isFetchingNextPage,
data: fileList,
isLoading: isLoadingFiles,
} = useFiles();
const { isLoading: isLoadingFolders } = useFolders();
const { isLoading: isLoadingQuickItems } = useQuickFiles();
const dispatch = useAppDispatch();
const { sentinelRef, reachedIntersect } = useInfiniteScroll();
const [initialLoad, setInitialLoad] = useState(true);
const params = useParams();
const { uploadFiles } = useUploader();
const DataForm = memo(
({ scrollDivRef }: { scrollDivRef: React.RefObject<HTMLDivElement> }) => {
const {
fetchNextPage: filesFetchNextPage,
isFetchingNextPage,
data: fileList,
isLoading: isLoadingFiles,
} = useFiles();
const { isLoading: isLoadingFolders } = useFolders();
const { isLoading: isLoadingQuickItems } = useQuickFiles();
const dispatch = useAppDispatch();
const { sentinelRef, reachedIntersect } = useInfiniteScroll();
const [initialLoad, setInitialLoad] = useState(true);
const params = useParams();
const { uploadFiles } = useUploader();
const navigationMap = useAppSelector((state) => {
return state.selected.navigationMap[window.location.pathname];
});
const isLoading = isLoadingFiles || isLoadingFolders || isLoadingQuickItems;
const isLoading = isLoadingFiles || isLoadingFolders || isLoadingQuickItems;
useEffect(() => {
if (initialLoad) {
setInitialLoad(false);
return;
} else if (!fileList) {
return;
}
if (reachedIntersect && !isFetchingNextPage) {
filesFetchNextPage();
}
}, [reachedIntersect, initialLoad, isFetchingNextPage]);
useEffect(() => {
if (initialLoad) {
setInitialLoad(false);
return;
} else if (!fileList) {
return;
}
if (reachedIntersect && !isFetchingNextPage) {
filesFetchNextPage();
}
}, [reachedIntersect, initialLoad, isFetchingNextPage]);
const addFile = useCallback(
(files: FileList) => {
uploadFiles(files);
},
[params.id]
);
useEffect(() => {
if (!isLoading && navigationMap) {
scrollDivRef.current?.scrollTo(0, navigationMap.scrollTop);
} else if (!isLoading) {
scrollDivRef.current?.scrollTo(0, 0);
}
}, [isLoading, navigationMap, window.location.pathname]);
const {
isDraggingFile,
onDragDropEvent,
onDragEvent,
onDragEnterEvent,
stopDrag,
} = useDragAndDrop(addFile);
const addFile = useCallback(
(files: FileList) => {
uploadFiles(files);
},
[params.id]
);
return (
<div
className={classNames(
"w-full px-2.5 desktopMode:px-10 py-6 overflow-y-scroll",
{
"opacity-50": isDraggingFile,
}
)}
onDrop={onDragDropEvent}
onDragOver={onDragEvent}
onDragLeave={onDragEvent}
onDragEnter={onDragEnterEvent}
onMouseLeave={stopDrag}
>
{!isLoading && (
<div>
<div className="fixed bottom-0 flex justify-center items-center right-0 left-0 z-10">
<MultiSelectBar />
const {
isDraggingFile,
onDragDropEvent,
onDragEvent,
onDragEnterEvent,
stopDrag,
} = useDragAndDrop(addFile);
return (
<div
className={classNames(
"w-full px-2.5 desktopMode:px-10 py-6 overflow-y-scroll",
{
"opacity-50": isDraggingFile,
}
)}
onDrop={onDragDropEvent}
onDragOver={onDragEvent}
onDragLeave={onDragEvent}
onDragEnter={onDragEnterEvent}
onMouseLeave={stopDrag}
ref={scrollDivRef}
>
{!isLoading && (
<div>
<div className="fixed bottom-0 flex justify-center items-center right-0 left-0 z-10">
<MultiSelectBar />
</div>
<QuickAccess />
<Folders scrollDivRef={scrollDivRef} />
<Files />
</div>
)}
<QuickAccess />
{isLoading && (
<div className="w-full flex justify-center items-center h-full">
<Spinner />
</div>
)}
{/* @ts-ignore */}
<div ref={sentinelRef} className="h-1"></div>
<Folders />
<Files />
</div>
)}
{isLoading && (
<div className="w-full flex justify-center items-center h-full">
<Spinner />
</div>
)}
{/* @ts-ignore */}
<div ref={sentinelRef} className="h-1"></div>
{/* TODO: Change this spinner name */}
{isFetchingNextPage && (
<div className="w-full flex justify-center items-center mt-4">
<Spinner />
</div>
)}
</div>
);
});
{/* TODO: Change this spinner name */}
{isFetchingNextPage && (
<div className="w-full flex justify-center items-center mt-4">
<Spinner />
</div>
)}
</div>
);
}
);
export default DataForm;
+13 -2
View File
@@ -6,16 +6,21 @@ import { useNavigate } from "react-router-dom";
import mobilecheck from "../../utils/mobileCheck";
import moment from "moment";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { setMainSelect, setMultiSelectMode } from "../../reducers/selected";
import {
addNavigationMap,
setMainSelect,
setMultiSelectMode,
} from "../../reducers/selected";
import { useUtils } from "../../hooks/utils";
import { FolderInterface } from "../../types/folders";
interface FolderItemProps {
folder: FolderInterface;
scrollDivRef: React.RefObject<HTMLDivElement>;
}
const FolderItem: React.FC<FolderItemProps> = memo((props) => {
const { folder } = props;
const { folder, scrollDivRef } = props;
const elementSelected = useAppSelector((state) => {
if (state.selected.mainSection.type !== "folder") return false;
return state.selected.mainSection.id === folder._id;
@@ -77,6 +82,12 @@ const FolderItem: React.FC<FolderItemProps> = memo((props) => {
}
if (singleClickFolders || currentDate - lastSelected.current < 1500) {
dispatch(
addNavigationMap({
url: window.location.pathname,
scrollTop: scrollDivRef.current?.scrollTop || 0,
})
);
if (isTrash) {
navigate(`/folder-trash/${folder._id}`);
} else {
+124 -118
View File
@@ -6,137 +6,143 @@ import { useUtils } from "../../hooks/utils";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { setSortBy } from "../../reducers/filter";
const Folders = memo(() => {
const { data: folders } = useFolders(false);
const { isHome, isTrash, isSearch } = useUtils();
const sortBy = useAppSelector((state) => state.filter.sortBy);
const dispatch = useAppDispatch();
const Folders = memo(
({ scrollDivRef }: { scrollDivRef: React.RefObject<HTMLDivElement> }) => {
const { data: folders } = useFolders(false);
const { isHome, isTrash, isSearch } = useUtils();
const sortBy = useAppSelector((state) => state.filter.sortBy);
const dispatch = useAppDispatch();
const switchOrderSortBy = useCallback(() => {
let newSortBy = "";
switch (sortBy) {
case "date_asc": {
newSortBy = "date_desc";
break;
}
case "date_desc": {
newSortBy = "date_asc";
break;
}
case "alp_asc": {
newSortBy = "alp_desc";
break;
}
case "alp_desc": {
newSortBy = "alp_asc";
break;
}
default: {
newSortBy = "date_desc";
break;
}
}
dispatch(setSortBy(newSortBy));
}, [sortBy]);
const switchTypeOrderBy = useCallback(
(e: any) => {
const value = e.target.value;
let newSortBy = "date_desc";
if (value === "date") {
if (sortBy.includes("asc")) {
newSortBy = "date_asc";
} else {
const switchOrderSortBy = useCallback(() => {
let newSortBy = "";
switch (sortBy) {
case "date_asc": {
newSortBy = "date_desc";
break;
}
} else if (value === "name") {
if (sortBy.includes("asc")) {
newSortBy = "alp_asc";
} else {
case "date_desc": {
newSortBy = "date_asc";
break;
}
case "alp_asc": {
newSortBy = "alp_desc";
break;
}
case "alp_desc": {
newSortBy = "alp_asc";
break;
}
default: {
newSortBy = "date_desc";
break;
}
}
dispatch(setSortBy(newSortBy));
},
[sortBy]
);
}, [sortBy]);
const title = useMemo(() => {
if (isTrash) {
return "Trash";
} else if (isSearch) {
return "Search";
} else {
return folders?.length === 0 ? "No Folders" : "Folders";
}
}, [isHome, isTrash, isSearch, folders?.length]);
const switchTypeOrderBy = useCallback(
(e: any) => {
const value = e.target.value;
return (
<div className="mt-8 select-none">
<div className="flex flex-row mb-5 justify-between items-center">
<h2
className={classNames(
"m-0 text-xl font-medium"
// isHome || isTrash ? "block" : "invisible"
)}
>
{title}
</h2>
<div className="flex flex-row items-center">
<a className="mr-2" onClick={switchOrderSortBy}>
<svg
className="h-3 w-3 cursor-pointer animate"
width="6"
height="10"
viewBox="0 0 6 10"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style={
sortBy === "date_desc" || sortBy === "alp_desc"
? { transform: "scaleY(-1)" }
: {}
let newSortBy = "date_desc";
if (value === "date") {
if (sortBy.includes("asc")) {
newSortBy = "date_asc";
} else {
newSortBy = "date_desc";
}
} else if (value === "name") {
if (sortBy.includes("asc")) {
newSortBy = "alp_asc";
} else {
newSortBy = "alp_desc";
}
}
dispatch(setSortBy(newSortBy));
},
[sortBy]
);
const title = useMemo(() => {
if (isTrash) {
return "Trash";
} else if (isSearch) {
return "Search";
} else {
return folders?.length === 0 ? "No Folders" : "Folders";
}
}, [isHome, isTrash, isSearch, folders?.length]);
return (
<div className="mt-8 select-none">
<div className="flex flex-row mb-5 justify-between items-center">
<h2
className={classNames(
"m-0 text-xl font-medium"
// isHome || isTrash ? "block" : "invisible"
)}
>
{title}
</h2>
<div className="flex flex-row items-center">
<a className="mr-2" onClick={switchOrderSortBy}>
<svg
className="h-3 w-3 cursor-pointer animate"
width="6"
height="10"
viewBox="0 0 6 10"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style={
sortBy === "date_desc" || sortBy === "alp_desc"
? { transform: "scaleY(-1)" }
: {}
}
>
<g id="upload">
<path
id="Path"
d="M5.58035 2.51616L3.20339 0.139199C3.01776 -0.0463997 2.71681 -0.0463997 2.53119 0.139199L0.154195 2.51616C-0.0282007 2.70502 -0.0229639 3.00597 0.165894 3.18836C0.350128 3.3663 0.642189 3.3663 0.826423 3.18836L2.39191 1.62288V9.50781C2.39191 9.77037 2.60475 9.98321 2.86731 9.98321C3.12988 9.98321 3.34272 9.77037 3.34272 9.50781V1.6229L4.90821 3.18839C5.09706 3.37079 5.39801 3.36555 5.58041 3.17669C5.75829 2.99246 5.75829 2.7004 5.58035 2.51616Z"
fill="currentColor"
/>
</g>
</svg>
</a>
<select
className="text-sm font-medium appearance-none bg-white"
onChange={switchTypeOrderBy}
value={
sortBy === "alp_desc" || sortBy === "alp_asc" ? "name" : "date"
}
>
<g id="upload">
<path
id="Path"
d="M5.58035 2.51616L3.20339 0.139199C3.01776 -0.0463997 2.71681 -0.0463997 2.53119 0.139199L0.154195 2.51616C-0.0282007 2.70502 -0.0229639 3.00597 0.165894 3.18836C0.350128 3.3663 0.642189 3.3663 0.826423 3.18836L2.39191 1.62288V9.50781C2.39191 9.77037 2.60475 9.98321 2.86731 9.98321C3.12988 9.98321 3.34272 9.77037 3.34272 9.50781V1.6229L4.90821 3.18839C5.09706 3.37079 5.39801 3.36555 5.58041 3.17669C5.75829 2.99246 5.75829 2.7004 5.58035 2.51616Z"
fill="currentColor"
/>
</g>
</svg>
</a>
<select
className="text-sm font-medium appearance-none bg-white"
onChange={switchTypeOrderBy}
value={
sortBy === "alp_desc" || sortBy === "alp_asc" ? "name" : "date"
}
>
<option value="date">Modified</option>
<option value="name">Name</option>
</select>
<option value="date">Modified</option>
<option value="name">Name</option>
</select>
</div>
</div>
<div
className={classNames(
"grid grid-cols-[repeat(auto-fit,minmax(47%,45%))] xs:grid-cols-[repeat(auto-fill,minmax(160px,1fr))] gap-[16px]",
folders?.length === 1
? "justify-normal"
: "justify-center xs:justify-normal"
)}
>
{folders?.map((folder) => (
<FolderItem
folder={folder}
key={folder._id}
scrollDivRef={scrollDivRef}
/>
))}
</div>
</div>
<div
className={classNames(
"grid grid-cols-[repeat(auto-fit,minmax(47%,45%))] xs:grid-cols-[repeat(auto-fill,minmax(160px,1fr))] gap-[16px]",
folders?.length === 1
? "justify-normal"
: "justify-center xs:justify-normal"
)}
>
{folders?.map((folder) => (
<FolderItem folder={folder} key={folder._id} />
))}
</div>
</div>
);
});
);
}
);
export default Folders;
+30 -1
View File
@@ -10,8 +10,13 @@ import { closeDrawer } from "../../reducers/leftSection";
import SettingsIcon from "../../icons/SettingsIcon";
import ChevronSolid from "../../icons/ChevronSolid";
import HomeIconOutline from "../../icons/HomeIconOutline";
import { addNavigationMap } from "../../reducers/selected";
const LeftSection = () => {
const LeftSection = ({
scrollDivRef,
}: {
scrollDivRef: React.RefObject<HTMLDivElement>;
}) => {
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const leftSectionOpen = useAppSelector((state) => state.leftSection.drawOpen);
const { isHome, isHomeFolder, isTrash, isMedia, isSettings } = useUtils();
@@ -33,21 +38,45 @@ const LeftSection = () => {
const goHome = () => {
dispatch(closeDrawer());
dispatch(
addNavigationMap({
url: window.location.pathname,
scrollTop: scrollDivRef.current?.scrollTop || 0,
})
);
navigate("/home");
};
const goTrash = () => {
dispatch(closeDrawer());
dispatch(
addNavigationMap({
url: window.location.pathname,
scrollTop: scrollDivRef.current?.scrollTop || 0,
})
);
navigate("/trash");
};
const goMedia = () => {
dispatch(closeDrawer());
dispatch(
addNavigationMap({
url: window.location.pathname,
scrollTop: scrollDivRef.current?.scrollTop || 0,
})
);
navigate("/media");
};
const goSettings = () => {
dispatch(closeDrawer());
dispatch(
addNavigationMap({
url: window.location.pathname,
scrollTop: scrollDivRef.current?.scrollTop || 0,
})
);
navigate("/settings");
};
+8 -3
View File
@@ -1,6 +1,6 @@
import DataForm from "../Dataform/Dataform";
import RightSection from "../RightSection/RightSection";
import { memo } from "react";
import { memo, useRef } from "react";
import LeftSection from "../LeftSection/LeftSection";
import { useUtils } from "../../hooks/utils";
import Medias from "../Medias/Medias";
@@ -20,6 +20,7 @@ const MainSection = memo(() => {
const moveModalItemType = useAppSelector(
(state) => state.selected.moveModal.type
);
const scrollDivRef = useRef<HTMLDivElement>(null);
const isMediaSelected =
popupModalItem?.metadata.isVideo || popupModalItem?.metadata.hasThumbnail;
@@ -40,9 +41,13 @@ const MainSection = memo(() => {
{moveModalItemType && <MoverPopup />}
<div className="flex flex-row dynamic-height w-screen pt-16">
<LeftSection />
<LeftSection scrollDivRef={scrollDivRef} />
{!isMedia ? <DataForm /> : <Medias />}
{!isMedia ? (
<DataForm scrollDivRef={scrollDivRef} />
) : (
<Medias scrollDivRef={scrollDivRef} />
)}
<RightSection />
</div>
+133 -116
View File
@@ -7,133 +7,150 @@ import { useInfiniteScroll } from "../../hooks/infiniteScroll";
import { useAppDispatch, useAppSelector } from "../../hooks/store";
import { setMediaFilter, setSortBy } from "../../reducers/filter";
const Medias = memo(() => {
const {
data: files,
isFetchingNextPage,
fetchNextPage: filesFetchNextPage,
} = useFiles();
const [initialLoad, setInitialLoad] = useState(true);
const { sentinelRef, reachedIntersect } = useInfiniteScroll();
const sortBy = useAppSelector((state) => state.filter.sortBy);
const mediaFilter = useAppSelector((state) => state.filter.mediaFilter);
const dispatch = useAppDispatch();
const Medias = memo(
({ scrollDivRef }: { scrollDivRef: React.RefObject<HTMLDivElement> }) => {
const {
data: files,
isFetchingNextPage,
fetchNextPage: filesFetchNextPage,
} = useFiles();
const [initialLoad, setInitialLoad] = useState(true);
const { sentinelRef, reachedIntersect } = useInfiniteScroll();
const sortBy = useAppSelector((state) => state.filter.sortBy);
const mediaFilter = useAppSelector((state) => state.filter.mediaFilter);
const navigationMap = useAppSelector((state) => {
return state.selected.navigationMap[window.location.pathname];
});
useEffect(() => {
if (initialLoad) {
setInitialLoad(false);
return;
} else if (!files) {
return;
}
if (reachedIntersect && !isFetchingNextPage) {
filesFetchNextPage();
}
}, [reachedIntersect, initialLoad, isFetchingNextPage]);
const dispatch = useAppDispatch();
const switchOrderSortBy = useCallback(() => {
let newSortBy = "";
switch (sortBy) {
case "date_asc": {
newSortBy = "date_desc";
break;
useEffect(() => {
if (initialLoad) {
setInitialLoad(false);
return;
} else if (!files) {
return;
}
case "date_desc": {
newSortBy = "date_asc";
break;
if (reachedIntersect && !isFetchingNextPage) {
filesFetchNextPage();
}
case "alp_asc": {
newSortBy = "alp_desc";
break;
}, [reachedIntersect, initialLoad, isFetchingNextPage]);
useEffect(() => {
if (!initialLoad && navigationMap) {
scrollDivRef.current?.scrollTo(0, navigationMap.scrollTop);
} else if (!initialLoad) {
scrollDivRef.current?.scrollTo(0, 0);
}
case "alp_desc": {
newSortBy = "alp_asc";
break;
}, [initialLoad, navigationMap, window.location.pathname]);
const switchOrderSortBy = useCallback(() => {
let newSortBy = "";
switch (sortBy) {
case "date_asc": {
newSortBy = "date_desc";
break;
}
case "date_desc": {
newSortBy = "date_asc";
break;
}
case "alp_asc": {
newSortBy = "alp_desc";
break;
}
case "alp_desc": {
newSortBy = "alp_asc";
break;
}
default: {
newSortBy = "date_desc";
break;
}
}
default: {
newSortBy = "date_desc";
break;
dispatch(setSortBy(newSortBy));
}, [sortBy]);
const mediaFilterOnChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const value = e.target.value;
dispatch(setMediaFilter(value));
};
const title = useMemo(() => {
if (mediaFilter === "all") {
return "Photos and Videos";
} else if (mediaFilter === "photos") {
return "Photos";
} else if (mediaFilter === "videos") {
return "Videos";
}
}
}, [mediaFilter]);
dispatch(setSortBy(newSortBy));
}, [sortBy]);
const mediaFilterOnChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const value = e.target.value;
dispatch(setMediaFilter(value));
};
const title = useMemo(() => {
if (mediaFilter === "all") {
return "Photos and Videos";
} else if (mediaFilter === "photos") {
return "Photos";
} else if (mediaFilter === "videos") {
return "Videos";
}
}, [mediaFilter]);
return (
<div className="w-full p-[17px_15px] desktopMode:p-[17px_40px] overflow-y-scroll select-none">
<div className="flex flex-row mb-5 justify-between items-center mt-2">
<h2 className={classNames("m-0 text-xl font-medium")}>{title}</h2>
<div className="flex flex-row items-center">
<a className="mr-2" onClick={switchOrderSortBy}>
<svg
className="h-3 w-3 cursor-pointer animate"
width="6"
height="10"
viewBox="0 0 6 10"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style={
sortBy === "date_desc" || sortBy === "alp_desc"
? { transform: "scaleY(-1)" }
: {}
}
>
<g id="upload">
<path
id="Path"
d="M5.58035 2.51616L3.20339 0.139199C3.01776 -0.0463997 2.71681 -0.0463997 2.53119 0.139199L0.154195 2.51616C-0.0282007 2.70502 -0.0229639 3.00597 0.165894 3.18836C0.350128 3.3663 0.642189 3.3663 0.826423 3.18836L2.39191 1.62288V9.50781C2.39191 9.77037 2.60475 9.98321 2.86731 9.98321C3.12988 9.98321 3.34272 9.77037 3.34272 9.50781V1.6229L4.90821 3.18839C5.09706 3.37079 5.39801 3.36555 5.58041 3.17669C5.75829 2.99246 5.75829 2.7004 5.58035 2.51616Z"
fill="currentColor"
/>
</g>
</svg>
</a>
<select
className="text-sm font-medium appearance-none bg-white"
onChange={mediaFilterOnChange}
value={mediaFilter}
>
<option value="all">All</option>
<option value="photos">Photos</option>
<option value="videos">Videos</option>
</select>
</div>
</div>
return (
<div
className={classNames(
"grid grid-cols-[repeat(auto-fill,minmax(100px,1fr))] gap-[10px]"
)}
className="w-full p-[17px_15px] desktopMode:p-[17px_40px] overflow-y-scroll select-none"
ref={scrollDivRef}
>
<div className="fixed bottom-0 flex justify-center items-center right-0 left-0 z-10">
<MultiSelectBar />
<div className="flex flex-row mb-5 justify-between items-center mt-2">
<h2 className={classNames("m-0 text-xl font-medium")}>{title}</h2>
<div className="flex flex-row items-center">
<a className="mr-2" onClick={switchOrderSortBy}>
<svg
className="h-3 w-3 cursor-pointer animate"
width="6"
height="10"
viewBox="0 0 6 10"
fill="none"
xmlns="http://www.w3.org/2000/svg"
style={
sortBy === "date_desc" || sortBy === "alp_desc"
? { transform: "scaleY(-1)" }
: {}
}
>
<g id="upload">
<path
id="Path"
d="M5.58035 2.51616L3.20339 0.139199C3.01776 -0.0463997 2.71681 -0.0463997 2.53119 0.139199L0.154195 2.51616C-0.0282007 2.70502 -0.0229639 3.00597 0.165894 3.18836C0.350128 3.3663 0.642189 3.3663 0.826423 3.18836L2.39191 1.62288V9.50781C2.39191 9.77037 2.60475 9.98321 2.86731 9.98321C3.12988 9.98321 3.34272 9.77037 3.34272 9.50781V1.6229L4.90821 3.18839C5.09706 3.37079 5.39801 3.36555 5.58041 3.17669C5.75829 2.99246 5.75829 2.7004 5.58035 2.51616Z"
fill="currentColor"
/>
</g>
</svg>
</a>
<select
className="text-sm font-medium appearance-none bg-white"
onChange={mediaFilterOnChange}
value={mediaFilter}
>
<option value="all">All</option>
<option value="photos">Photos</option>
<option value="videos">Videos</option>
</select>
</div>
</div>
{files?.pages.map((filePage, index) => (
<React.Fragment key={index}>
{filePage.map((file) => (
<MediaItem file={file} key={file._id} />
))}
</React.Fragment>
))}
<div
className={classNames(
"grid grid-cols-[repeat(auto-fill,minmax(100px,1fr))] gap-[10px]"
)}
>
<div className="fixed bottom-0 flex justify-center items-center right-0 left-0 z-10">
<MultiSelectBar />
</div>
{files?.pages.map((filePage, index) => (
<React.Fragment key={index}>
{filePage.map((file) => (
<MediaItem file={file} key={file._id} />
))}
</React.Fragment>
))}
</div>
{/* @ts-ignore */}
<div ref={sentinelRef} className="h-1"></div>
</div>
{/* @ts-ignore */}
<div ref={sentinelRef} className="h-1"></div>
</div>
);
});
);
}
);
export default Medias;
+22
View File
@@ -30,6 +30,12 @@ export interface SelectedStateType {
file: FileInterface | null;
};
moveModal: MoveStateType;
navigationMap: {
[key: string]: {
url: string;
scrollTop: number;
};
};
}
const initialState: SelectedStateType = {
@@ -54,6 +60,7 @@ const initialState: SelectedStateType = {
file: null,
folder: null,
},
navigationMap: {},
};
const selectedSlice = createSlice({
@@ -143,6 +150,20 @@ const selectedSlice = createSlice({
folder: null,
};
},
addNavigationMap: (
state,
action: PayloadAction<{
url: string;
scrollTop: number;
}>
) => {
const navigationMap = state.navigationMap;
navigationMap[action.payload.url] = {
url: action.payload.url,
scrollTop: action.payload.scrollTop,
};
state.navigationMap = navigationMap;
},
},
});
@@ -157,6 +178,7 @@ export const {
resetShareModal,
setMoveModal,
resetMoveModal,
addNavigationMap,
} = selectedSlice.actions;
export default selectedSlice.reducer;