Skip to content

Commit

Permalink
feat: improve player (#596)
Browse files Browse the repository at this point in the history
* fix: show shortcut folder as card

* fix: try to make the navigation not suck

* fix: make PR changes

* fix: update deps
  • Loading branch information
spaenleh authored Apr 3, 2024
1 parent b7fdc4d commit 5bbfc97
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 242 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
"@emotion/react": "11.11.4",
"@emotion/styled": "11.11.0",
"@graasp/chatbox": "3.1.0",
"@graasp/query-client": "3.0.1",
"@graasp/sdk": "4.3.1",
"@graasp/query-client": "3.2.0",
"@graasp/sdk": "4.4.0",
"@graasp/translations": "1.25.3",
"@graasp/ui": "4.12.1",
"@graasp/ui": "4.13.0",
"@mui/icons-material": "5.15.14",
"@mui/lab": "5.0.0-alpha.151",
"@mui/material": "5.15.14",
Expand Down
47 changes: 47 additions & 0 deletions src/modules/item/FolderCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Link, useParams } from 'react-router-dom';

import { styled } from '@mui/material';

import { DiscriminatedItem, ThumbnailSize } from '@graasp/sdk';
import { Card as GraaspCard, TextDisplay } from '@graasp/ui';

import image from '@/assets/avatar.png';
import { buildContentPagePath } from '@/config/paths';
import { hooks } from '@/config/queryClient';

const StyledLink = styled(Link)(() => ({
textDecoration: 'none',
}));

type Props = {
item: DiscriminatedItem;
id?: string;
replaceRoot?: boolean;
};

const FolderCard = ({ id, item, replaceRoot = false }: Props): JSX.Element => {
const { rootId } = useParams();
const { id: itemId, description, name } = item;
const { data: thumbnail } = hooks.useItemThumbnailUrl({
id: item.id,
size: ThumbnailSize.Medium,
});

return (
<StyledLink
to={buildContentPagePath({
rootId: replaceRoot ? itemId : rootId,
itemId,
})}
>
<GraaspCard
description={<TextDisplay content={description ?? ''} />}
name={name}
image={thumbnail ?? image}
cardId={id}
/>
</StyledLink>
);
};

export default FolderCard;
195 changes: 96 additions & 99 deletions src/modules/item/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
DiscriminatedItem,
DocumentItemType,
EtherpadItemType,
FolderItemType,
H5PItemType,
ItemType,
LinkItemType,
Expand Down Expand Up @@ -61,7 +62,7 @@ import { PLAYER } from '@/langs/constants';
import { isHidden, paginationContentFilter } from '@/utils/item';

import NavigationIsland from '../navigationIsland/NavigationIsland';
import PinnedFolderItem from './PinnedFolderItem';
import FolderCard from './FolderCard';

