feat(comments): add comments view

This commit is contained in:
plebeius.eth
2023-10-24 15:45:23 +02:00
parent c17789b695
commit 179d2f54fd
12 changed files with 174 additions and 75 deletions

View File

@@ -14,7 +14,7 @@ const AccountBar: FC = () => {
<div className={styles.header}>
<span className={styles.user}>
<Link to='/user' onClick={(e) => e.preventDefault()}>
{account?.author.shortAddress}
{account?.author?.shortAddress}
</Link>
</span>
<span className={styles.separator}>|</span>

View File

@@ -0,0 +1,36 @@
.pageName {
font-weight: bold;
margin-right: 1ex;
font-variant: small-caps;
font-size: 1.2em;
padding: 43px 0 0 15px;
}
.pageName a {
color: var(--text);
text-decoration: none;
}
.tabMenu {
list-style: none;
white-space: nowrap;
display: inline-block;
margin-bottom: -43px;
padding-left: 5px;
transform: translateY(0.5px);
}
.tabMenu li {
display: inline;
font-weight: bold;
}
.tabMenu li a {
padding: 2px 6px 0 6px;
text-decoration: none;
line-height: 20px;
color: var(--text-secondary);
background-color: var(--background);
border: 1px solid var(--border-primary);
border-bottom: 1px solid var(--background);
}

View File

@@ -0,0 +1,34 @@
import { FC } from 'react';
import { Link, useParams } from 'react-router-dom';
import styles from './comments-buttons.module.css';
import { useTranslation } from 'react-i18next';
import { useSubplebbit } from '@plebbit/plebbit-react-hooks';
const CommentsButtons: FC = () => {
const { t } = useTranslation();
const { subplebbitAddress, commentCid } = useParams();
const subplebbit = useSubplebbit({ subplebbitAddress });
const { title, shortAddress } = subplebbit || {};
return (
<>
<span className={styles.pageName}>
<Link
to={`/p/${subplebbitAddress}`}
onClick={(e) => {
e.preventDefault();
}}
>
{title || shortAddress}
</Link>
</span>
<ul className={styles.tabMenu}>
<li>
<Link to={`/p/${subplebbitAddress}/c/${commentCid}`}>{t('header_comments')}</Link>
</li>
</ul>
</>
);
};
export default CommentsButtons;

View File

@@ -0,0 +1 @@
export {default} from './comments-buttons';

View File

@@ -31,40 +31,6 @@
transform: translateY(0.5px);
}
.tabMenu {
list-style: none;
white-space: nowrap;
display: inline-block;
margin-bottom: -43px;
padding-left: 15px;
transform: translateY(0.5px);
}
.tabMenu li {
display: inline;
font-weight: bold;
padding: 0px 3px;
}
.tabMenu li .selected {
color: var(--text-secondary);
background-color: var(--background);
border: 1px solid var(--border-primary);
border-bottom: 1px solid var(--background);
}
.tabMenu li .choice {
color: var(--text-primary);
background-color: var(--background-secondary);
border-bottom: 1px solid var(--border-primary);
}
.tabMenu li a {
padding: 2px 6px 0 6px;
text-decoration: none;
line-height: 20px;
}
.temporary {
display: flex;
position: absolute;

View File

@@ -1,15 +1,15 @@
import { FC, useState, useEffect } from 'react';
import { Link, useParams } from 'react-router-dom';
import { FC } from 'react';
import { Link, useLocation, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import styles from './header.module.css';
import useTheme from '../../hooks/use-theme';
import AccountBar from './account-bar';
const choices = ['/hot', '/new', '/active', '/controversialAll', '/topAll'];
import { SortButtons, CommentsButtons } from '../header';
// prettier-ignore
const availableLanguages = ['ar', 'bn', 'cs', 'da', 'de', 'el', 'en', 'es', 'fa', 'fi', 'fil', 'fr', 'he', 'hi', 'hu', 'id', 'it', 'ja', 'ko', 'mr', 'nl', 'no', 'pl', 'pt', 'ro', 'ru', 'sq', 'sv', 'te', 'th', 'tr', 'uk', 'ur', 'vi', 'zh'];
// TODO: move to settings page
const Theme: FC = () => {
const [theme, setTheme] = useTheme();
const { t } = useTranslation();
@@ -24,6 +24,7 @@ const Theme: FC = () => {
);
};
// TODO: move to settings page
const Language: FC = () => {
const { i18n } = useTranslation();
const { changeLanguage, language } = i18n;
@@ -46,32 +47,17 @@ const Language: FC = () => {
};
const Header: FC = () => {
const { sortType } = useParams<{ sortType: string }>();
const { t } = useTranslation();
const [theme] = useTheme();
const [selected, setSelected] = useState(sortType || '/topMonth');
const { sortType, subplebbitAddress, commentCid } = useParams();
const location = useLocation();
const labels = [t('header_hot'), t('header_new'), t('header_active'), t('header_controversial'), t('header_top')];
let buttons = null;
useEffect(() => {
if (sortType) {
setSelected('/' + sortType);
} else {
setSelected('/hot');
}
}, [sortType]);
const handleSelect = (choice: string) => {
setSelected(choice);
};
const menuItems = choices.map((choice, index) => (
<li key={choice}>
<Link to={choice} className={selected === choice ? styles.selected : styles.choice} onClick={() => handleSelect(choice)}>
{labels[index]}
</Link>
</li>
));
if (location.pathname === `/p/${subplebbitAddress}/c/${commentCid}`) {
buttons = <CommentsButtons />;
} else if ((location.pathname === `/`) || (sortType && ['hot', 'new', 'active', 'controversialAll', 'topAll'].includes(sortType))) {
buttons = <SortButtons />;
}
return (
<div className={styles.header}>
@@ -81,14 +67,7 @@ const Header: FC = () => {
<img className={styles.logo} src='/assets/logo/seedit.png' alt='logo' />
<img src={`${process.env.PUBLIC_URL}/assets/logo/seedit-text-${theme === 'black' ? 'dark' : 'light'}.svg`} className={styles.logoText} alt='logo' />
</Link>
<ul className={styles.tabMenu}>
{menuItems}
<li>
<Link to='/wiki' className={styles.choice} onClick={(event) => event.preventDefault()}>
{t('header_wiki')}
</Link>
</li>
</ul>
{buttons}
</span>
&nbsp;
</div>

View File

@@ -1,2 +1,4 @@
export {default} from './header';
export {default as AccountBar} from './account-bar';
export {default as AccountBar} from './account-bar';
export {default as SortButtons} from './sort-buttons';
export {default as CommentsButtons} from './comments-buttons';

View File

@@ -0,0 +1 @@
export {default} from './sort-buttons';

View File

@@ -0,0 +1,33 @@
.tabMenu {
list-style: none;
white-space: nowrap;
display: inline-block;
margin-bottom: -43px;
padding-left: 15px;
transform: translateY(0.5px);
}
.tabMenu li {
display: inline;
font-weight: bold;
padding: 0px 3px;
}
.tabMenu li .selected {
color: var(--text-secondary);
background-color: var(--background);
border: 1px solid var(--border-primary);
border-bottom: 1px solid var(--background);
}
.tabMenu li .choice {
color: var(--text-primary);
background-color: var(--background-secondary);
border-bottom: 1px solid var(--border-primary);
}
.tabMenu li a {
padding: 2px 6px 0 6px;
text-decoration: none;
line-height: 20px;
}

View File

@@ -0,0 +1,47 @@
import { FC, useEffect, useState } from 'react';
import { Link, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import styles from './sort-buttons.module.css';
const choices = ['/hot', '/new', '/active', '/controversialAll', '/topAll'];
const SortButtons: FC = () => {
const { sortType } = useParams<{ sortType: string }>();
const { t } = useTranslation();
const [selected, setSelected] = useState(sortType || '/topMonth');
const labels = [t('header_hot'), t('header_new'), t('header_active'), t('header_controversial'), t('header_top')];
const handleSelect = (choice: string) => {
setSelected(choice);
};
useEffect(() => {
if (sortType) {
setSelected('/' + sortType);
} else {
setSelected('/hot');
}
}, [sortType]);
const menuItems = choices.map((choice, index) => (
<li key={choice}>
<Link to={choice} className={selected === choice ? styles.selected : styles.choice} onClick={() => handleSelect(choice)}>
{labels[index]}
</Link>
</li>
));
return (
<ul className={styles.tabMenu}>
{menuItems}
<li>
<Link to='/wiki' className={styles.choice} onClick={(event) => event.preventDefault()}>
{t('header_wiki')}
</Link>
</li>
</ul>
);
};
export default SortButtons;

View File

@@ -12,7 +12,7 @@ interface PostToolsProps {
const PostTools: FC<PostToolsProps> = ({ commentCid }) => {
const comment = useComment({ commentCid });
const subplebbitAddress = comment.subplebbitAddress;
const { cid, replyCount, spoiler } = comment;
const { cid, replyCount, spoiler } = comment || {};
const { t } = useTranslation();
return (

View File

@@ -67,12 +67,12 @@ const Post: FC<PostProps> = ({ post, index }) => {
<ExpandButton commentCid={cid} expanded={expanded} hasThumbnail={hasThumbnail} toggleExpanded={toggleExpanded} />
<p className={styles.tagline}>
{t('post_submitted')} {utils.getFormattedTime(timestamp)} {t('post_by')}&nbsp;
<Link className={styles.author} to={`u/${author.shortAddress}`} onClick={(e) => e.preventDefault()}>
u/{author.shortAddress}
<Link className={styles.author} to={`u/${author?.shortAddress}`} onClick={(e) => e.preventDefault()}>
u/{author?.shortAddress}
</Link>
 {t('post_to')}
<Link className={styles.subplebbit} to={`p/${subplebbitAddress}`} onClick={(e) => e.preventDefault()}>
&nbsp;p/{subplebbit.shortAddress}
&nbsp;p/{subplebbit?.shortAddress}
</Link>
</p>
<PostTools commentCid={cid} />