import React, {
memo, useCallback, useEffect,
} from 'react';
import {
isPopulated, type IPageHasId,
} from '@growi/core';
import { DevidedPagePath } from '@growi/core/dist/models';
import { UserPicture } from '@growi/ui/dist/components';
import { useTranslation } from 'react-i18next';
import FormattedDistanceDate from '~/client/components/FormattedDistanceDate';
import InfiniteScroll from '~/client/components/InfiniteScroll';
import { useKeywordManager } from '~/client/services/search-operation';
import { PagePathHierarchicalLink } from '~/components/Common/PagePathHierarchicalLink';
import LinkedPagePath from '~/models/linked-page-path';
import { useSWRINFxRecentlyUpdated } from '~/stores/page-listing';
import loggerFactory from '~/utils/logger';
import { SidebarHeaderReloadButton } from '../SidebarHeaderReloadButton';
import styles from './RecentChangesSubstance.module.scss';
const formerLinkClass = styles['grw-former-link'];
const pageItemLowerClass = styles['grw-recent-changes-item-lower'];
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const logger = loggerFactory('growi:History');
type PageItemLowerProps = {
page: IPageHasId,
}
type PageItemProps = PageItemLowerProps & {
isSmall: boolean,
onClickTag?: (tagName: string) => void,
}
const PageItemLower = memo(({ page }: PageItemLowerProps): JSX.Element => {
return (
footprint
{page.seenUsers.length}
chat
{page.commentCount}
);
});
PageItemLower.displayName = 'PageItemLower';
type PageTagsProps = PageItemProps;
const PageTags = memo((props: PageTagsProps): JSX.Element => {
const { page, isSmall, onClickTag } = props;
if (isSmall || (page.tags.length === 0)) {
return <>>;
}
return (
<>
{ page.tags.map((tag) => {
if (!isPopulated(tag)) {
return <>>;
}
return (
onClickTag?.(tag.name)}
>
{tag.name}
);
}) }
>
);
});
PageTags.displayName = 'PageTags';
const PageItem = memo(({ page, isSmall, onClickTag }: PageItemProps): JSX.Element => {
const dPagePath = new DevidedPagePath(page.path, false, true);
const linkedPagePathFormer = new LinkedPagePath(dPagePath.former);
const linkedPagePathLatter = new LinkedPagePath(dPagePath.latter);
const FormerLink = () => (
);
let locked;
if (page.grant !== 1) {
locked = lock;
}
const isTagElementsRendered = !(isSmall || (page.tags.length === 0));
return (
{ !dPagePath.isRoot && }
{ page.wip && (
WIP
) }
{locked}
{ isTagElementsRendered && (
) }
);
});
PageItem.displayName = 'PageItem';
type HeaderProps = {
isSmall: boolean,
onSizeChange: (isSmall: boolean) => void,
isWipPageShown: boolean,
onWipPageShownChange: () => void,
}
export const RecentChangesHeader = ({
isSmall, onSizeChange, isWipPageShown, onWipPageShownChange,
}: HeaderProps): JSX.Element => {
const { t } = useTranslation();
const { mutate } = useSWRINFxRecentlyUpdated(isWipPageShown, { suspense: true });
const retrieveSizePreferenceFromLocalStorage = useCallback(() => {
if (window.localStorage.isRecentChangesSidebarSmall === 'true') {
onSizeChange(true);
}
}, [onSizeChange]);
const changeSizeHandler = useCallback(() => {
onSizeChange(!isSmall);
window.localStorage.setItem('isRecentChangesSidebarSmall', String(isSmall));
}, [isSmall, onSizeChange]);
// componentDidMount
useEffect(() => {
retrieveSizePreferenceFromLocalStorage();
}, [retrieveSizePreferenceFromLocalStorage]);
return (
<>
mutate()} />
>
);
};
type ContentProps = {
isSmall: boolean,
isWipPageShown: boolean,
}
export const RecentChangesContent = ({ isSmall, isWipPageShown }: ContentProps): JSX.Element => {
const swrInifinitexRecentlyUpdated = useSWRINFxRecentlyUpdated(isWipPageShown, { suspense: true });
const { data } = swrInifinitexRecentlyUpdated;
const { pushState } = useKeywordManager();
const isEmpty = data?.[0]?.pages.length === 0;
const lastPageIndex = data?.length ? data.length - 1 : 0;
const isReachingEnd = isEmpty || (data != null && lastPageIndex > 0 && data[lastPageIndex]?.pages.length < data[lastPageIndex - 1]?.pages.length);
return (
{ data != null && data.map(apiResult => apiResult.pages).flat()
.map(page => (
pushState(`tag:${tagName}`)} />
))
}
);
};