mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
add offline indicator to all desktop views
This commit is contained in:
@@ -1,22 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import { useSubplebbit } from "@plebbit/plebbit-react-hooks";
|
|
||||||
import { Tooltip } from 'react-tooltip';
|
|
||||||
|
|
||||||
|
|
||||||
const BoardSubscription = ({ address }) => {
|
|
||||||
const subplebbit = useSubplebbit({ subplebbitAddress: address });
|
|
||||||
const isOnline = subplebbit.updatedAt > Date.now() / 1000 - 60 * 20;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{address} {!isOnline && (
|
|
||||||
<img className="disconnected" alt="offline" src="assets/offline.png"
|
|
||||||
data-tooltip-id="tooltip"
|
|
||||||
data-tooltip-content="OFFLINE"
|
|
||||||
data-tooltip-place="top" />
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default BoardSubscription;
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { useSubplebbit } from "@plebbit/plebbit-react-hooks";
|
||||||
|
|
||||||
|
|
||||||
|
const OfflineIndicator = ({ address, className, tooltipPlace }) => {
|
||||||
|
const subplebbit = useSubplebbit({ subplebbitAddress: address });
|
||||||
|
const isOnline = subplebbit.updatedAt > Date.now() / 1000 - 60 * 20;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{!isOnline && (
|
||||||
|
<>
|
||||||
|
{" "}
|
||||||
|
<img
|
||||||
|
className={className}
|
||||||
|
alt="offline"
|
||||||
|
src="assets/offline.png"
|
||||||
|
data-tooltip-id="tooltip"
|
||||||
|
data-tooltip-content="OFFLINE"
|
||||||
|
data-tooltip-place={tooltipPlace}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default OfflineIndicator;
|
||||||
@@ -30,6 +30,12 @@ export const NavBar = styled.div`
|
|||||||
#board-nav-mobile {
|
#board-nav-mobile {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.offline-nav {
|
||||||
|
width: 12px;
|
||||||
|
position: relative;
|
||||||
|
margin: 2px 2px -2px -2px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
@media (max-width: 480px) {
|
||||||
@@ -1617,6 +1623,13 @@ export const BoardForm = styled.div`
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.offline-sub {
|
||||||
|
width: 13px;
|
||||||
|
margin-right: -5px;
|
||||||
|
margin-bottom: -2px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
${({ selectedStyle }) => {
|
${({ selectedStyle }) => {
|
||||||
switch (selectedStyle) {
|
switch (selectedStyle) {
|
||||||
case 'Yotsuba':
|
case 'Yotsuba':
|
||||||
|
|||||||
@@ -286,18 +286,28 @@ export const BoardsContent = styled.div`
|
|||||||
.boardlink, #view-all {
|
.boardlink, #view-all {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disconnected {
|
||||||
|
width: 15px;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 480px) {
|
@media (min-width: 480px) {
|
||||||
#mobile-br {
|
#mobile-br {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disconnected {
|
||||||
|
width: 11px;
|
||||||
|
margin-bottom: -1px;
|
||||||
|
margin-top: 2px;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.disconnected {
|
|
||||||
width: 13px;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Footer = styled.div`
|
export const Footer = styled.div`
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import useGeneralStore from '../../hooks/stores/useGeneralStore';
|
|||||||
import { Container, NavBar, Header, Break, PostFormLink, PostFormTable, PostForm, TopBar, BoardForm } from '../styled/Board.styled';
|
import { Container, NavBar, Header, Break, PostFormLink, PostFormTable, PostForm, TopBar, BoardForm } from '../styled/Board.styled';
|
||||||
import { Footer } from '../styled/Thread.styled';
|
import { Footer } from '../styled/Thread.styled';
|
||||||
import ImageBanner from '../ImageBanner';
|
import ImageBanner from '../ImageBanner';
|
||||||
|
import OfflineIndicator from '../OfflineIndicator';
|
||||||
import Post from '../Post';
|
import Post from '../Post';
|
||||||
import PostLoader from '../PostLoader';
|
import PostLoader from '../PostLoader';
|
||||||
import ReplyModal from '../ReplyModal';
|
import ReplyModal from '../ReplyModal';
|
||||||
@@ -325,10 +326,8 @@ const Board = () => {
|
|||||||
try {
|
try {
|
||||||
if (subscribed === false) {
|
if (subscribed === false) {
|
||||||
await subscribe(selectedAddress);
|
await subscribe(selectedAddress);
|
||||||
setSuccessMessage(`Subscribed to ${selectedTitle ? selectedTitle : selectedAddress}`);
|
|
||||||
} else if (subscribed === true) {
|
} else if (subscribed === true) {
|
||||||
await unsubscribe(selectedAddress);
|
await unsubscribe(selectedAddress);
|
||||||
setSuccessMessage(`Unsubscribed from ${selectedTitle ? selectedTitle : selectedAddress}`);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setErrorMessage(error);
|
setErrorMessage(error);
|
||||||
@@ -360,6 +359,10 @@ const Board = () => {
|
|||||||
{index === 0 ? null : "\u00a0"}
|
{index === 0 ? null : "\u00a0"}
|
||||||
<Link to={`/p/${subplebbit.address}`} key={`a-${subplebbit.address}`} onClick={() => handleClickTitle(subplebbit.title, subplebbit.address)}
|
<Link to={`/p/${subplebbit.address}`} key={`a-${subplebbit.address}`} onClick={() => handleClickTitle(subplebbit.title, subplebbit.address)}
|
||||||
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
|
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
|
||||||
|
<OfflineIndicator
|
||||||
|
address={subplebbit.address}
|
||||||
|
className="offline-nav"
|
||||||
|
tooltipPlace="bottom" />
|
||||||
{index !== defaultSubplebbits.length - 1 ? " /" : null}
|
{index !== defaultSubplebbits.length - 1 ? " /" : null}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { Threads } from '../styled/Catalog.styled';
|
|||||||
import { TopBar, Footer } from '../styled/Thread.styled';
|
import { TopBar, Footer } from '../styled/Thread.styled';
|
||||||
import CatalogLoader from '../CatalogLoader';
|
import CatalogLoader from '../CatalogLoader';
|
||||||
import ImageBanner from '../ImageBanner';
|
import ImageBanner from '../ImageBanner';
|
||||||
|
import OfflineIndicator from '../OfflineIndicator';
|
||||||
import SettingsModal from '../SettingsModal';
|
import SettingsModal from '../SettingsModal';
|
||||||
import getCommentMediaInfo from '../../utils/getCommentMediaInfo';
|
import getCommentMediaInfo from '../../utils/getCommentMediaInfo';
|
||||||
import handleStyleChange from '../../utils/handleStyleChange';
|
import handleStyleChange from '../../utils/handleStyleChange';
|
||||||
@@ -239,10 +240,8 @@ const Catalog = () => {
|
|||||||
try {
|
try {
|
||||||
if (subscribed === false) {
|
if (subscribed === false) {
|
||||||
await subscribe(selectedAddress);
|
await subscribe(selectedAddress);
|
||||||
setSuccessMessage(`Subscribed to ${selectedTitle ? selectedTitle : selectedAddress}`);
|
|
||||||
} else if (subscribed === true) {
|
} else if (subscribed === true) {
|
||||||
await unsubscribe(selectedAddress);
|
await unsubscribe(selectedAddress);
|
||||||
setSuccessMessage(`Unsubscribed from ${selectedTitle ? selectedTitle : selectedAddress}`);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setErrorMessage(error);
|
setErrorMessage(error);
|
||||||
@@ -273,6 +272,10 @@ const Catalog = () => {
|
|||||||
setSelectedAddress(subplebbit.address);
|
setSelectedAddress(subplebbit.address);
|
||||||
}}
|
}}
|
||||||
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
|
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
|
||||||
|
<OfflineIndicator
|
||||||
|
address={subplebbit.address}
|
||||||
|
className="offline-nav"
|
||||||
|
tooltipPlace="bottom" />
|
||||||
{index !== defaultSubplebbits.length - 1 ? " /" : null}
|
{index !== defaultSubplebbits.length - 1 ? " /" : null}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import useGeneralStore from '../../hooks/stores/useGeneralStore';
|
|||||||
import { Link, useNavigate } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { Container, Header, Logo, Page, Search, About, AboutTitle, AboutContent, Boards, BoardsTitle, BoardsContent, Footer } from '../styled/Home.styled';
|
import { Container, Header, Logo, Page, Search, About, AboutTitle, AboutContent, Boards, BoardsTitle, BoardsContent, Footer } from '../styled/Home.styled';
|
||||||
import BoardAvatar from '../BoardAvatar';
|
import BoardAvatar from '../BoardAvatar';
|
||||||
import BoardSubscription from '../BoardSubscription';
|
import OfflineIndicator from '../OfflineIndicator';
|
||||||
import packageJson from '../../../package.json'
|
import packageJson from '../../../package.json'
|
||||||
import { Tooltip } from 'react-tooltip';
|
import { Tooltip } from 'react-tooltip';
|
||||||
const {version} = packageJson
|
const {version} = packageJson
|
||||||
@@ -104,7 +104,11 @@ const Home = () => {
|
|||||||
<>
|
<>
|
||||||
<Link key={`sub-${index}`} className="boardlink" to={`/p/${subscription}`}>
|
<Link key={`sub-${index}`} className="boardlink" to={`/p/${subscription}`}>
|
||||||
<br id="mobile-br" />
|
<br id="mobile-br" />
|
||||||
<BoardSubscription address={subscription} />
|
{subscription}
|
||||||
|
<OfflineIndicator
|
||||||
|
address={subscription}
|
||||||
|
className="disconnected"
|
||||||
|
tooltipPlace="top" />
|
||||||
</Link>
|
</Link>
|
||||||
<br />
|
<br />
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import useGeneralStore from '../../hooks/stores/useGeneralStore';
|
|||||||
import { Container, NavBar, Header, Break, TopBar, BoardForm } from '../styled/Board.styled';
|
import { Container, NavBar, Header, Break, TopBar, BoardForm } from '../styled/Board.styled';
|
||||||
import { Footer } from '../styled/Thread.styled';
|
import { Footer } from '../styled/Thread.styled';
|
||||||
import ImageBanner from '../ImageBanner';
|
import ImageBanner from '../ImageBanner';
|
||||||
|
import OfflineIndicator from '../OfflineIndicator';
|
||||||
import Post from '../Post';
|
import Post from '../Post';
|
||||||
import PostLoader from '../PostLoader';
|
import PostLoader from '../PostLoader';
|
||||||
import ReplyModal from '../ReplyModal';
|
import ReplyModal from '../ReplyModal';
|
||||||
@@ -173,6 +174,10 @@ const Subscriptions = () => {
|
|||||||
{index === 0 ? null : "\u00a0"}
|
{index === 0 ? null : "\u00a0"}
|
||||||
<Link to={`/p/${subplebbit.address}`} key={`a-${subplebbit.address}`} onClick={() => handleClickTitle(subplebbit.title, subplebbit.address)}
|
<Link to={`/p/${subplebbit.address}`} key={`a-${subplebbit.address}`} onClick={() => handleClickTitle(subplebbit.title, subplebbit.address)}
|
||||||
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
|
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
|
||||||
|
<OfflineIndicator
|
||||||
|
address={subplebbit.address}
|
||||||
|
className="offline-nav"
|
||||||
|
tooltipPlace="bottom" />
|
||||||
{index !== defaultSubplebbits.length - 1 ? " /" : null}
|
{index !== defaultSubplebbits.length - 1 ? " /" : null}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
@@ -387,6 +392,10 @@ const Subscriptions = () => {
|
|||||||
>{thread.subplebbitAddress.slice(0, 10) + "(...)"}</span>
|
>{thread.subplebbitAddress.slice(0, 10) + "(...)"}</span>
|
||||||
)}
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
|
<OfflineIndicator key={`oi-${index}`}
|
||||||
|
address={thread.subplebbitAddress}
|
||||||
|
className="offline-sub"
|
||||||
|
tooltipPlace="top" />
|
||||||
<span key={`rl1-${index}`}>
|
<span key={`rl1-${index}`}>
|
||||||
[
|
[
|
||||||
<Link key={`rl2-${index}`} to={`/p/${thread.subplebbitAddress}/c/${thread.cid}`} onClick={() => setSelectedThread(thread.cid)} className="reply-link" >Reply</Link>
|
<Link key={`rl2-${index}`} to={`/p/${thread.subplebbitAddress}/c/${thread.cid}`} onClick={() => setSelectedThread(thread.cid)} className="reply-link" >Reply</Link>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import useGeneralStore from '../../hooks/stores/useGeneralStore';
|
|||||||
import { Container, NavBar, Header, Break, PostForm, PostFormTable } from '../styled/Board.styled';
|
import { Container, NavBar, Header, Break, PostForm, PostFormTable } from '../styled/Board.styled';
|
||||||
import { ReplyFormLink, TopBar, BottomBar, BoardForm, Footer } from '../styled/Thread.styled';
|
import { ReplyFormLink, TopBar, BottomBar, BoardForm, Footer } from '../styled/Thread.styled';
|
||||||
import ImageBanner from '../ImageBanner';
|
import ImageBanner from '../ImageBanner';
|
||||||
|
import OfflineIndicator from '../OfflineIndicator';
|
||||||
import Post from '../Post';
|
import Post from '../Post';
|
||||||
import PostLoader from '../PostLoader';
|
import PostLoader from '../PostLoader';
|
||||||
import ReplyModal from '../ReplyModal';
|
import ReplyModal from '../ReplyModal';
|
||||||
@@ -297,6 +298,10 @@ const Thread = () => {
|
|||||||
setSelectedAddress(subplebbit.address);
|
setSelectedAddress(subplebbit.address);
|
||||||
}}
|
}}
|
||||||
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
|
>{subplebbit.title ? subplebbit.title : subplebbit.address}</Link>
|
||||||
|
<OfflineIndicator
|
||||||
|
address={subplebbit.address}
|
||||||
|
className="offline-nav"
|
||||||
|
tooltipPlace="bottom" />
|
||||||
{index !== defaultSubplebbits.length - 1 ? " /" : null}
|
{index !== defaultSubplebbits.length - 1 ? " /" : null}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Reference in New Issue
Block a user