// @flow import distanceInWordsToNow from "date-fns/distance_in_words_to_now"; import { sortBy } from "lodash"; import { observer } from "mobx-react"; import * as React from "react"; import { useTranslation } from "react-i18next"; import Document from "models/Document"; import Avatar from "components/Avatar"; import ListItem from "components/List/Item"; import PaginatedList from "components/PaginatedList"; import useStores from "hooks/useStores"; type Props = {| document: Document, isOpen?: boolean, |}; function DocumentViews({ document, isOpen }: Props) { const { t } = useTranslation(); const { views, presence } = useStores(); React.useEffect(() => { views.fetchPage({ documentId: document.id }); }, [views, document.id]); let documentPresence = presence.get(document.id); documentPresence = documentPresence ? Array.from(documentPresence.values()) : []; const presentIds = documentPresence.map((p) => p.userId); const editingIds = documentPresence .filter((p) => p.isEditing) .map((p) => p.userId); // ensure currently present via websocket are always ordered first const documentViews = views.inDocument(document.id); const sortedViews = sortBy(documentViews, (view) => presentIds.includes(view.user.id) ); const users = React.useMemo(() => sortedViews.map((v) => v.user), [ sortedViews, ]); return ( <> {isOpen && ( { const view = documentViews.find((v) => v.user.id === item.id); const isPresent = presentIds.includes(item.id); const isEditing = editingIds.includes(item.id); const subtitle = isPresent ? isEditing ? t("Currently editing") : t("Currently viewing") : t("Viewed {{ timeAgo }} ago", { timeAgo: distanceInWordsToNow( view ? new Date(view.lastViewedAt) : new Date() ), }); return ( } border={false} /> ); }} /> )} ); } export default observer(DocumentViews);