feat(board): add mobile footer with Start a New Thread, Top, Refresh, pagination, Catalog, Load More

This commit is contained in:
plebeius
2026-03-01 20:45:26 +08:00
parent 5e48483b21
commit 1a4e8a624b
39 changed files with 200 additions and 37 deletions
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "المنتديات التي تقوم بالإشراف عليها",
"link_to_file": "رابط للملف",
"support_5chan": "دعم 5chan",
"images": "صور"
"images": "صور",
"load_more": "تحميل المزيد"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "আপনি যা মডারেট করেন এমন বোর্ড",
"link_to_file": "ফাইলের লিংক",
"support_5chan": "5chan সমর্থন করুন",
"images": "ছবি"
"images": "ছবি",
"load_more": "আরও লোড করুন"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Fóra, která moderujete",
"link_to_file": "Odkaz na soubor",
"support_5chan": "Podpořte 5chan",
"images": "obrázky"
"images": "obrázky",
"load_more": "Načíst více"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Boards du modererer",
"link_to_file": "Link til fil",
"support_5chan": "Støt 5chan",
"images": "billeder"
"images": "billeder",
"load_more": "Indlæs mere"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Von dir moderierte Boards",
"link_to_file": "Link zur Datei",
"support_5chan": "5chan unterstützen",
"images": "Bilder"
"images": "Bilder",
"load_more": "Mehr laden"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Πίνακες που διαχειρίζεστε",
"link_to_file": "Σύνδεσμος προς αρχείο",
"support_5chan": "Υποστηρίξτε το 5chan",
"images": "εικόνες"
"images": "εικόνες",
"load_more": "Φόρτωση περισσότερων"
}
+1
View File
@@ -107,6 +107,7 @@
"expand_all_settings": "Expand All Settings",
"collapse_all_settings": "Collapse All Settings",
"refresh": "Refresh",
"load_more": "Load More",
"none": "none",
"not_subscribed_to_any_board": "You have not subscribed to any board yet.",
"this_post_was_removed": "this post was removed",
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Tableros que moderas",
"link_to_file": "Enlace al archivo",
"support_5chan": "Apoyar 5chan",
"images": "imágenes"
"images": "imágenes",
"load_more": "Cargar más"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "تابلوهایی که مدیریت می‌کنید",
"link_to_file": "لینک به فایل",
"support_5chan": "از 5chan پشتیبانی کنید",
"images": "تصاویر"
"images": "تصاویر",
"load_more": "بارگذاری بیشتر"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Laudat, joita moderoit",
"link_to_file": "Linkki tiedostoon",
"support_5chan": "Tue 5chan",
"images": "kuvat"
"images": "kuvat",
"load_more": "Lataa lisää"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Mga board na minomodera mo",
"link_to_file": "Link sa File",
"support_5chan": "Suportahan ang 5chan",
"images": "mga larawan"
"images": "mga larawan",
"load_more": "Mag-load ng higit pa"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Tableaux que vous modérez",
"link_to_file": "Lien vers le fichier",
"support_5chan": "Soutenir 5chan",
"images": "images"
"images": "images",
"load_more": "Charger plus"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "לוחות שאתה מפקח עליהם",
"link_to_file": "קישור לקובץ",
"support_5chan": "תמוך ב-5chan",
"images": "תמונות"
"images": "תמונות",
"load_more": "טען עוד"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "बोर्ड जिन्हें आप मॉडरेट करते हैं",
"link_to_file": "फ़ाइल का लिंक",
"support_5chan": "5chan का समर्थन करें",
"images": "छवियाँ"
"images": "छवियाँ",
"load_more": "और लोड करें"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "A táblák, amelyeket moderálsz",
"link_to_file": "Link a fájlhoz",
"support_5chan": "5chan támogatása",
"images": "képek"
"images": "képek",
"load_more": "További betöltése"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Papan yang Anda moderasi",
"link_to_file": "Tautan ke File",
"support_5chan": "Dukung 5chan",
"images": "gambar"
"images": "gambar",
"load_more": "Muat lebih banyak"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Board che moderi",
"link_to_file": "Link al file",
"support_5chan": "Supporta 5chan",
"images": "immagini"
"images": "immagini",
"load_more": "Carica altro"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "あなたがモデレートする板",
"link_to_file": "ファイルへのリンク",
"support_5chan": "5chanをサポート",
"images": "画像"
"images": "画像",
"load_more": "さらに読み込む"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "당신이 관리하는 게시판",
"link_to_file": "파일 링크",
"support_5chan": "5chan 지원",
"images": "이미지"
"images": "이미지",
"load_more": "더 보기"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "तुम्ही मॉडरेट करता ते बोर्ड",
"link_to_file": "फाइलची लिंक",
"support_5chan": "5chan चे समर्थन करा",
"images": "प्रतिमा"
"images": "प्रतिमा",
"load_more": "अधिक लोड करा"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Boards die je beheert",
"link_to_file": "Link naar bestand",
"support_5chan": "Steun 5chan",
"images": "afbeeldingen"
"images": "afbeeldingen",
"load_more": "Meer laden"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Boards du modererer",
"link_to_file": "Lenke til fil",
"support_5chan": "Støtt 5chan",
"images": "bilder"
"images": "bilder",
"load_more": "Last inn mer"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Tablice, które moderujesz",
"link_to_file": "Link do pliku",
"support_5chan": "Wspieraj 5chan",
"images": "obrazy"
"images": "obrazy",
"load_more": "Załaduj więcej"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Quadros que você modera",
"link_to_file": "Link para o arquivo",
"support_5chan": "Apoiar 5chan",
"images": "imagens"
"images": "imagens",
"load_more": "Carregar mais"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Forumuri pe care le moderezi",
"link_to_file": "Link către fișier",
"support_5chan": "Sprijiniți 5chan",
"images": "imagini"
"images": "imagini",
"load_more": "Încarcă mai mult"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Доски, которые вы модерируете",
"link_to_file": "Ссылка на файл",
"support_5chan": "Поддержать 5chan",
"images": "изображения"
"images": "изображения",
"load_more": "Загрузить ещё"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Bordet që moderoni",
"link_to_file": "Lidhje me skedarin",
"support_5chan": "Mbështetni 5chan",
"images": "imazhe"
"images": "imazhe",
"load_more": "Ngarko më shumë"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Boards du modererar",
"link_to_file": "Länk till fil",
"support_5chan": "Stöd 5chan",
"images": "bilder"
"images": "bilder",
"load_more": "Ladda mer"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "మీరు మోడరేట్ చేసే బోర్డ్లు",
"link_to_file": "ఫైల్‌కు లింక్",
"support_5chan": "5chanకు మద్దతు ఇవ్వండి",
"images": "చిత్రాలు"
"images": "చిత్రాలు",
"load_more": "మరింత లోడ్ చేయండి"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "บอร์ดที่คุณดูแล",
"link_to_file": "ลิงก์ไปยังไฟล์",
"support_5chan": "สนับสนุน 5chan",
"images": "รูปภาพ"
"images": "รูปภาพ",
"load_more": "โหลดเพิ่มเติม"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Yönettiğiniz panolar",
"link_to_file": "Dosyaya bağlantı",
"support_5chan": "5chan'ı Destekle",
"images": "görseller"
"images": "görseller",
"load_more": "Daha fazla yükle"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Дошки, які ви модеруєте",
"link_to_file": "Посилання на файл",
"support_5chan": "Підтримати 5chan",
"images": "зображення"
"images": "зображення",
"load_more": "Завантажити ще"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "بورڈز جنہیں آپ ماڈریٹ کرتے ہیں",
"link_to_file": "فائل کا لنک",
"support_5chan": "5chan کی حمایت کریں",
"images": "تصاویر"
"images": "تصاویر",
"load_more": "مزید لوڈ کریں"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "Các bảng bạn điều hành",
"link_to_file": "Liên kết đến tệp",
"support_5chan": "Hỗ trợ 5chan",
"images": "hình ảnh"
"images": "hình ảnh",
"load_more": "Tải thêm"
}
+2 -1
View File
@@ -296,5 +296,6 @@
"boards_you_moderate_nav": "您管理的板块",
"link_to_file": "链接到文件",
"support_5chan": "支持 5chan",
"images": "图片"
"images": "图片",
"load_more": "加载更多"
}
+57
View File
@@ -152,3 +152,60 @@
display: none;
}
}
/* Mobile page footer — hidden on desktop, shown on mobile */
.mobileFooter {
display: none;
}
@media (max-width: 640px) {
.mobileFooter {
display: block;
text-align: center;
padding: 0 0 16px;
}
}
.mobileFooterButtons {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 6px;
padding: 8px 8px;
}
.mobileFooterPagination {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 10px;
padding: 4px 8px;
font-size: 16px;
color: var(--boardsbar-desktop-link-text-color);
}
.mobileFooterPagination a {
text-decoration: none;
color: var(--boardsbar-desktop-link-text-color);
}
.mobileFooterPaginationCurrent {
font-weight: bold;
}
.mobileFooterLinks {
padding: 12px 8px 4px;
font-size: 10px;
text-align: center;
}
.mobileFooterLinks a {
color: var(--boardsbar-desktop-link-text-color);
text-decoration: underline;
}
.mobileFooterLinks a:hover {
color: var(--boardsbar-desktop-link-text-color-hover);
}
+16
View File
@@ -149,3 +149,19 @@ export const ThreadFooterFirstRow = ({ postCid, threadNumber, subplebbitAddress,
</div>
);
};
/* -----------------------------------------------------------------------------
* PageFooterMobile
* Mobile-only page footer with content slot and footer links.
* -------------------------------------------------------------------------- */
export const PageFooterMobile = ({ children }: { children: React.ReactNode }) => (
<footer className={styles.mobileFooter}>
<hr />
{children}
<hr />
<div className={styles.mobileFooterLinks}>
<SiteLegalMeta order='license-first' />
</div>
</footer>
);
+1 -1
View File
@@ -1,2 +1,2 @@
export { PageFooterDesktop, CatalogFooterFirstRow, ThreadFooterFirstRow, ThreadFooterStyleRow } from './footer';
export { PageFooterDesktop, PageFooterMobile, CatalogFooterFirstRow, ThreadFooterFirstRow, ThreadFooterStyleRow } from './footer';
export type { PageFooterDesktopProps, CatalogFooterFirstRowProps, ThreadFooterFirstRowProps } from './footer';
+57 -2
View File
@@ -1,10 +1,11 @@
import { useCallback, useEffect, useMemo, useRef } from 'react';
import { useLocation, useNavigate, useNavigationType, useParams } from 'react-router-dom';
import { Link, useLocation, useNavigate, useNavigationType, useParams } from 'react-router-dom';
import { Comment, useAccount, useAccountComments, useAccountSubplebbits, useFeed, useSubplebbit } from '@bitsocialhq/pkc-react-hooks';
import { useSubplebbitField } from '../../hooks/use-stable-subplebbit';
import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
import { useTranslation } from 'react-i18next';
import styles from './board.module.css';
import mobileFooterStyles from '../../components/footer/footer.module.css';
import { shouldShowSnow } from '../../lib/snow';
import { useDirectoryAddresses, useDirectories, useDirectoryByAddress } from '../../hooks/use-directories';
import { useFilteredDirectoryAddresses } from '../../hooks/use-filtered-directory-addresses';
@@ -18,7 +19,7 @@ import { getPageFromFeedPath, getSubplebbitAddress, isDirectoryBoard, normalizeM
import ErrorDisplay from '../../components/error-display/error-display';
import LoadingEllipsis from '../../components/loading-ellipsis';
import BoardPagination from '../../components/board-pagination';
import { PageFooterDesktop } from '../../components/footer';
import { PageFooterDesktop, PageFooterMobile } from '../../components/footer';
import { Post } from '../post';
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
@@ -131,6 +132,7 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, i
}, [isInAllView, isInSubscriptionsView, isInModView, subplebbitAddress, directoryAddresses, filteredDirectoryAddresses, subscriptions, accountSubplebbitAddresses]);
const enableInfiniteScroll = useFeedViewSettingsStore((state) => state.enableInfiniteScroll);
const setEnableInfiniteScroll = useFeedViewSettingsStore((state) => state.setEnableInfiniteScroll);
const isForcedInfiniteScroll = isInAllView || isInSubscriptionsView || isInModView;
const effectiveInfiniteScroll = enableInfiniteScroll || isForcedInfiniteScroll;
const community = useDirectoryByAddress(isInAllView || isInSubscriptionsView || isInModView ? undefined : subplebbitAddress);
@@ -267,6 +269,56 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, i
<BoardPagination basePath={paginationBasePath} currentPage={currentPage} totalPages={totalPages} footerStyle isMultiboard={isForcedInfiniteScroll} />
}
/>
<PageFooterMobile>
<div>
{!isForcedInfiniteScroll && (
<div className={mobileFooterStyles.mobileFooterButtons}>
<button className='button' onClick={() => window.scrollTo({ top: 0, left: 0, behavior: 'instant' })}>
{t('start_new_thread')}
</button>
</div>
)}
<div className={mobileFooterStyles.mobileFooterButtons}>
<button className='button' onClick={() => window.scrollTo({ top: 0, left: 0, behavior: 'instant' })}>
{t('top')}
</button>
<button className='button' onClick={() => reset && reset()}>
{t('refresh')}
</button>
</div>
<hr />
{!isForcedInfiniteScroll && !effectiveInfiniteScroll && (
<>
<div className={mobileFooterStyles.mobileFooterPagination}>
{Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => (
<span key={page}>
[
<Link
to={page === 1 ? paginationBasePath : `${paginationBasePath}/${page}`}
className={page === currentPage ? mobileFooterStyles.mobileFooterPaginationCurrent : undefined}
>
{page}
</Link>
]
</span>
))}
</div>
<div className={mobileFooterStyles.mobileFooterButtons}>
<Link to={`${paginationBasePath}/catalog`} className='button'>
{t('catalog')}
</Link>
</div>
</>
)}
{hasMore && !effectiveInfiniteScroll && (
<div className={mobileFooterStyles.mobileFooterButtons}>
<button className='button' onClick={() => setEnableInfiniteScroll(true)}>
{t('load_more')}
</button>
</div>
)}
</div>
</PageFooterMobile>
</>
),
}),
@@ -285,6 +337,9 @@ const Board = ({ feedCacheKey, viewType, boardIdentifier: boardIdentifierProp, i
paginationBasePath,
currentPage,
totalPages,
setEnableInfiniteScroll,
reset,
t,
],
);