const {
useEtherpad,
Expand Down Expand Up @@ -301,7 +302,7 @@ const ItemContent = ({ item }: ItemContentProps) => {
switch (item.type) {
case ItemType.FOLDER: {
const folderButton = (
<PinnedFolderItem id={buildFolderButtonId(item.id)} item={item} />
<FolderCard id={buildFolderButtonId(item.id)} item={item} replaceRoot />
);
return folderButton;

Expand Down Expand Up @@ -372,50 +373,30 @@ const ItemContentWrapper = ({ item }: { item: DiscriminatedItem }) => {
return <ItemContent item={item} />;
};

type Props = {
/**
* Id of the parent item for which the page is displayed
*/
id?: string;

isChildren?: boolean;
type FolderContentProps = {
item: FolderItemType;
showPinnedOnly?: boolean;
};

/**
*
* @returns
*/
const Item = ({
id,
isChildren = false,
const FolderContent = ({
item,
showPinnedOnly = false,
}: Props): JSX.Element | null => {
}: FolderContentProps) => {
const { ref, inView } = useInView();
const { t: translatePlayer } = usePlayerTranslation();
const { t: translateMessage } = useMessagesTranslation();
const { data: item, isInitialLoading: isLoadingItem, isError } = useItem(id);

// fetch children if item is folder
const isFolder = Boolean(item?.type === ItemType.FOLDER);
const {
data: children = [],
isInitialLoading: isChildrenLoading,
isError: isChildrenError,
} = useChildren(id, undefined, {
enabled: isFolder,
getUpdates: isFolder,
});
// this should be fetched only when the item is a folder
const { data: children = [], isInitialLoading: isChildrenLoading } =
useChildren(item.id, undefined, {
getUpdates: true,
});

const {
data: childrenPaginated,
isInitialLoading: isChildrenPaginatedLoading,
isError: isChildrenPaginatedError,
refetch: refetchChildrenPaginated,
hasNextPage,
isFetchingNextPage,
fetchNextPage,
} = useChildrenPaginated(id, children, {
} = useChildrenPaginated(item.id, children, {
enabled: Boolean(!showPinnedOnly && children && !isChildrenLoading),
filterFunction: paginationContentFilter,
});
Expand All @@ -431,7 +412,77 @@ const Item = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [inView, children]);

if (isLoadingItem || isChildrenLoading || isChildrenPaginatedLoading) {
const showLoadMoreButton =
!hasNextPage || isFetchingNextPage ? null : (
<Container ref={ref}>
<Button
disabled={!hasNextPage || isFetchingNextPage}
onClick={() => fetchNextPage()}
fullWidth
>
{translatePlayer(PLAYER.LOAD_MORE)}
</Button>
</Container>
);

if (showPinnedOnly) {
return children
?.filter((i) => showPinnedOnly === (i.settings?.isPinned || false))
?.map((thisItem) => (
<ItemContentWrapper key={thisItem.id} item={thisItem} />
));
}
// render each children recursively
return (
<Box pb={7}>
<Stack direction="column">
<Typography className={FOLDER_NAME_TITLE_CLASS} variant="h5">
{item.name}
</Typography>
<TextDisplay content={item.description ?? ''} />
</Stack>

{childrenPaginated?.pages?.map((page) => (
<Fragment key={page.pageNumber}>
{page.data.map((thisItem) => (
<Box key={thisItem.id} textAlign="center" mt={1} mb={1}>
<ItemContentWrapper item={thisItem} />
</Box>
))}
</Fragment>
))}
{showLoadMoreButton}
<NavigationIsland />
</Box>
);
};

type Props = {
/**
* Id of the parent item for which the page is displayed
*/
id?: string;

isChildren?: boolean;
showPinnedOnly?: boolean;
};

const Item = ({
id,
isChildren = false,
showPinnedOnly = false,
}: Props): JSX.Element | false => {
const { t: translateMessage } = useMessagesTranslation();
const { data: item, isInitialLoading: isLoadingItem, isError } = useItem(id);

if (item && item.type === ItemType.FOLDER) {
if (isChildren) {
return <ItemContentWrapper item={item} />;
}
return <FolderContent item={item} showPinnedOnly={showPinnedOnly} />;
}

if (isLoadingItem) {
return (
<ItemSkeleton
itemType={item?.type ?? ItemType.FOLDER}
Expand All @@ -441,78 +492,24 @@ const Item = ({
);
}

if (isError || !item || isChildrenError || isChildrenPaginatedError) {
if (item) {
// executed when item is a single child that is not a folder
return (
<Alert severity="error">
{translateMessage(FAILURE_MESSAGES.UNEXPECTED_ERROR)}
</Alert>
<>
<ItemContentWrapper item={item} />
<NavigationIsland />
</>
);
}

if (item.type === ItemType.FOLDER) {
const showLoadMoreButton =
!hasNextPage || isFetchingNextPage ? null : (
<Container ref={ref}>
<Button
disabled={!hasNextPage || isFetchingNextPage}
onClick={() => fetchNextPage()}
fullWidth
>
{translatePlayer(PLAYER.LOAD_MORE)}
</Button>
</Container>
);

// render each children recursively
if (isError || !item) {
return (
<>
{!showPinnedOnly && (
<>
<Stack direction="column">
<Typography className={FOLDER_NAME_TITLE_CLASS} variant="h5">
{item.name}
</Typography>
<TextDisplay content={item.description ?? ''} />
</Stack>

{childrenPaginated?.pages.map((page) => (
<Fragment key={page.pageNumber}>
{page.data.map((thisItem) => (
<Box
key={thisItem.id}
textAlign="center"
marginTop={(theme) => theme.spacing(1)}
marginBottom={(theme) => theme.spacing(1)}
>
<ItemContentWrapper item={thisItem} />
</Box>
))}
</Fragment>
))}
{showLoadMoreButton}
<NavigationIsland />
</>
)}

{showPinnedOnly &&
children
?.filter((i) => showPinnedOnly === (i.settings?.isPinned || false))
?.map((thisItem) => (
<Container key={thisItem.id}>
<ItemContentWrapper item={thisItem} />
</Container>
))}
</>
<Alert severity="error">
{translateMessage(FAILURE_MESSAGES.UNEXPECTED_ERROR)}
</Alert>
);
}

// executed when item is a single child that is not a folder
return (
<>
<ItemContentWrapper item={item} />
<NavigationIsland />
</>
);
return false;
};

export default Item;
77 changes: 0 additions & 77 deletions src/modules/item/PinnedFolderItem.tsx

This file was deleted.

Loading

0 comments on commit 5bbfc97

Please sign in to comment.