diff --git a/src/views/home/home.module.css b/src/views/home/home.module.css index ce973af0..7cc4b837 100644 --- a/src/views/home/home.module.css +++ b/src/views/home/home.module.css @@ -124,6 +124,17 @@ text-decoration: var(--homepage-box-link-text-decoration-hover); } +.list span { + display: inline-block; + font-weight: 700; + color: var(--homepage-box-link-text-color); +} + +.list span:hover { + color: var(--homepage-box-link-text-color-hover); + cursor: pointer; +} + .boardsBoxContent { font-size: 93%; padding: 0.5em; @@ -135,11 +146,26 @@ .boardsBoxContent .column { float: left; - width: 163px; - margin-right: 20px; + min-width: 163px; + padding-right: 20px; overflow: hidden; } +.subplebbit { + position: relative; +} + +.offlineIcon { + background-image: url('/public/assets/icons/offline.png'); + background-size: 100%; + position: absolute; + width: 13px; + height: 13px; + margin-left: 3px; + display: inline-block; + image-rendering: pixelated; +} + .boardsBoxContent h3 { font-size: 100%; font-weight: 700; diff --git a/src/views/home/home.tsx b/src/views/home/home.tsx index 0c3eb3ca..7747347a 100644 --- a/src/views/home/home.tsx +++ b/src/views/home/home.tsx @@ -1,8 +1,8 @@ -import { useRef } from 'react'; -import styles from './home.module.css'; +import { useMemo, useRef, useState } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { Trans, useTranslation } from 'react-i18next'; import { Subplebbit } from '@plebbit/plebbit-react-hooks'; +import styles from './home.module.css'; import packageJson from '../../../package.json'; interface HomeProps { @@ -71,6 +71,27 @@ const InfoBox = () => { const Boards = ({ subplebbits }: HomeProps) => { const { t } = useTranslation(); + const sortedSubplebbits = useMemo(() => { + const oneHourAgo = Date.now() - 60 * 60 * 1000; + const retainedSubplebbits: (Subplebbit | undefined)[] = []; + const offlineSubplebbits: Subplebbit[] = []; + + subplebbits.forEach((sub: Subplebbit | undefined) => { + if (!sub || sub.updatedAt === undefined) { + // retain the position of loading or undefined subplebbits + retainedSubplebbits.push(sub); + } else if (sub.updatedAt * 1000 > oneHourAgo) { + // retain the position of online subplebbits + retainedSubplebbits.push(sub); + } else { + // push offline subs to the end of the list + offlineSubplebbits.push(sub); + } + }); + return [...retainedSubplebbits, ...offlineSubplebbits]; + }, [subplebbits]); + + const [showAllBoards, setShowAllBoards] = useState(false); return (
@@ -82,21 +103,27 @@ const Boards = ({ subplebbits }: HomeProps) => {

Default SFW

- {subplebbits + {sortedSubplebbits .filter((subplebbit): subplebbit is Subplebbit => subplebbit !== undefined) + .slice(0, showAllBoards ? undefined : 18) .map((subplebbit) => { - const address = subplebbit.address; + const { address, updatedAt } = subplebbit || {}; + const isOffline = updatedAt && updatedAt * 1000 < Date.now() - 60 * 60 * 1000; // 1 hour return (
{address} + {isOffline && }
); })} + {sortedSubplebbits.length > 17 && ( + <> + {!showAllBoards ? '... ' : null} + setShowAllBoards(!showAllBoards)}>{showAllBoards ? '[show less]' : '[show more]'} + + )}
-
-

Default NSFW

-

Subscriptions