Merge pull request #352 from plebbit/development

Development
This commit is contained in:
Tom (plebeius.eth)
2024-05-04 18:04:07 +02:00
committed by GitHub
56 changed files with 458 additions and 194 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
"dependencies": {
"@capacitor/app": "1.1.1",
"@floating-ui/react": "0.26.1",
"@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#6d0d38ad52ce77715cb05be6cec55d691f5f013d",
"@plebbit/plebbit-react-hooks": "https://github.com/plebbit/plebbit-react-hooks.git#ebad94cad75020c6eef2516fffc87f5a7b7181ff",
"@testing-library/jest-dom": "5.14.1",
"@testing-library/react": "13.0.0",
"@testing-library/user-event": "13.2.1",
+1
View File
@@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="referrer" content="no-referrer" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<meta name="theme-color" content="#000000" />
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} ردود و{{linksCount}} روابط محذوفة. <1>اضغط هنا</1> لعرضها.",
"thread_closed_alert": "الموضوع مغلق",
"reply_to_cid": "الرد على {{cid}}",
"submit": "إرسال"
"submit": "إرسال",
"gif": "جي آي إف"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}}টি উত্তর এবং {{linksCount}}টি লিঙ্ক বাদ দেওয়া হয়েছে। <1>দেখতে এখানে ক্লিক করুন</1>।",
"thread_closed_alert": "থ্রেডটি বন্ধ করা হয়েছে",
"reply_to_cid": "{{cid}}-এ উত্তর দিন",
"submit": "জমা দিন"
"submit": "জমা দিন",
"gif": "জিআইএফ"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} odpovědí a {{linksCount}} odkazů vynecháno. <1>Klikněte zde</1> pro zobrazení.",
"thread_closed_alert": "Vlákno je uzavřeno",
"reply_to_cid": "Odpovědět na {{cid}}",
"submit": "Odeslat"
"submit": "Odeslat",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} svar og {{linksCount}} links udeladt. <1>Klik her</1> for at se dem.",
"thread_closed_alert": "Tråden er lukket",
"reply_to_cid": "Svar til {{cid}}",
"submit": "Indsend"
"submit": "Indsend",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} Antworten und {{linksCount}} Links ausgelassen. <1>Klicken Sie hier</1>, um sie anzuzeigen.",
"thread_closed_alert": "Der Thread ist geschlossen",
"reply_to_cid": "Antwort an {{cid}}",
"submit": "Einreichen"
"submit": "Einreichen",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} απαντήσεις και {{linksCount}} σύνδεσμοι παραλείφθηκαν. <1>Κάντε κλικ εδώ</1> για να τις δείτε.",
"thread_closed_alert": "Το νήμα έχει κλείσει",
"reply_to_cid": "Απάντηση σε {{cid}}",
"submit": "Υποβολή"
"submit": "Υποβολή",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} replies and {{linksCount}} links omitted. <1>Click here</1> to view.",
"thread_closed_alert": "This thread is closed",
"reply_to_cid": "Reply to {{cid}}",
"submit": "Submit"
"submit": "Submit",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} respuestas y {{linksCount}} enlaces omitidos. <1>Haz clic aquí</1> para verlos.",
"thread_closed_alert": "El hilo está cerrado",
"reply_to_cid": "Responder a {{cid}}",
"submit": "Enviar"
"submit": "Enviar",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} پاسخ و {{linksCount}} لینک حذف شده است. <1>اینجا کلیک کنید</1> تا آنها را مشاهده کنید.",
"thread_closed_alert": "موضوع بسته شده است",
"reply_to_cid": "پاسخ به {{cid}}",
"submit": "ارسال"
"submit": "ارسال",
"gif": "گیف"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} vastausta ja {{linksCount}} linkkiä jätetty pois. <1>Napsauta tästä</1> nähdäksesi ne.",
"thread_closed_alert": "Ketju on suljettu",
"reply_to_cid": "Vastaa {{cid}}",
"submit": "Lähetä"
"submit": "Lähetä",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} mga tugon at {{linksCount}} mga link ang hindi ipinakita. <1>I-click dito</1> upang makita.",
"thread_closed_alert": "Sarado na ang thread",
"reply_to_cid": "Tumugon sa {{cid}}",
"submit": "Isumite"
"submit": "Isumite",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} réponses et {{linksCount}} liens omis. <1>Cliquez ici</1> pour les afficher.",
"thread_closed_alert": "Le fil est fermé",
"reply_to_cid": "Répondre à {{cid}}",
"submit": "Soumettre"
"submit": "Soumettre",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} תגובות ו{{linksCount}} קישורים נשמטו. <1>לחץ כאן</1> לצפייה.",
"thread_closed_alert": "האשכול סגור",
"reply_to_cid": "תגובה ל{{cid}}",
"submit": "שלח"
"submit": "שלח",
"gif": "גיף"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} उत्तर और {{linksCount}} लिंक छोड़े गए हैं। <1>देखने के लिए यहां क्लिक करें</1>।",
"thread_closed_alert": "यह थ्रेड बंद है",
"reply_to_cid": "{{cid}} का उत्तर दें",
"submit": "जमा करें"
"submit": "जमा करें",
"gif": "जीआईएफ"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} válasz és {{linksCount}} link kihagyva. <1>Kattintson ide</1> a megtekintéshez.",
"thread_closed_alert": "A téma lezárva",
"reply_to_cid": "Válasz erre: {{cid}}",
"submit": "Beküldés"
"submit": "Beküldés",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} balasan dan {{linksCount}} tautan dihilangkan. <1>Klik di sini</1> untuk melihat.",
"thread_closed_alert": "Thread ini ditutup",
"reply_to_cid": "Balas ke {{cid}}",
"submit": "Kirim"
"submit": "Kirim",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} risposte e {{linksCount}} link omessi. <1>Clicca qui</1> per visualizzare.",
"thread_closed_alert": "Questo thread è chiuso",
"reply_to_cid": "Rispondi a {{cid}}",
"submit": "Invia"
"submit": "Invia",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}}件の返信と{{linksCount}}件のリンクが省略されました。 <1>ここをクリック</1>して表示。",
"thread_closed_alert": "このスレッドは閉じられています",
"reply_to_cid": "{{cid}}に返信",
"submit": "送信"
"submit": "送信",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}}개의 답글과 {{linksCount}}개의 링크가 생략되었습니다. <1>여기를 클릭하십시오</1> 보려면.",
"thread_closed_alert": "이 스레드는 닫혔습니다",
"reply_to_cid": "{{cid}}에 답변",
"submit": "제출"
"submit": "제출",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} प्रतिसाद आणि {{linksCount}} दुवे वगळले गेले आहेत. <1>पाहण्यासाठी येथे क्लिक करा</1>.",
"thread_closed_alert": "हा थ्रेड बंद आहे",
"reply_to_cid": "{{cid}} ला उत्तर द्या",
"submit": "सबमिट करा"
"submit": "सबमिट करा",
"gif": "जीआईएफ"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} reacties en {{linksCount}} links weggelaten. <1>Klik hier</1> om ze te bekijken.",
"thread_closed_alert": "De thread is gesloten",
"reply_to_cid": "Reageren op {{cid}}",
"submit": "Verzenden"
"submit": "Verzenden",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} svar og {{linksCount}} lenker utelatt. <1>Klikk her</1> for å se dem.",
"thread_closed_alert": "Tråden er stengt",
"reply_to_cid": "Svar til {{cid}}",
"submit": "Send inn"
"submit": "Send inn",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "Pominięto {{repliesCount}} odpowiedzi i {{linksCount}} linków. <1>Kliknij tutaj</1>, aby je zobaczyć.",
"thread_closed_alert": "Wątek jest zamknięty",
"reply_to_cid": "Odpowiedz na {{cid}}",
"submit": "Zatwierdź"
"submit": "Zatwierdź",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} respostas e {{linksCount}} links omitidos. <1>Clique aqui</1> para visualizar.",
"thread_closed_alert": "O tópico está fechado",
"reply_to_cid": "Responder a {{cid}}",
"submit": "Enviar"
"submit": "Enviar",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} răspunsuri și {{linksCount}} linkuri omise. <1>Click aici</1> pentru a le vizualiza.",
"thread_closed_alert": "Acest fir de discuție este închis",
"reply_to_cid": "Răspundeți la {{cid}}",
"submit": "Trimite"
"submit": "Trimite",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} ответов и {{linksCount}} ссылок пропущено. <1>Нажмите здесь</1>, чтобы посмотреть.",
"thread_closed_alert": "Тема закрыта",
"reply_to_cid": "Ответить на {{cid}}",
"submit": "Отправить"
"submit": "Отправить",
"gif": "ГИФ"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} përgjigje dhe {{linksCount}} lidhje janë lënë jashtë. <1>Kliko këtu</1> për t'i shikuar.",
"thread_closed_alert": "Temë është mbyllur",
"reply_to_cid": "Përgjigju në {{cid}}",
"submit": "Dorëzo"
"submit": "Dorëzo",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} svar och {{linksCount}} länkar utelämnade. <1>Klicka här</1> för att visa dem.",
"thread_closed_alert": "Tråden är stängd",
"reply_to_cid": "Svara på {{cid}}",
"submit": "Skicka in"
"submit": "Skicka in",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} స్పందనలు మరియు {{linksCount}} లింకులు వదిలివేయబడ్డాయి. <1>చూడటానికి ఇక్కడ క్లిక్ చేయండి</1>.",
"thread_closed_alert": "ఈ థ్రెడ్ మూసివేయబడింది",
"reply_to_cid": "{{cid}}కి స్పందించండి",
"submit": "సమర్పించు"
"submit": "సమర్పించు",
"gif": "జీఐఎఫ్"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "ข้าม {{repliesCount}} คำตอบและ {{linksCount}} ลิงก์ <1>คลิกที่นี่</1> เพื่อดู.",
"thread_closed_alert": "กระทู้นี้ถูกปิด",
"reply_to_cid": "ตอบกลับ {{cid}}",
"submit": "ส่ง"
"submit": "ส่ง",
"gif": "จีไอเอฟ"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} yanıt ve {{linksCount}} bağlantı göz ardı edildi. <1>Buraya tıklayın</1> görüntülemek için.",
"thread_closed_alert": "Bu konu kapatılmıştır",
"reply_to_cid": "{{cid}}ye yanıt ver",
"submit": "Gönder"
"submit": "Gönder",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} відповідей та {{linksCount}} посилань пропущено. <1>Натисніть тут</1>, щоб переглянути.",
"thread_closed_alert": "Тему закрито",
"reply_to_cid": "Відповісти на {{cid}}",
"submit": "Надіслати"
"submit": "Надіслати",
"gif": "ГІФ"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} جوابات اور {{linksCount}} لنکس چھوڑ دیے گئے ہیں۔ <1>مکمل دیکھنے کے لیے یہاں کلک کریں</1>۔",
"thread_closed_alert": "یہ دھاگہ بند ہے",
"reply_to_cid": "{{cid}} کا جواب دیں",
"submit": "جمع کرائیں"
"submit": "جمع کرائیں",
"gif": "جی آئی ایف"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "{{repliesCount}} câu trả lời và {{linksCount}} liên kết bị bỏ qua. <1>Nhấn vào đây</1> để xem.",
"thread_closed_alert": "Chủ đề này đã đóng",
"reply_to_cid": "Trả lời {{cid}}",
"submit": "Gửi"
"submit": "Gửi",
"gif": "GIF"
}
+2 -1
View File
@@ -61,5 +61,6 @@
"replies_and_links_omitted": "省略了{{repliesCount}}条回复和{{linksCount}}个链接。 <1>点击这里</1>查看。",
"thread_closed_alert": "该主题已关闭",
"reply_to_cid": "回复{{cid}}",
"submit": "提交"
"submit": "提交",
"gif": "GIF"
}
-8
View File
@@ -1,13 +1,5 @@
.app {
background: var(--body-background-base-color) var(--body-background-pattern-image) top center repeat-x;
font-size: var(--body-font-size);
font-family: var(--body-font-family);
color: var(--body-font-color);
z-index: 1;
min-height: 100%;
overflow-y: hidden;
overflow-x: hidden;
min-height: 100vh;
}
@media (min-width: 640px) {
+5 -5
View File
@@ -39,13 +39,13 @@ const BoardLayout = () => {
const App = () => {
const location = useLocation();
const isInHomeView = isHomeView(location.pathname);
// add theme className to body so it can set the correct body background in index.css
const [theme] = useTheme();
useEffect(() => {
document.body.classList.forEach((className) => document.body.classList.remove(className));
document.body.classList.add(theme);
}, [theme]);
const classToAdd = isInHomeView ? 'yotsuba' : theme;
document.body.classList.add(classToAdd);
}, [theme, isInHomeView]);
const globalLayout = (
<>
@@ -55,7 +55,7 @@ const App = () => {
);
return (
<div className={`${styles.app} ${isInHomeView ? 'yotsuba' : theme}`}>
<div className={styles.app}>
<Routes>
<Route element={globalLayout}>
<Route path='/' element={<Home />} />
+18 -14
View File
@@ -3,14 +3,14 @@ import { Link, useLocation, useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { isCatalogView } from '../../lib/utils/view-utils';
import styles from './board-nav.module.css';
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
import useDefaultSubplebbits, { MultisubSubplebbit } from '../../hooks/use-default-subplebbits';
interface BoardNavProps {
subplebbitAddresses: string[];
defaultSubplebbits: MultisubSubplebbit[];
subplebbitAddress?: string;
}
const BoardNavDesktop = ({ subplebbitAddresses }: BoardNavProps) => {
const BoardNavDesktop = ({ defaultSubplebbits }: BoardNavProps) => {
const { t } = useTranslation();
const isInCatalogView = isCatalogView(useLocation().pathname, useParams());
@@ -18,12 +18,14 @@ const BoardNavDesktop = ({ subplebbitAddresses }: BoardNavProps) => {
<div className={styles.boardNavDesktop}>
<span className={styles.boardList}>
[
{subplebbitAddresses.map((address: string, index: number) => {
{defaultSubplebbits.map((subplebbit, index: number) => {
const { address, title } = subplebbit || {};
const displayAddress = address.includes('.') ? address : address.slice(0, 10).concat('...');
return (
<span key={index}>
{index === 0 ? null : ' '}
<Link to={`/p/${address}${isInCatalogView ? '/catalog' : ''}`}>{address.includes('.') ? address : address.slice(0, 10).concat('...')}</Link>
{index !== subplebbitAddresses.length - 1 ? ' /' : null}
<Link to={`/p/${address}${isInCatalogView ? '/catalog' : ''}`}>{title || displayAddress}</Link>
{index !== defaultSubplebbits.length - 1 ? ' /' : null}
</span>
);
})}
@@ -36,12 +38,13 @@ const BoardNavDesktop = ({ subplebbitAddresses }: BoardNavProps) => {
);
};
const BoardNavMobile = ({ subplebbitAddresses, subplebbitAddress }: BoardNavProps) => {
const BoardNavMobile = ({ defaultSubplebbits, subplebbitAddress }: BoardNavProps) => {
const { t } = useTranslation();
const navigate = useNavigate();
const displaySubplebbitAddress = subplebbitAddress && subplebbitAddress.length > 30 ? subplebbitAddress.slice(0, 30).concat('...') : subplebbitAddress;
const currentSubplebbitIsInList = subplebbitAddresses.some((address: string) => address === subplebbitAddress);
const subplebbitAddresses = new Set(defaultSubplebbits.map((sub) => sub.address.toLowerCase()));
const currentSubplebbitIsInList = subplebbitAddress && subplebbitAddresses.has(subplebbitAddress.toLowerCase());
const isInCatalogView = isCatalogView(useLocation().pathname, useParams());
@@ -50,11 +53,12 @@ const BoardNavMobile = ({ subplebbitAddresses, subplebbitAddress }: BoardNavProp
{!currentSubplebbitIsInList && subplebbitAddress && <option value={subplebbitAddress}>{displaySubplebbitAddress}</option>}
<option value='all'>{t('all')}</option>
<option value='subscriptions'>{t('subscriptions')}</option>
{subplebbitAddresses.map((address: any, index: number) => {
const subplebbitAddress = address?.includes('.') ? address : address?.slice(0, 10).concat('...');
{defaultSubplebbits.map((subplebbit, index) => {
const { address, title } = subplebbit || {};
const displayAddress = address.includes('.') ? address : address.slice(0, 10).concat('...');
return (
<option key={index} value={address}>
{subplebbitAddress}
{title || displayAddress}
</option>
);
})}
@@ -122,7 +126,7 @@ if (!window.STICKY_MENU_SCROLL_LISTENER) {
}
const BoardNav = () => {
const subplebbitAddresses = useDefaultSubplebbitAddresses();
const defaultSubplebbits = useDefaultSubplebbits();
const params = useParams();
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
@@ -130,8 +134,8 @@ const BoardNav = () => {
return (
<>
<BoardNavDesktop subplebbitAddresses={subplebbitAddresses} />
<BoardNavMobile subplebbitAddresses={subplebbitAddresses} subplebbitAddress={subplebbitAddress} />
<BoardNavDesktop defaultSubplebbits={defaultSubplebbits} />
<BoardNavMobile defaultSubplebbits={defaultSubplebbits} subplebbitAddress={subplebbitAddress} />
</>
);
};
+2 -2
View File
@@ -7,7 +7,7 @@ import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame';
import useCountLinksInReplies from '../../hooks/use-count-links-in-replies';
import styles from './catalog-row.module.css';
const CatalogPostMedia = ({ commentMediaInfo, link }: { commentMediaInfo: any; link: string }) => {
export const CatalogPostMedia = ({ commentMediaInfo }: { commentMediaInfo: any }) => {
const { patternThumbnailUrl, thumbnail, type, url } = commentMediaInfo || {};
const iframeThumbnail = patternThumbnailUrl || thumbnail;
const gifFrameUrl = useFetchGifFirstFrame(type === 'gif' ? url : undefined);
@@ -91,7 +91,7 @@ const CatalogPost = ({ openMenu, post, toggleMenu }: CatalogPostProps) => {
<div className={styles.mediaPaddingWrapper}>
{threadIcons}
<div className={styles.mediaWrapper} style={thumbnailDimensions}>
<CatalogPostMedia commentMediaInfo={commentMediaInfo} link={link} />
<CatalogPostMedia commentMediaInfo={commentMediaInfo} />
</div>
</div>
</Link>
+1 -1
View File
@@ -1 +1 @@
export { default } from './catalog-row';
export { default, CatalogPostMedia } from './catalog-row';
+2 -2
View File
@@ -77,7 +77,7 @@ const PostDesktop = ({ openReplyModal, post, roles, showAllReplies }: PostProps)
<a href={url} target='_blank' rel='noopener noreferrer'>
{url.length > 30 ? url.slice(0, 30) + '...' : url}
</a>{' '}
({type && getDisplayMediaInfoType(type, t)})
({type && _.lowerCase(getDisplayMediaInfoType(type, t))})
{!showThumbnail && (type === 'iframe' || type === 'video' || type === 'audio') && (
<span>
{' '}
@@ -286,7 +286,7 @@ const ReplyDesktop = ({ reply, roles, openReplyModal }: PostProps) => {
<a href={link} target='_blank' rel='noopener noreferrer'>
{link.length > 30 ? link?.slice(0, 30) + '...' : link}
</a>{' '}
({type && getDisplayMediaInfoType(type, t)})
({type && _.lowerCase(getDisplayMediaInfoType(type, t))})
{!showThumbnail && (type === 'iframe' || type === 'video' || type === 'audio') && (
<span>
{' '}
+4 -4
View File
@@ -13,9 +13,10 @@ import _ from 'lodash';
interface ReplyModalProps {
closeModal: () => void;
parentCid: string;
scrollY: number;
}
const ReplyModal = ({ closeModal, parentCid }: ReplyModalProps) => {
const ReplyModal = ({ closeModal, parentCid, scrollY }: ReplyModalProps) => {
const { t } = useTranslation();
const { subplebbitAddress } = useParams() as { subplebbitAddress: string };
const { setContent, resetContent, replyIndex, publishReply } = useReply({ cid: parentCid, subplebbitAddress });
@@ -56,12 +57,11 @@ const ReplyModal = ({ closeModal, parentCid }: ReplyModalProps) => {
useEffect(() => {
if (nodeRef.current && isMobile) {
const viewportHeight = window.innerHeight;
const scrollY = window.scrollY;
const modalHeight = 150;
const centeredPosition = scrollY + viewportHeight / 2 - modalHeight / 2;
nodeRef.current.style.top = `${centeredPosition}px`;
}
}, [isMobile]);
}, [isMobile, scrollY]);
const modalContent = (
<div className={styles.container} ref={nodeRef}>
@@ -96,7 +96,7 @@ const ReplyModal = ({ closeModal, parentCid }: ReplyModalProps) => {
ref={textRef}
placeholder={_.capitalize(t('comment'))}
onChange={(e) => setContent.content(e.target.value)}
autoFocus
autoFocus={!isMobile} // autofocus causes auto scroll to top on mobile
/>
</div>
<div className={styles.footer}>
@@ -19,7 +19,7 @@ const SubplebbitDescription = ({ avatarUrl, createdAt, description, shortAddress
author: { displayName: '## Board Mods' },
content: description,
link: avatarUrl,
title: t('welcome_to_board', { board: title || `p/${shortAddress}` }),
title: t('welcome_to_board', { board: title || `p/${shortAddress}`, interpolation: { escapeValue: false } }),
pinned: true,
locked: true,
};
+4 -4
View File
@@ -1,16 +1,16 @@
import { useEffect, useMemo, useState } from 'react';
interface Subplebbit {
export interface MultisubSubplebbit {
title?: string;
address: string;
tags?: string[];
features?: string[];
}
let cache: Subplebbit[] | null = null;
let cache: MultisubSubplebbit[] | null = null;
const useDefaultSubplebbits = () => {
const [subplebbits, setSubplebbits] = useState<Subplebbit[]>([]);
const [subplebbits, setSubplebbits] = useState<MultisubSubplebbit[]>([]);
useEffect(() => {
if (cache) {
@@ -35,7 +35,7 @@ const useDefaultSubplebbits = () => {
export const useDefaultSubplebbitAddresses = () => {
const defaultSubplebbits = useDefaultSubplebbits();
return useMemo(() => defaultSubplebbits.map((subplebbit: Subplebbit) => subplebbit.address), [defaultSubplebbits]);
return useMemo(() => defaultSubplebbits.map((subplebbit: MultisubSubplebbit) => subplebbit.address), [defaultSubplebbits]);
};
export default useDefaultSubplebbits;
+4 -4
View File
@@ -6,15 +6,15 @@ const useRepliesAndAccountReplies = (comment: Comment) => {
// flatten all replies including nested ones from the original comment
const flattenedReplies = useMemo(() => flattenCommentsPages(comment.replies), [comment.replies]);
// gemerate a Set of CIDs from flattened replies for quick lookup
// generate a Set of CIDs from flattened replies for quick lookup
const replyCids = useMemo(() => new Set(flattenedReplies.map((reply) => reply.cid)), [flattenedReplies]);
// filter against all CIDs in flattened replies
// filter against the original comment's CID and all CIDs in flattened replies
const filter = useCallback(
(accountComment: Comment) => {
return replyCids.has(accountComment.parentCid);
return accountComment.parentCid === comment.cid || replyCids.has(accountComment.parentCid);
},
[replyCids],
[comment.cid, replyCids],
);
const { accountComments } = useAccountComments({ filter });
+11 -2
View File
@@ -1,9 +1,14 @@
import { useState, useCallback } from 'react';
import useWindowWidth from './use-window-width';
const useReplyModal = () => {
const [showReplyModal, setShowReplyModal] = useState(false);
const [activeCid, setActiveCid] = useState<string | null>(null);
// on mobile, the position is absolute instead of fixed, so we need to calculate the top position
const isMobile = useWindowWidth() < 640;
const [scrollY, setScrollY] = useState<number>(0);
const closeModal = useCallback(() => {
setActiveCid(null);
setShowReplyModal(false);
@@ -11,6 +16,10 @@ const useReplyModal = () => {
const openReplyModal = useCallback(
(cid: string) => {
if (isMobile) {
const currentScrollY = window.scrollY;
setScrollY(currentScrollY);
}
if (activeCid && activeCid !== cid) {
closeModal();
setTimeout(() => {
@@ -22,10 +31,10 @@ const useReplyModal = () => {
setShowReplyModal(true);
}
},
[activeCid, closeModal],
[activeCid, closeModal, isMobile],
);
return { showReplyModal, activeCid, openReplyModal, closeModal };
return { activeCid, closeModal, openReplyModal, scrollY, showReplyModal };
};
export default useReplyModal;
+4
View File
@@ -5,6 +5,10 @@ html, body {
body {
background-color: white;
background: var(--body-background-base-color) var(--body-background-pattern-image) top center repeat-x;
font-size: var(--body-font-size);
font-family: var(--body-font-family);
color: var(--body-font-color);
}
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, th, td, iframe, blockquote {
+2
View File
@@ -15,6 +15,8 @@ export const getDisplayMediaInfoType = (type: string, t: any) => {
switch (type) {
case 'image':
return t('image');
case 'gif':
return t('gif');
case 'iframe':
return t('iframe');
case 'video':
+6 -6
View File
@@ -22,7 +22,7 @@
--body-background-pattern-image: url("/public/assets/background-fade.png");
--body-font-color: maroon;
--body-font-family: arial, helvetica, sans-serif;
--body-font-size: 10pt;
--body-font-size: 13px;
/* catalog post */
--catalog-post-menu-btn-color: navy;
@@ -175,7 +175,7 @@
--body-background-pattern-image: url("/public/assets/background-fade-blue.png");
--body-font-color: #000;
--body-font-family: arial, helvetica, sans-serif;
--body-font-size: 10pt;
--body-font-size: 13px;
/* catalog post */
--catalog-post-menu-btn-color: navy;
@@ -306,7 +306,7 @@
--body-background-pattern-image: none;
--body-font-color: maroon;
--body-font-family: times new roman, serif;
--body-font-size: 12pt;
--body-font-size: 16px;
/* board nav */
--boardnav-font-size: 11pt;
@@ -448,7 +448,7 @@
--body-background-pattern-image: none;
--body-font-color: #000;
--body-font-family: times new roman, serif;
--body-font-size: 12pt;
--body-font-size: 16px;
/* challenge modal */
--challenge-modal-background-color: #d6daf0;
@@ -564,7 +564,7 @@
--body-background-pattern-image: none;
--body-font-color: #c5c8c6;
--body-font-family: arial, helvetica, sans-serif;
--body-font-size: 10pt;
--body-font-size: 13px;
/* homepage */
--homepage-infobox-text-color: #c5c8c6;
@@ -715,7 +715,7 @@
--body-background-pattern-image: none;
--body-font-color: #333;
--body-font-family: arial, helvetica, sans-serif;
--body-font-size: 10pt;
--body-font-size: 13px;
/* board nav */
--boardnav-font-size: 9pt;
+2 -2
View File
@@ -24,7 +24,7 @@ const Board = () => {
const subplebbit = useSubplebbit({ subplebbitAddress });
const { createdAt, description, rules, shortAddress, state, suggested, title } = subplebbit || {};
const { showReplyModal, activeCid, openReplyModal, closeModal } = useReplyModal();
const { activeCid, closeModal, openReplyModal, showReplyModal, scrollY } = useReplyModal();
const loadingStateString = useFeedStateString(subplebbitAddresses) || t('loading');
const loadingString = <div className={styles.stateString}>{state === 'failed' ? state : <LoadingEllipsis string={loadingStateString} />}</div>;
@@ -62,7 +62,7 @@ const Board = () => {
return (
<div className={styles.content}>
{showReplyModal && activeCid && <ReplyModal closeModal={closeModal} parentCid={activeCid} />}
{showReplyModal && activeCid && <ReplyModal closeModal={closeModal} parentCid={activeCid} scrollY={scrollY} />}
{feed.length > 0 && (
<>
{rules && rules.length > 0 && <SubplebbitRules subplebbitAddress={subplebbitAddress} createdAt={createdAt} rules={rules} />}
+74 -1
View File
@@ -3,7 +3,7 @@
height: 100%;
margin: auto;
text-align: left;
width: 57.69em;
width: 750px;
min-width: 750px;
}
@@ -25,6 +25,11 @@
padding-bottom: 0.5em;
}
.boardsBox {
height: 343px;
overflow: hidden;
}
.boxBar, .infoboxBar {
padding-left: 0.5em;
line-height: 2em;
@@ -167,6 +172,74 @@
text-decoration: underline;
}
.popularThreads {
font-size: 93%;
padding: 0.5em;
padding-top: 0.25em;
padding-bottom: 0;
line-height: 130%;
text-align: center;
}
.popularThreads .loading {
text-align: left !important;
}
.popularThread {
vertical-align: top;
display: inline-block;
word-wrap: break-word;
overflow: hidden;
margin-top: 5px;
padding: 5px 0 3px;
position: relative;
width: 175px;
max-height: 320px;
margin-bottom: 10px;
color: #800;
}
.popularThread .title {
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
display: block;
white-space: nowrap;
margin-bottom: 5px;
}
.popularThread .mediaContainer {
width: auto;
height: auto;
border: 1px solid #800;
display: inline-block;
overflow: hidden;
position: relative;
line-height: 0;
}
.popularThread .mediaContainer img, .popularThread .mediaContainer video {
max-width: 150px;
max-height: 150px;
}
.popularThread .threadContent {
margin-bottom: 5px;
padding: 0 2px;
white-space: pre-line;
}
.stats {
margin-top: 5px;
text-align: center;
color: #800;
}
.stats .stat {
display: inline-block;
width: 33%;
}
@media (max-width: 640px) {
.content {
min-width: 0;
+124 -13
View File
@@ -1,10 +1,13 @@
import { useRef } from 'react';
import { useEffect, useRef, useState } from 'react';
import styles from './home.module.css';
import { Link, useNavigate } from 'react-router-dom';
import { Trans, useTranslation } from 'react-i18next';
import { Subplebbit, useSubplebbits } from '@plebbit/plebbit-react-hooks';
import { Comment, Subplebbit, useSubplebbits } from '@plebbit/plebbit-react-hooks';
import packageJson from '../../../package.json';
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
import useDefaultSubplebbits, { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils';
import { CatalogPostMedia } from '../../components/catalog-row';
import LoadingEllipsis from '../../components/loading-ellipsis';
const isValidAddress = (address: string): boolean => {
if (address.includes('/') || address.includes('\\') || address.includes(' ')) {
@@ -66,11 +69,11 @@ const InfoBox = () => {
);
};
const Boards = ({ subplebbits }: { subplebbits: (Subplebbit | undefined)[] }) => {
const Boards = ({ defaultSubplebbits }: { defaultSubplebbits: any }) => {
const { t } = useTranslation();
return (
<div className={styles.box}>
<div className={`${styles.box} ${styles.boardsBox}`}>
<div className={styles.boxBar}>
<h2 className={styles.capitalize}>{t('boards')}</h2>
<span>{t('options')} </span>
@@ -79,7 +82,7 @@ const Boards = ({ subplebbits }: { subplebbits: (Subplebbit | undefined)[] }) =>
<div className={styles.column}>
<h3>Default SFW</h3>
<div className={styles.list}>
{subplebbits
{defaultSubplebbits
.filter((subplebbit: Subplebbit | undefined): subplebbit is Subplebbit => subplebbit !== undefined)
.map((subplebbit: Subplebbit) => {
const address = subplebbit.address;
@@ -105,27 +108,134 @@ const Boards = ({ subplebbits }: { subplebbits: (Subplebbit | undefined)[] }) =>
);
};
const PopularThreads = () => {
interface PopularThreadProps {
post: Comment;
boardTitle: string | undefined;
boardShortAddress: string;
}
const PopularThreadCard = ({ post, boardTitle, boardShortAddress }: PopularThreadProps) => {
const { cid, content, subplebbitAddress, title } = post || {};
const commentMediaInfo = getCommentMediaInfo(post);
return (
<div className={styles.popularThread} key={cid}>
<div className={styles.title}>{boardTitle || boardShortAddress}</div>
<div className={styles.mediaContainer}>
<Link to={`/p/${subplebbitAddress}/c/${cid}`}>
<CatalogPostMedia commentMediaInfo={commentMediaInfo} />
</Link>
</div>
<div className={styles.threadContent}>
{title && <b>{title}</b>}
{content && (content.length > 99 ? `: ${content.substring(0, 99)}...` : `: ${content}`)}
</div>
</div>
);
};
const PopularThreads = ({ subplebbits }: { subplebbits: any }) => {
const { t } = useTranslation();
const [popularPosts, setPopularPosts] = useState<any[]>([]);
useEffect(() => {
const subplebbitToPost: { [key: string]: any } = {};
const uniqueLinks: Set<string> = new Set();
subplebbits.forEach((subplebbit: any) => {
let maxTimestamp = -Infinity;
let mostRecentPost = null;
if (subplebbit?.posts?.pages?.hot?.comments) {
for (const post of Object.values(subplebbit.posts.pages.hot.comments as Comment)) {
const { deleted, link, locked, pinned, removed, replyCount, timestamp } = post;
const commentMediaInfo = getCommentMediaInfo(post);
const isMediaShowed = getHasThumbnail(commentMediaInfo, link);
if (
isMediaShowed &&
replyCount > 0 &&
!deleted &&
!removed &&
!locked &&
!pinned &&
timestamp > Date.now() / 1000 - 60 * 60 * 24 * 30 &&
timestamp > maxTimestamp &&
!uniqueLinks.has(link)
) {
maxTimestamp = post.timestamp;
mostRecentPost = post;
uniqueLinks.add(link);
}
}
if (mostRecentPost) {
subplebbitToPost[subplebbit.address] = { post: mostRecentPost, timestamp: maxTimestamp };
}
}
});
const sortedPosts = Object.values(subplebbitToPost)
.sort((a, b) => b.timestamp - a.timestamp)
.map((item) => item.post);
setPopularPosts((prevPosts) => {
const updatedPosts = [...prevPosts];
sortedPosts.forEach((post) => {
if (!updatedPosts.find((p) => p.cid === post.cid)) {
if (updatedPosts.length < 8) {
updatedPosts.push(post);
}
}
});
return updatedPosts;
});
}, [subplebbits]);
return (
<div className={styles.box}>
<div className={`${styles.boxBar} ${styles.color2ColorBar}`}>
<h2 className={styles.capitalize}>{t('popular_threads')}</h2>
<span>{t('options')} </span>
</div>
<div className={styles.boxContent}></div>
<div className={`${styles.boxContent} ${popularPosts.length === 8 ? styles.popularThreads : ''}`}>
{popularPosts.length < 8 ? (
<span className={styles.loading}>
<LoadingEllipsis string={t('loading')} />
</span>
) : (
popularPosts.map((post: any) => (
<PopularThreadCard key={post.cid} post={post} boardTitle={post.subplebbitTitle || post.subplebbitAddress} boardShortAddress={post.subplebbitAddress} />
))
)}
</div>
</div>
);
};
const Stats = () => {
const Stats = ({ subplebbitAddresses }: { subplebbitAddresses: string[] }) => {
const { t } = useTranslation();
// const { totalPosts, currentUsers, boardsTracked } = useSubplebbitStats(subplebbitAddresses);
return (
<div className={styles.box}>
<div className={`${styles.boxBar} ${styles.color2ColorBar}`}>
<h2 className={styles.capitalize}>{t('stats')}</h2>
</div>
<div className={styles.boxContent}></div>
<div className={`${styles.boxContent} ${styles.stats}`}>
{/* <div className={styles.statsInfo}>
<p>{t('stats_info')}</p>
</div> */}
<div className={styles.stat}>
<b>Total Posts:</b>{' '}
</div>
<div className={styles.stat}>
<b>Current Users:</b>{' '}
</div>
<div className={styles.stat}>
<b>Boards Tracked:</b>{' '}
</div>
</div>
</div>
);
};
@@ -219,6 +329,7 @@ const Footer = () => {
};
const Home = () => {
const defaultSubplebbits = useDefaultSubplebbits();
const subplebbitAddresses = useDefaultSubplebbitAddresses();
const { subplebbits } = useSubplebbits({ subplebbitAddresses });
@@ -231,9 +342,9 @@ const Home = () => {
</Link>
<SearchBar />
<InfoBox />
<Boards subplebbits={subplebbits} />
<PopularThreads />
<Stats />
<Boards defaultSubplebbits={defaultSubplebbits} />
<PopularThreads subplebbits={subplebbits} />
<Stats subplebbitAddresses={subplebbitAddresses} />
<Footer />
</div>
);
+2 -2
View File
@@ -22,7 +22,7 @@ const PostPage = () => {
const isInDescriptionView = isDescriptionView(location.pathname, params);
const isInRulesView = isRulesView(location.pathname, params);
const { showReplyModal, activeCid, openReplyModal, closeModal } = useReplyModal();
const { activeCid, closeModal, openReplyModal, showReplyModal, scrollY } = useReplyModal();
const post = useComment({ commentCid });
const { deleted, locked, removed } = post || {};
@@ -34,7 +34,7 @@ const PostPage = () => {
return (
<div className={styles.content}>
{showReplyModal && activeCid && <ReplyModal closeModal={closeModal} parentCid={activeCid} />}
{showReplyModal && activeCid && <ReplyModal closeModal={closeModal} parentCid={activeCid} scrollY={scrollY} />}
{isInDescriptionView ? (
<SubplebbitDescription
avatarUrl={suggested?.avatarUrl}
+120 -87
View File
@@ -189,7 +189,7 @@
dependencies:
"@babel/types" "^7.23.0"
"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5", "@babel/helper-module-imports@^7.24.1", "@babel/helper-module-imports@^7.24.3":
"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.24.1", "@babel/helper-module-imports@^7.24.3":
version "7.24.3"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz#6ac476e6d168c7c23ff3ba3cf4f7841d46ac8128"
integrity sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==
@@ -477,7 +477,7 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
"@babel/plugin-syntax-jsx@^7.22.5", "@babel/plugin-syntax-jsx@^7.23.3", "@babel/plugin-syntax-jsx@^7.24.1":
"@babel/plugin-syntax-jsx@^7.23.3", "@babel/plugin-syntax-jsx@^7.24.1":
version "7.24.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz#3f6ca04b8c841811dbc3c5c5f837934e0d626c10"
integrity sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==
@@ -1160,7 +1160,7 @@
"@babel/parser" "^7.24.0"
"@babel/types" "^7.24.0"
"@babel/traverse@^7.24.1", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.2":
"@babel/traverse@^7.24.1", "@babel/traverse@^7.7.2":
version "7.24.1"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.1.tgz#d65c36ac9dd17282175d1e4a3c49d5b7988f530c"
integrity sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==
@@ -1215,6 +1215,22 @@
ipaddr.js "^2.1.0"
punycode "^2.3.1"
"@bonfida/spl-name-service@2.4.2":
version "2.4.2"
resolved "https://registry.yarnpkg.com/@bonfida/spl-name-service/-/spl-name-service-2.4.2.tgz#a5802320781fa4c0a1be1b6d2f889746e53f7705"
integrity sha512-LfxHVIN8dxStUFJy963S1hlkDpUG/X4v5JFUGcZNNIuGpPREqd7+C2dxjNe2/gGOV/a3pyljwoTI5S+Qhmy8Eg==
dependencies:
"@bonfida/sns-records" "0.0.1"
"@noble/curves" "^1.3.0"
"@scure/base" "^1.1.5"
"@solana/buffer-layout" "^4.0.1"
"@solana/spl-token" "0.3.9"
borsh "2.0.0"
buffer "^6.0.3"
graphemesplit "^2.4.4"
ipaddr.js "^2.1.0"
punycode "^2.3.1"
"@capacitor/android@3.6.0":
version "3.6.0"
resolved "https://registry.yarnpkg.com/@capacitor/android/-/android-3.6.0.tgz#60438a0614415c7c242dda48a031cd45335e067a"
@@ -1529,28 +1545,6 @@
minimatch "^3.0.4"
plist "^3.0.4"
"@emotion/is-prop-valid@^1.1.0":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz#d4175076679c6a26faa92b03bb786f9e52612337"
integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==
dependencies:
"@emotion/memoize" "^0.8.1"
"@emotion/memoize@^0.8.1":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17"
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
"@emotion/stylis@^0.8.4":
version "0.8.5"
resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
"@emotion/unitless@^0.7.4":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
"@ensdomains/eth-ens-namehash@2.0.15":
version "2.0.15"
resolved "https://registry.yarnpkg.com/@ensdomains/eth-ens-namehash/-/eth-ens-namehash-2.0.15.tgz#5e5f2f24ba802aff8bc19edd822c9a11200cdf4a"
@@ -3409,6 +3403,69 @@
uuid "9.0.1"
viem "1.5.2"
"@plebbit/plebbit-js@https://github.com/plebbit/plebbit-js.git#3debda4034d18cf62ae46a4257a47284a8281e31":
version "0.0.3"
resolved "https://github.com/plebbit/plebbit-js.git#3debda4034d18cf62ae46a4257a47284a8281e31"
dependencies:
"@bonfida/spl-name-service" "2.4.2"
"@chainsafe/libp2p-gossipsub" "12.0.0"
"@chainsafe/libp2p-noise" "15.0.0"
"@chainsafe/libp2p-yamux" "6.0.2"
"@ensdomains/eth-ens-namehash" "2.0.15"
"@keyv/sqlite" "3.6.7"
"@libp2p/autonat" "1.0.12"
"@libp2p/bootstrap" "10.0.15"
"@libp2p/circuit-relay-v2" "^1.0.15"
"@libp2p/identify" "1.0.14"
"@libp2p/kad-dht" "12.0.7"
"@libp2p/mplex" "10.0.15"
"@libp2p/peer-id-factory" "4.0.6"
"@libp2p/webrtc" "4.0.19"
"@libp2p/webtransport" "4.0.19"
"@plebbit/plebbit-logger" "github:plebbit/plebbit-logger#355a96d7659ed820047980049dfa627d30d83a69"
"@plebbit/proper-lockfile" "github:plebbit/node-proper-lockfile#7fd6332117340c1d3d98dd0afee2d31cc06f72b8"
"@types/proper-lockfile" "4.1.2"
"@types/uuid" "8.3.4"
assert "2.1.0"
better-sqlite3 "9.3.0"
buffer "6.0.3"
captcha-canvas "3.2.1"
cbor "9.0.1"
debounce "1.2.1"
err-code "3.0.1"
ethers "6.10.0"
ext-name "5.0.0"
file-type "16.5.4"
hpagent "1.2.0"
ipfs-only-hash "4.0.0"
jose "4.11.0"
js-sha256 "0.9.0"
js-sha512 "0.9.0"
keyv "4.5.4"
knex "3.1.0"
kubo-rpc-client "3.0.3"
libp2p "1.2.1"
libp2p-crypto "0.21.2"
limiter-es6-compat "2.1.2"
localforage "1.10.0"
lodash-es "4.17.21"
lru-cache "10.1.0"
open-graph-scraper "6.3.3"
p-limit "4.0.0"
p-timeout "6.1.2"
peer-id "0.16.0"
probe-image-size "7.2.3"
retry "0.13.1"
rpc-websockets "7.10.0"
safe-stable-stringify "2.4.3"
sha1-uint8array "0.10.7"
skia-canvas "1.0.0"
tiny-typed-emitter "2.1.0"
tinycache "1.1.2"
ts-custom-error "3.3.1"
uuid "9.0.1"
viem "1.5.2"
"@plebbit/plebbit-logger@github:plebbit/plebbit-logger#355a96d7659ed820047980049dfa627d30d83a69":
version "0.0.1"
uid "355a96d7659ed820047980049dfa627d30d83a69"
@@ -3438,6 +3495,22 @@
uuid "8.3.2"
zustand "4.0.0"
"@plebbit/plebbit-react-hooks@https://github.com/plebbit/plebbit-react-hooks.git#ebad94cad75020c6eef2516fffc87f5a7b7181ff":
version "0.0.1"
resolved "https://github.com/plebbit/plebbit-react-hooks.git#ebad94cad75020c6eef2516fffc87f5a7b7181ff"
dependencies:
"@plebbit/plebbit-js" "https://github.com/plebbit/plebbit-js.git#3debda4034d18cf62ae46a4257a47284a8281e31"
"@plebbit/plebbit-logger" "https://github.com/plebbit/plebbit-logger.git"
assert "2.0.0"
ethers "5.6.9"
localforage "1.10.0"
lodash.isequal "4.5.0"
memoizee "0.4.15"
quick-lru "5.1.1"
uint8arrays "3.1.1"
uuid "8.3.2"
zustand "4.0.0"
"@plebbit/proper-lockfile@github:plebbit/node-proper-lockfile#7fd6332117340c1d3d98dd0afee2d31cc06f72b8":
version "4.1.2"
resolved "https://codeload.github.com/plebbit/node-proper-lockfile/tar.gz/7fd6332117340c1d3d98dd0afee2d31cc06f72b8"
@@ -5307,17 +5380,6 @@ babel-plugin-polyfill-regenerator@^0.6.1:
dependencies:
"@babel/helper-define-polyfill-provider" "^0.6.1"
"babel-plugin-styled-components@>= 1.12.0":
version "2.1.4"
resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz#9a1f37c7f32ef927b4b008b529feb4a2c82b1092"
integrity sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==
dependencies:
"@babel/helper-annotate-as-pure" "^7.22.5"
"@babel/helper-module-imports" "^7.22.5"
"@babel/plugin-syntax-jsx" "^7.22.5"
lodash "^4.17.21"
picomatch "^2.3.1"
babel-plugin-transform-react-remove-prop-types@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a"
@@ -5862,11 +5924,6 @@ camelcase@^6.2.0, camelcase@^6.2.1:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
camelize@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3"
integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==
caniuse-api@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0"
@@ -6710,11 +6767,6 @@ css-blank-pseudo@^3.0.3:
dependencies:
postcss-selector-parser "^6.0.9"
css-color-keywords@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==
css-declaration-sorter@^6.3.1:
version "6.4.1"
resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71"
@@ -6795,15 +6847,6 @@ css-select@^5.1.0:
domutils "^3.0.1"
nth-check "^2.0.1"
css-to-react-native@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32"
integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==
dependencies:
camelize "^1.0.0"
css-color-keywords "^1.0.0"
postcss-value-parser "^4.0.2"
css-tree@1.0.0-alpha.37:
version "1.0.0-alpha.37"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22"
@@ -9406,13 +9449,6 @@ hmac-drbg@^1.0.1:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
hoist-non-react-statics@^3.0.0:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
dependencies:
react-is "^16.7.0"
homedir-polyfill@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
@@ -11352,6 +11388,11 @@ js-sha3@0.8.0, js-sha3@^0.8.0:
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
js-sha512@0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/js-sha512/-/js-sha512-0.9.0.tgz#ed569aa1e4bdaf0b83363c29db1ab87b1192d9ae"
integrity sha512-mirki9WS/SUahm+1TbAPkqvbCiCfOAAsyXeHxK1UkullnJVVqoJG2pL9ObvT05CN+tM7fxhfYm0NbXn+1hWoZg==
js-sizeof@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/js-sizeof/-/js-sizeof-0.0.1.tgz#bf35bb93b59abe02e4f44dd8239dbf447ea62334"
@@ -14298,7 +14339,7 @@ postcss-unique-selectors@^5.1.1:
dependencies:
postcss-selector-parser "^6.0.5"
postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
@@ -14704,7 +14745,7 @@ react-dom@18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
react-draggable@^4.4.6:
react-draggable@4.4.6:
version "4.4.6"
resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.6.tgz#63343ee945770881ca1256a5b6fa5c9f5983fe1e"
integrity sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==
@@ -14725,7 +14766,7 @@ react-i18next@13.2.2:
"@babel/runtime" "^7.22.5"
html-parse-stringify "^3.0.1"
react-is@^16.13.1, react-is@^16.7.0:
react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -15286,6 +15327,19 @@ rollup@^2.43.1:
optionalDependencies:
fsevents "~2.3.2"
rpc-websockets@7.10.0:
version "7.10.0"
resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.10.0.tgz#8ffaf6aaab3eb18e603c7549988cf49feeddcd29"
integrity sha512-cemZ6RiDtYZpPiBzYijdOrkQQzmBCmug0E9SdRH2gIUNT15ql4mwCYWIp0VnSZq6Qrw/JkGUygp4PrK1y9KfwQ==
dependencies:
"@babel/runtime" "^7.17.2"
eventemitter3 "^4.0.7"
uuid "^8.3.2"
ws "^8.5.0"
optionalDependencies:
bufferutil "^4.0.1"
utf-8-validate "^5.0.2"
rpc-websockets@7.9.0, rpc-websockets@^7.5.1:
version "7.9.0"
resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.9.0.tgz#a3938e16d6f134a3999fdfac422a503731bf8973"
@@ -15614,11 +15668,6 @@ sha1-uint8array@0.10.7:
resolved "https://registry.yarnpkg.com/sha1-uint8array/-/sha1-uint8array-0.10.7.tgz#270f51f405b520806a89dcbc0d2cdb17e89082a6"
integrity sha512-COJRCUOuTgEEPyhcRncHlf3Z2/Nik0PGZ60/tA9Ni2jlwYJ2g/WgP8TV19gbllmZDs/DGV5YklZxreyMHFX8ww==
shallowequal@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
sharp@^0.29.2:
version "0.29.3"
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2"
@@ -16230,22 +16279,6 @@ style-to-object@^0.4.0:
dependencies:
inline-style-parser "0.1.1"
styled-components@^5:
version "5.3.11"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.11.tgz#9fda7bf1108e39bf3f3e612fcc18170dedcd57a8"
integrity sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/traverse" "^7.4.5"
"@emotion/is-prop-valid" "^1.1.0"
"@emotion/stylis" "^0.8.4"
"@emotion/unitless" "^0.7.4"
babel-plugin-styled-components ">= 1.12.0"
css-to-react-native "^3.0.0"
hoist-non-react-statics "^3.0.0"
shallowequal "^1.1.0"
supports-color "^5.5.0"
stylehacks@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9"
@@ -16279,7 +16312,7 @@ superstruct@^0.14.2:
resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b"
integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==
supports-color@^5.3.0, supports-color@^5.5.0:
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==