added helmet title to all views

This commit is contained in:
plebbitor
2023-04-21 10:47:39 +02:00
parent a4c7e86adb
commit 6aa27c3e1e
6 changed files with 1891 additions and 1849 deletions
+201 -195
View File
@@ -1,6 +1,7 @@
import React, { useState, useEffect, useRef, Fragment } from 'react';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { Helmet } from 'react-helmet-async';
import InfiniteScroll from 'react-infinite-scroller';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { useFeed, usePublishComment } from '@plebbit/plebbit-react-hooks';
import { debounce } from 'lodash';
import useGeneralStore from '../../hooks/stores/useGeneralStore';
@@ -202,210 +203,215 @@ const Catalog = () => {
return (
<Container>
<SettingsModal
selectedStyle={selectedStyle}
isOpen={isSettingsOpen}
closeModal={() => setIsSettingsOpen(false)} />
<NavBar selectedStyle={selectedStyle}>
<>
{defaultSubplebbits.map(subplebbit => (
<span className="boardList" key={`span-${subplebbit.address}`}>
<>
<Helmet>
<title>{((selectedTitle ? selectedTitle : selectedAddress) + " - Catalog - plebchan")}</title>
</Helmet>
<Container>
<SettingsModal
selectedStyle={selectedStyle}
isOpen={isSettingsOpen}
closeModal={() => setIsSettingsOpen(false)} />
<NavBar selectedStyle={selectedStyle}>
<>
{defaultSubplebbits.map(subplebbit => (
<span className="boardList" key={`span-${subplebbit.address}`}>
[
<Link to={`/p/${subplebbit.address}`} key={`a-${subplebbit.address}`}
onClick={() => {
setSelectedTitle(subplebbit.title);
setSelectedAddress(subplebbit.address);
}}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
]&nbsp;
</span>
))}
<span className="nav">
[
<Link to={`/p/${subplebbit.address}`} key={`a-${subplebbit.address}`}
onClick={() => {
setSelectedTitle(subplebbit.title);
setSelectedAddress(subplebbit.address);
}}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
]&nbsp;
</span>
))}
<span className="nav">
[
<Link to={`/p/${selectedAddress}/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
]
[
<Link to="/" onClick={() => handleStyleChange({target: {value: "Yotsuba"}}
)}>Home</Link>
]
</span>
<div id="board-nav-mobile" style={{ top: visible ? 0 : '-23px' }}>
<div className="board-select">
<strong>Board</strong>
&nbsp;
<select id="board-select-mobile" value={selectedAddress} onChange={handleSelectChange}>
{defaultSubplebbits.map(subplebbit => (
<option key={`option-${subplebbit.address}`} value={subplebbit.address}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
))}
</select>
</div>
<div className="page-jump">
<Link to={`/p/${selectedAddress}/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
&nbsp;
]
[
<Link to="/" onClick={() => handleStyleChange({target: {value: "Yotsuba"}}
)}>Home</Link>
)}>Home</Link>
]
</span>
<div id="board-nav-mobile" style={{ top: visible ? 0 : '-23px' }}>
<div className="board-select">
<strong>Board</strong>
&nbsp;
<select id="board-select-mobile" value={selectedAddress} onChange={handleSelectChange}>
{defaultSubplebbits.map(subplebbit => (
<option key={`option-${subplebbit.address}`} value={subplebbit.address}
>{subplebbit.title ? subplebbit.title : subplebbit.address}</option>
))}
</select>
</div>
<div className="page-jump">
<Link to={`/p/${selectedAddress}/catalog/settings`} onClick={() => setIsSettingsOpen(true)}>Settings</Link>
&nbsp;
<Link to="/" onClick={() => handleStyleChange({target: {value: "Yotsuba"}}
)}>Home</Link>
</div>
</div>
</div>
<div id="separator-mobile">&nbsp;</div>
<div id="separator-mobile">&nbsp;</div>
</>
</NavBar>
<Header selectedStyle={selectedStyle}>
<>
<div className="banner">
<ImageBanner />
</div>
<>
<div className="board-title">{selectedTitle}</div>
<div className="board-address">p/{selectedAddress}</div>
</>
</>
</Header>
<Break selectedStyle={selectedStyle} />
<PostForm selectedStyle={selectedStyle}>
<PostFormLink id="post-form-link" showPostFormLink={showPostFormLink} selectedStyle={selectedStyle} >
<div id="post-form-link-desktop">
<div id="separator-mobile">&nbsp;</div>
<div id="separator-mobile">&nbsp;</div>
</>
</NavBar>
<Header selectedStyle={selectedStyle}>
<>
<div className="banner">
<ImageBanner />
</div>
<>
<div className="board-title">{selectedTitle}</div>
<div className="board-address">p/{selectedAddress}</div>
</>
</>
</Header>
<Break selectedStyle={selectedStyle} />
<PostForm selectedStyle={selectedStyle}>
<PostFormLink id="post-form-link" showPostFormLink={showPostFormLink} selectedStyle={selectedStyle} >
<div id="post-form-link-desktop">
[
<a onClick={useClickForm()} onMouseOver={(event) => event.target.style.cursor='pointer'}>Start a New Thread</a>
]
</div>
<div id="post-form-link-mobile">
<span className="btn-wrap">
<a onClick={useClickForm()} onMouseOver={(event) => event.target.style.cursor='pointer'}>Start a New Thread</a>
</span>
</div>
</PostFormLink>
<PostFormTable id="post-form" showPostForm={showPostForm} selectedStyle={selectedStyle} className="post-form">
<tbody>
<tr data-type="Name">
<td id="td-name">Name</td>
<td>
<input name="name" type="text" tabIndex={1} placeholder="Anonymous" ref={nameRef} />
</td>
</tr>
<tr data-type="Subject">
<td>Subject</td>
<td>
<input name="sub" type="text" tabIndex={3} ref={subjectRef}/>
<input id="post-button" type="submit" value="Post" tabIndex={6}
onClick={handleSubmit} />
</td>
</tr>
<tr data-type="Comment">
<td>Comment</td>
<td>
<textarea name="com" cols="48" rows="4" tabIndex={4} wrap="soft" ref={commentRef} />
</td>
</tr>
<tr data-type="File">
<td>Embed File</td>
<td>
<input name="embed" type="text" tabIndex={7} placeholder="Paste link" ref={linkRef} />
<button id="t-help" type="button" onClick={
() => alert("- Embedding media is optional, posts can be text-only. \n- A CAPTCHA challenge will appear after posting. \n- The CAPTCHA is case-sensitive.")
} data-tip="Help">?</button>
</td>
</tr>
</tbody>
</PostFormTable>
</PostForm>
<TopBar selectedStyle={selectedStyle}>
<hr />
<span className="style-changer">
Style:
 
<select id="style-selector" onChange={handleStyleChange} value={selectedStyle}>
<option value="Yotsuba">Yotsuba</option>
<option value="Yotsuba-B">Yotsuba B</option>
<option value="Futaba">Futaba</option>
<option value="Burichan">Burichan</option>
<option value="Tomorrow">Tomorrow</option>
<option value="Photon">Photon</option>
</select>
</span>
<div className="return-button" id="return-button-desktop">
[
<a onClick={useClickForm()} onMouseOver={(event) => event.target.style.cursor='pointer'}>Start a New Thread</a>
<Link to={`/p/${selectedAddress}`}>Return</Link>
]
</div>
<div id="post-form-link-mobile">
<span className="btn-wrap">
<a onClick={useClickForm()} onMouseOver={(event) => event.target.style.cursor='pointer'}>Start a New Thread</a>
<div id="return-button-mobile">
<span className="btn-wrap-catalog btn-wrap">
<Link to={`/p/${selectedAddress}`}>Return</Link>
</span>
</div>
</PostFormLink>
<PostFormTable id="post-form" showPostForm={showPostForm} selectedStyle={selectedStyle} className="post-form">
<tbody>
<tr data-type="Name">
<td id="td-name">Name</td>
<td>
<input name="name" type="text" tabIndex={1} placeholder="Anonymous" ref={nameRef} />
</td>
</tr>
<tr data-type="Subject">
<td>Subject</td>
<td>
<input name="sub" type="text" tabIndex={3} ref={subjectRef}/>
<input id="post-button" type="submit" value="Post" tabIndex={6}
onClick={handleSubmit} />
</td>
</tr>
<tr data-type="Comment">
<td>Comment</td>
<td>
<textarea name="com" cols="48" rows="4" tabIndex={4} wrap="soft" ref={commentRef} />
</td>
</tr>
<tr data-type="File">
<td>Embed File</td>
<td>
<input name="embed" type="text" tabIndex={7} placeholder="Paste link" ref={linkRef} />
<button id="t-help" type="button" onClick={
() => alert("- Embedding media is optional, posts can be text-only. \n- A CAPTCHA challenge will appear after posting. \n- The CAPTCHA is case-sensitive.")
} data-tip="Help">?</button>
</td>
</tr>
</tbody>
</PostFormTable>
</PostForm>
<TopBar selectedStyle={selectedStyle}>
<hr />
<span className="style-changer">
Style:
 
<select id="style-selector" onChange={handleStyleChange} value={selectedStyle}>
<option value="Yotsuba">Yotsuba</option>
<option value="Yotsuba-B">Yotsuba B</option>
<option value="Futaba">Futaba</option>
<option value="Burichan">Burichan</option>
<option value="Tomorrow">Tomorrow</option>
<option value="Photon">Photon</option>
</select>
</span>
<div className="return-button" id="return-button-desktop">
[
<Link to={`/p/${selectedAddress}`}>Return</Link>
]
</div>
<div id="return-button-mobile">
<span className="btn-wrap-catalog btn-wrap">
<Link to={`/p/${selectedAddress}`}>Return</Link>
</span>
</div>
<div id="stats" style={{float: "right", marginTop: "5px"}}>
{feed.length > 0 ? (null) : (<span>Fetching IPFS...</span>)}
</div>
<hr />
</TopBar>
<Threads selectedStyle={selectedStyle}>
{feed.length < 1 ? (
<CatalogLoader />
) : (
<InfiniteScroll
pageStart={0}
loadMore={tryLoadMore}
hasMore={hasMore}
>
{feed.map((thread) => {
const commentMediaInfo = getCommentMediaInfo(thread);
const fallbackImgUrl = "/assets/filedeleted-res.gif";
return (
<Link style={{all: "unset", cursor: "pointer"}} key={`link-${thread.cid}`} to={`/p/${selectedAddress}/c/${thread.cid}`} onClick={() => setSelectedThread(thread.cid)}>
<div key={`thread-${thread.cid}`} className="thread">
{commentMediaInfo?.url ? (
<Fragment key="f-catalog">
{commentMediaInfo?.type === "webpage" ? (
<img key={`img-${thread.cid}`} alt="thread"
src={commentMediaInfo.url}
onError={(e) => {
e.target.src = fallbackImgUrl
e.target.onerror = null;}} />
) : null}
{commentMediaInfo?.type === "image" ? (
<img key={`img-${thread.cid}`} alt="thread"
src={commentMediaInfo.url}
onError={(e) => {
e.target.src = fallbackImgUrl
e.target.onerror = null;}} />
) : null}
{commentMediaInfo?.type === "video" ? (
<video key={`fti-${thread.cid}`}
src={commentMediaInfo.url}
alt={commentMediaInfo.type}
style={{ pointerEvents: "none" }}
onError={(e) => e.target.src = fallbackImgUrl} />
) : null}
{commentMediaInfo?.type === "audio" ? (
<audio controls
key={`fti-${thread.cid}`}
src={commentMediaInfo.url}
alt={commentMediaInfo.type}
style={{ pointerEvents: "none" }}
onError={(e) => e.target.src = fallbackImgUrl} />
) : null}
</Fragment>
) : null}
{/* <div key={`ti-${thread.cid}`} className="thread-icons" >
<span key={`si-${thread.cid}`} className="thread-icon sticky-icon" title="Sticky"></span>
</div> */}
<div key={`meta-${thread.cid}`} className="meta" title="(R)eplies / (I)mage Replies" >
R:
<b key={`b-${thread.cid}`}>{thread.replyCount}</b>
<div id="stats" style={{float: "right", marginTop: "5px"}}>
{feed.length > 0 ? (null) : (<span>Fetching IPFS...</span>)}
</div>
<hr />
</TopBar>
<Threads selectedStyle={selectedStyle}>
{feed.length < 1 ? (
<CatalogLoader />
) : (
<InfiniteScroll
pageStart={0}
loadMore={tryLoadMore}
hasMore={hasMore}
>
{feed.map((thread) => {
const commentMediaInfo = getCommentMediaInfo(thread);
const fallbackImgUrl = "/assets/filedeleted-res.gif";
return (
<Link style={{all: "unset", cursor: "pointer"}} key={`link-${thread.cid}`} to={`/p/${selectedAddress}/c/${thread.cid}`} onClick={() => setSelectedThread(thread.cid)}>
<div key={`thread-${thread.cid}`} className="thread">
{commentMediaInfo?.url ? (
<Fragment key="f-catalog">
{commentMediaInfo?.type === "webpage" ? (
<img key={`img-${thread.cid}`} alt="thread"
src={commentMediaInfo.url}
onError={(e) => {
e.target.src = fallbackImgUrl
e.target.onerror = null;}} />
) : null}
{commentMediaInfo?.type === "image" ? (
<img key={`img-${thread.cid}`} alt="thread"
src={commentMediaInfo.url}
onError={(e) => {
e.target.src = fallbackImgUrl
e.target.onerror = null;}} />
) : null}
{commentMediaInfo?.type === "video" ? (
<video key={`fti-${thread.cid}`}
src={commentMediaInfo.url}
alt={commentMediaInfo.type}
style={{ pointerEvents: "none" }}
onError={(e) => e.target.src = fallbackImgUrl} />
) : null}
{commentMediaInfo?.type === "audio" ? (
<audio controls
key={`fti-${thread.cid}`}
src={commentMediaInfo.url}
alt={commentMediaInfo.type}
style={{ pointerEvents: "none" }}
onError={(e) => e.target.src = fallbackImgUrl} />
) : null}
</Fragment>
) : null}
{/* <div key={`ti-${thread.cid}`} className="thread-icons" >
<span key={`si-${thread.cid}`} className="thread-icon sticky-icon" title="Sticky"></span>
</div> */}
<div key={`meta-${thread.cid}`} className="meta" title="(R)eplies / (I)mage Replies" >
R:
<b key={`b-${thread.cid}`}>{thread.replyCount}</b>
</div>
<div key={`t-${thread.cid}`} className="teaser">
<b key={`b2-${thread.cid}`}>{thread.title ? `${thread.title}` : null}</b>
{thread.content ? `: ${thread.content}` : null}
</div>
</div>
<div key={`t-${thread.cid}`} className="teaser">
<b key={`b2-${thread.cid}`}>{thread.title ? `${thread.title}` : null}</b>
{thread.content ? `: ${thread.content}` : null}
</div>
</div>
</Link>
)})}
</InfiniteScroll>
)}
</Threads>
</Container>
</Link>
)})}
</InfiniteScroll>
)}
</Threads>
</Container>
</>
);
}