OurBigBook logoOurBigBook Docs OurBigBook logoOurBigBook.comSite Source code
web/front/ArticlePage.tsx
import React from 'react'

import CustomLink from 'front/CustomLink'
import UserLinkWithImage from 'front/UserLinkWithImage'
import { displayAndUsernameText } from 'front/user'
import Article from 'front/Article'
import ArticleList from 'front/ArticleList'
import {
  CreateMyOwnVersionOfThisTopic,
  DiscussionAbout,
  DiscussionIcon,
  MyHead,
  NewArticleIcon,
  SeeIcon,
  SeeMyOwnVersionOfThisTopic,
  TopicIcon,
  useEEdit,
  useEEditIssue,
} from 'front'
import { cant } from 'front/cant'
import { log } from 'front/config'
import routes from 'front/routes'
import { ArticleType, ArticleLinkType, ArticleAncestorType  } from 'front/types/ArticleType'
import { CommentType } from 'front/types/CommentType'
import { CommonPropsType } from 'front/types/CommonPropsType'
import { IssueType } from 'front/types/IssueType'
import { TopicType } from 'front/types/TopicType'

import { Macro } from 'ourbigbook'

export interface ArticlePageProps extends CommonPropsType {
  ancestors?: ArticleAncestorType[];
  article: ArticleType & IssueType;
  articleInTopicByLoggedInUser?: ArticleType,
  articlesInSamePage?: ArticleType[];
  articlesInSamePageCount?: number;
  articlesInSamePageForToc?: ArticleType[];
  articlesInSamePageForTocCount?: number;
  comments?: CommentType[];
  commentsCount?: number;
  hasUnlistedComments?: boolean;
  commentCountByLoggedInUser?: number;
  incomingLinks?: ArticleLinkType[];
  issueArticle?: ArticleType;
  list?: boolean;
  issuesCount?: number;
  isIndex?: boolean;
  latestIssues?: IssueType[];
  otherArticlesInTopic?: (ArticleType & IssueType & TopicType)[];
  page?: number;
  synonymLinks?: ArticleLinkType[];
  tagged?: ArticleLinkType[];
  topIssues?: IssueType[];
}

const ArticlePageHoc = (isIssue=false) => {
  return function ArticlePage({
    ancestors,
    article,
    articleInTopicByLoggedInUser,
    articlesInSamePage,
    articlesInSamePageCount,
    articlesInSamePageForToc,
    articlesInSamePageForTocCount,
    commentCountByLoggedInUser,
    comments,
    commentsCount,
    hasUnlistedComments,
    incomingLinks,
    issueArticle,
    list,
    issuesCount,
    latestIssues,
    loggedInUser,
    otherArticlesInTopic,
    page,
    synonymLinks,
    tagged,
    topIssues,
  }: ArticlePageProps) {
    let t0
    if (log.perf) {
      t0 = performance.now()
    }
    const author = article.author
    const otherArticlesInTopicCount = article.topicCount - (article.list === false ? 0 : 1)
    const canEdit = isIssue ? !cant.editIssue(loggedInUser, article.author.username) : !cant.editArticle(loggedInUser, article.author.username)
    if (isIssue) {
      useEEditIssue(canEdit, issueArticle.slug, article.number)
    } else {
      useEEdit(canEdit, article.slug)
    }
    const handleShortFragmentSkipOnce = React.useRef(false)
    const ret = <>
      <MyHead
        title={
          isIssue ? '' : ancestors.map(a => a.hasScope ? a.titleRenderPlaintext + ` ${Macro.HEADER_SCOPE_SEPARATOR} ` : '').join('') +
            `${article.titleRenderPlaintext} - ${displayAndUsernameText(author)}`
        }
        // TODO one day extract the first image from the article to DB and use that here.
        previewImage={article.image || author.effectiveImage}
      />
      <div className="article-page">
        {isIssue &&
          <div className="content-not-ourbigbook article-meta">
            <DiscussionAbout article={issueArticle} span={true}/>
            <div className="article-info">
              <span className="h2-nocolor inline">
                #{article.number}
                {' '}
              </span>
              {isIssue &&
                <>
                  {' '}
                  <CustomLink href={routes.articleIssues(issueArticle.slug)} className="btn"><DiscussionIcon /> See all ({issuesCount})</CustomLink>
                  {' '}
                  <CustomLink
                    className="btn"
                    href={routes.issueNew(issueArticle.slug)}
                    updatePreviousPage={true}
                  >
                    <NewArticleIcon /> New discussion
                  </CustomLink>
                </>
              }
            </div>
          </div>
        }
        <div className="container page">
          <Article {...{
            ancestors,
            article,
            articlesInSamePage,
            articlesInSamePageCount,
            articlesInSamePageForToc,
            articlesInSamePageForTocCount,
            commentCountByLoggedInUser,
            comments,
            commentsCount,
            hasUnlistedComments,
            handleShortFragmentSkipOnce,
            incomingLinks,
            issueArticle,
            list,
            isIndex: false,
            isIssue,
            issuesCount,
            latestIssues,
            page,
            synonymLinks,
            loggedInUser,
            tagged,
            topIssues,
          }} />
        </div>
        {!isIssue &&
          <>
            <h2 className="content-not-ourbigbook">
              <CustomLink href={routes.topic(article.topicId)}>
                <TopicIcon /> Articles by others on the same topic <span className="meta">({otherArticlesInTopicCount})</span>
              </CustomLink>
            </h2>
            <ArticleList {...{
              articles: otherArticlesInTopic,
              articlesCount: otherArticlesInTopicCount,
              handleShortFragmentSkipOnce,
              loggedInUser,
              showAuthor: true,
              showBody: true,
              showControls: false,
              what: 'articles',
            }}/>
            <div className="content-not-ourbigbook navlink">
              <CustomLink href={routes.topic(article.topicId)}> <TopicIcon /> <SeeIcon /> See all articles in the same topic</CustomLink>
              {articleInTopicByLoggedInUser
                ? <>
                    {articleInTopicByLoggedInUser.slug !== article.slug &&
                      <>{' '}<SeeMyOwnVersionOfThisTopic slug={articleInTopicByLoggedInUser.slug} toplevel={true} /></>
                    }
                  </>
                : <>{' '}<CreateMyOwnVersionOfThisTopic titleSource={article.titleSource} toplevel={true} /></>
              }
            </div>
          </>
        }
      </div>
    </>
    if (log.perf) {
      console.error(`perf: ArticlePage: ${performance.now() - t0} ms`)
    }
    return ret
  }
}

export default ArticlePageHoc;