mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
feat(home): push subs that are offline at the end of the list, show offline icon
This commit is contained in:
@@ -124,6 +124,17 @@
|
|||||||
text-decoration: var(--homepage-box-link-text-decoration-hover);
|
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 {
|
.boardsBoxContent {
|
||||||
font-size: 93%;
|
font-size: 93%;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
@@ -135,11 +146,26 @@
|
|||||||
|
|
||||||
.boardsBoxContent .column {
|
.boardsBoxContent .column {
|
||||||
float: left;
|
float: left;
|
||||||
width: 163px;
|
min-width: 163px;
|
||||||
margin-right: 20px;
|
padding-right: 20px;
|
||||||
overflow: hidden;
|
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 {
|
.boardsBoxContent h3 {
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|||||||
+34
-7
@@ -1,8 +1,8 @@
|
|||||||
import { useRef } from 'react';
|
import { useMemo, useRef, useState } from 'react';
|
||||||
import styles from './home.module.css';
|
|
||||||
import { Link, useNavigate } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { Trans, useTranslation } from 'react-i18next';
|
import { Trans, useTranslation } from 'react-i18next';
|
||||||
import { Subplebbit } from '@plebbit/plebbit-react-hooks';
|
import { Subplebbit } from '@plebbit/plebbit-react-hooks';
|
||||||
|
import styles from './home.module.css';
|
||||||
import packageJson from '../../../package.json';
|
import packageJson from '../../../package.json';
|
||||||
|
|
||||||
interface HomeProps {
|
interface HomeProps {
|
||||||
@@ -71,6 +71,27 @@ const InfoBox = () => {
|
|||||||
|
|
||||||
const Boards = ({ subplebbits }: HomeProps) => {
|
const Boards = ({ subplebbits }: HomeProps) => {
|
||||||
const { t } = useTranslation();
|
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 (
|
return (
|
||||||
<div className={styles.box}>
|
<div className={styles.box}>
|
||||||
@@ -82,21 +103,27 @@ const Boards = ({ subplebbits }: HomeProps) => {
|
|||||||
<div className={styles.column}>
|
<div className={styles.column}>
|
||||||
<h3>Default SFW</h3>
|
<h3>Default SFW</h3>
|
||||||
<div className={styles.list}>
|
<div className={styles.list}>
|
||||||
{subplebbits
|
{sortedSubplebbits
|
||||||
.filter((subplebbit): subplebbit is Subplebbit => subplebbit !== undefined)
|
.filter((subplebbit): subplebbit is Subplebbit => subplebbit !== undefined)
|
||||||
|
.slice(0, showAllBoards ? undefined : 18)
|
||||||
.map((subplebbit) => {
|
.map((subplebbit) => {
|
||||||
const address = subplebbit.address;
|
const { address, updatedAt } = subplebbit || {};
|
||||||
|
const isOffline = updatedAt && updatedAt * 1000 < Date.now() - 60 * 60 * 1000; // 1 hour
|
||||||
return (
|
return (
|
||||||
<div className={styles.subplebbit} key={address}>
|
<div className={styles.subplebbit} key={address}>
|
||||||
<Link to={`/p/${address}`}>{address}</Link>
|
<Link to={`/p/${address}`}>{address}</Link>
|
||||||
|
{isOffline && <span className={styles.offlineIcon} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
{sortedSubplebbits.length > 17 && (
|
||||||
|
<>
|
||||||
|
{!showAllBoards ? '... ' : null}
|
||||||
|
<span onClick={() => setShowAllBoards(!showAllBoards)}>{showAllBoards ? '[show less]' : '[show more]'}</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.column}>
|
|
||||||
<h3>Default NSFW</h3>
|
|
||||||
</div>
|
|
||||||
<div className={styles.column}>
|
<div className={styles.column}>
|
||||||
<h3>Subscriptions</h3>
|
<h3>Subscriptions</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user