Skip to content

Commit

Permalink
fix(web): dashboard projects is loading more than expected (#1193)
Browse files Browse the repository at this point in the history
  • Loading branch information
airslice authored Oct 24, 2024
1 parent 0fde95b commit 6a0d08d
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 98 deletions.
61 changes: 16 additions & 45 deletions web/src/beta/features/AssetsManager/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import useLoadMore from "@reearth/beta/hooks/useLoadMore";
import { BreadcrumbItem } from "@reearth/beta/lib/reearth-ui";
import { ManagerLayout } from "@reearth/beta/ui/components/ManagerBase";
import { useAssetsFetcher } from "@reearth/services/api";
Expand Down Expand Up @@ -151,26 +152,11 @@ export default ({
isLoadingMoreRef.current = false;
}, [hasMoreAssets, isRefetching, fetchMore, endCursor]);

const loadMoreRef = useRef<() => void>(loadMore);
loadMoreRef.current = loadMore;

const assetsWrapperRef = useRef<HTMLDivElement>(null);
const assetsContentRef = useRef<HTMLDivElement>(null);

const checkSize = useCallback(() => {
const parentElement = assetsWrapperRef.current;
const childElement = assetsContentRef.current;

if (childElement && parentElement) {
if (childElement.offsetHeight - 14 < parentElement.offsetHeight) {
loadMoreRef.current?.();
}
}
}, []);

useEffect(() => {
checkSize();
}, [assets, checkSize]);
const { wrapperRef: assetsWrapperRef, contentRef: assetsContentRef } =
useLoadMore({
data: filteredAssets,
onLoadMore: loadMore
});

const [contentWidth, setContentWidth] = useState(0);

Expand All @@ -182,9 +168,6 @@ export default ({

const checkSize = () => {
if (childElement && parentElement) {
if (childElement.offsetHeight <= parentElement.offsetHeight) {
loadMoreRef.current?.();
}
setContentWidth(childElement.offsetWidth);
}
};
Expand All @@ -197,26 +180,11 @@ export default ({

checkSize();

const handleScroll = () => {
if (
childElement &&
childElement.scrollHeight -
parentElement.scrollTop -
parentElement.clientHeight <
50
) {
loadMoreRef.current?.();
}
};

parentElement.addEventListener("scroll", handleScroll);

return () => {
parentObserver.disconnect();
childObserver.disconnect();
parentElement.removeEventListener("scroll", handleScroll);
};
}, [filteredAssets]);
}, [filteredAssets, assetsWrapperRef, assetsContentRef]);

const handleAssetsCreate = useCallback(
async (files?: FileList) => {
Expand Down Expand Up @@ -247,12 +215,15 @@ export default ({
? (localStorage.getItem(ASSETS_LAYOUT_STORAGE_KEY) as ManagerLayout)
: "grid"
);
const handleLayoutChange = useCallback((newLayout?: ManagerLayout) => {
if (!newLayout) return;
localStorage.setItem(ASSETS_LAYOUT_STORAGE_KEY, newLayout);
setLayout(newLayout);
assetsWrapperRef.current?.scrollTo({ top: 0 });
}, []);
const handleLayoutChange = useCallback(
(newLayout?: ManagerLayout) => {
if (!newLayout) return;
localStorage.setItem(ASSETS_LAYOUT_STORAGE_KEY, newLayout);
setLayout(newLayout);
assetsWrapperRef.current?.scrollTo({ top: 0 });
},
[assetsWrapperRef]
);

// path
// TODO: support path with folder
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { useApolloClient } from "@apollo/client";
import useLoadMore from "@reearth/beta/hooks/useLoadMore";
import { ManagerLayout } from "@reearth/beta/ui/components/ManagerBase";
import {
autoFillPage,
onScrollToBottom
} from "@reearth/beta/utils/infinite-scroll";
import { useProjectFetcher } from "@reearth/services/api";
import {
ProjectSortField,
Expand Down Expand Up @@ -50,9 +47,6 @@ export default (workspaceId?: string) => {
const [searchTerm, setSearchTerm] = useState<string>();
const [sortValue, setSort] = useState<SortType>("date-updated");

const wrapperRef = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);

const { starredProjects } = useStarredProjectsQuery(workspaceId);

const {
Expand Down Expand Up @@ -118,12 +112,10 @@ export default (workspaceId?: string) => {
return loading || isRefetching;
}, [isRefetching, loading]);

useEffect(() => {
if (wrapperRef.current && !isLoading && hasMoreProjects) {
handleGetMoreProjects();
}
autoFillPage(wrapperRef, handleGetMoreProjects);
}, [handleGetMoreProjects, projects, hasMoreProjects, isLoading]);
const { wrapperRef, contentRef } = useLoadMore({
data: filtedProjects,
onLoadMore: handleGetMoreProjects
});

const handleProjectSortChange = useCallback(
(value?: string) => {
Expand Down Expand Up @@ -241,7 +233,7 @@ export default (workspaceId?: string) => {
parentObserver.disconnect();
childObserver.disconnect();
};
}, []);
}, [wrapperRef, contentRef]);

const handleImportProject = useCallback(
async (event: React.ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -300,7 +292,6 @@ export default (workspaceId?: string) => {
handleProjectOpen,
handleProjectCreate,
handleProjectSelect,
handleScrollToBottom: onScrollToBottom,
handleLayoutChange,
handleProjectSortChange,
handleSearch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const Projects: FC<{ workspaceId?: string }> = ({ workspaceId }) => {
const {
filtedProjects,
isLoading,
hasMoreProjects,
selectedProject,
projectCreatorVisible,
wrapperRef,
Expand All @@ -31,12 +30,10 @@ const Projects: FC<{ workspaceId?: string }> = ({ workspaceId }) => {
sortValue,
showProjectCreator,
closeProjectCreator,
handleGetMoreProjects,
handleProjectUpdate,
handleProjectCreate,
handleProjectOpen,
handleProjectSelect,
handleScrollToBottom,
handleLayoutChange,
handleProjectSortChange,
handleSearch,
Expand Down Expand Up @@ -172,14 +169,7 @@ const Projects: FC<{ workspaceId?: string }> = ({ workspaceId }) => {
<ActionCol />
</ListHeader>
)}
<ProjectsWrapper
ref={wrapperRef}
onScroll={(e) => {
if (!isLoading && hasMoreProjects) {
handleScrollToBottom(e, handleGetMoreProjects);
}
}}
>
<ProjectsWrapper ref={wrapperRef}>
<ProjectsContainer ref={contentRef}>
<ProjectsGroup layout={layout}>
{filtedProjects.map((project) =>
Expand Down
2 changes: 1 addition & 1 deletion web/src/beta/features/Visualizer/Crust/Infobox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ const Infobox: FC<Props> = ({
handleClassName={INFOBOX_DRAG_HANDLE_CLASS_NAME}
onMoveEnd={handleMoveEnd}
dragDisabled={false}
gap={GAP_DEFAULT_VALUE}
gap={gapField?.value ?? GAP_DEFAULT_VALUE}
/>
)}
</Wrapper>
Expand Down
79 changes: 79 additions & 0 deletions web/src/beta/hooks/useLoadMore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { useCallback, useEffect, useRef } from "react";

type Props = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data: any;
onLoadMore: () => void;
};

const BOTTOM_ALLOWANCE = 50; // when there are 50px left to scroll, load more
const SHORTER_LIMIT = 20; // when the content minuse this is smaller than wrapper we load more

export default ({ data, onLoadMore }: Props) => {
const wrapperRef = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);

const onLoadMoreRef = useRef(onLoadMore);
onLoadMoreRef.current = onLoadMore;

const checkForLoadMore = useCallback(() => {
const wrapperElement = wrapperRef.current;
const contentElement = contentRef.current;

if (wrapperElement && contentElement) {
if (
contentElement.offsetHeight - SHORTER_LIMIT <
wrapperElement.offsetHeight ||
contentElement.scrollHeight -
wrapperElement.scrollTop -
wrapperElement.clientHeight <
BOTTOM_ALLOWANCE
) {
onLoadMoreRef.current?.();
}
}
}, []);

// Check on data change
useEffect(() => {
checkForLoadMore();
}, [data, checkForLoadMore]);

// Check on scroll
useEffect(() => {
const wrapperElement = wrapperRef.current;
if (!wrapperElement) return;

wrapperElement.addEventListener("scroll", checkForLoadMore);

return () => {
wrapperElement.removeEventListener("scroll", checkForLoadMore);
};
}, [data, checkForLoadMore]);

// Check on resize
useEffect(() => {
const wrapperElement = wrapperRef.current;
const contentElement = contentRef.current;

if (!wrapperElement || !contentElement) return;

const wrapperObserver = new ResizeObserver(checkForLoadMore);
const contentObserver = new ResizeObserver(checkForLoadMore);

wrapperObserver.observe(wrapperElement);
contentObserver.observe(contentElement);

checkForLoadMore();

return () => {
wrapperObserver.disconnect();
contentObserver.disconnect();
};
}, [data, checkForLoadMore]);

return {
wrapperRef,
contentRef
};
};
26 changes: 0 additions & 26 deletions web/src/beta/utils/infinite-scroll.ts

This file was deleted.

0 comments on commit 6a0d08d

Please sign in to comment.