diff --git a/public/translations/ar/default.json b/public/translations/ar/default.json
index d90b8f8f..6d62118f 100644
--- a/public/translations/ar/default.json
+++ b/public/translations/ar/default.json
@@ -231,5 +231,6 @@
"pattern": "نمط",
"enable": "تفعيل",
"order": "ترتيب",
- "text": "نص"
+ "text": "نص",
+ "filtered_threads": "المواضيع المفلترة"
}
\ No newline at end of file
diff --git a/public/translations/bn/default.json b/public/translations/bn/default.json
index 1838abbb..db3b5750 100644
--- a/public/translations/bn/default.json
+++ b/public/translations/bn/default.json
@@ -231,5 +231,6 @@
"pattern": "প্যাটার্ন",
"enable": "সক্রিয় করুন",
"order": "অর্ডার",
- "text": "টেক্সট"
+ "text": "টেক্সট",
+ "filtered_threads": "ফিল্টার করা থ্রেড"
}
\ No newline at end of file
diff --git a/public/translations/cs/default.json b/public/translations/cs/default.json
index e3fff362..845cde9f 100644
--- a/public/translations/cs/default.json
+++ b/public/translations/cs/default.json
@@ -231,5 +231,6 @@
"pattern": "Vzor",
"enable": "Povolit",
"order": "Pořadí",
- "text": "Text"
+ "text": "Text",
+ "filtered_threads": "Filtr threads"
}
\ No newline at end of file
diff --git a/public/translations/da/default.json b/public/translations/da/default.json
index 52db8104..a84f4637 100644
--- a/public/translations/da/default.json
+++ b/public/translations/da/default.json
@@ -231,5 +231,6 @@
"pattern": "Mønster",
"enable": "Aktiver",
"order": "Rækkefølge",
- "text": "Tekst"
+ "text": "Tekst",
+ "filtered_threads": "Filtrerede tråde"
}
\ No newline at end of file
diff --git a/public/translations/de/default.json b/public/translations/de/default.json
index 8789fe4c..112c6fa8 100644
--- a/public/translations/de/default.json
+++ b/public/translations/de/default.json
@@ -231,5 +231,6 @@
"pattern": "Muster",
"enable": "Aktivieren",
"order": "Reihenfolge",
- "text": "Text"
+ "text": "Text",
+ "filtered_threads": "Gefilterte Threads"
}
\ No newline at end of file
diff --git a/public/translations/el/default.json b/public/translations/el/default.json
index 6bb0ec2c..311fd2be 100644
--- a/public/translations/el/default.json
+++ b/public/translations/el/default.json
@@ -231,5 +231,6 @@
"pattern": "Μοτίβο",
"enable": "Ενεργοποιήστε",
"order": "Σειρά",
- "text": "Κείμενο"
+ "text": "Κείμενο",
+ "filtered_threads": "Φιλτραρισμένα θέματα"
}
\ No newline at end of file
diff --git a/public/translations/en/default.json b/public/translations/en/default.json
index 774022eb..e75f74a3 100644
--- a/public/translations/en/default.json
+++ b/public/translations/en/default.json
@@ -231,5 +231,6 @@
"pattern": "Pattern",
"enable": "Enable",
"order": "Order",
- "text": "Text"
+ "text": "Text",
+ "filtered_threads": "Filtered threads"
}
\ No newline at end of file
diff --git a/public/translations/es/default.json b/public/translations/es/default.json
index 925c8a00..dc97a8ef 100644
--- a/public/translations/es/default.json
+++ b/public/translations/es/default.json
@@ -231,5 +231,6 @@
"pattern": "Patrón",
"enable": "Habilitar",
"order": "Orden",
- "text": "Texto"
+ "text": "Texto",
+ "filtered_threads": "Hilos filtrados"
}
\ No newline at end of file
diff --git a/public/translations/fa/default.json b/public/translations/fa/default.json
index 6f4737b1..c4985757 100644
--- a/public/translations/fa/default.json
+++ b/public/translations/fa/default.json
@@ -231,5 +231,6 @@
"pattern": "الگو",
"enable": "فعال کردن",
"order": "ترتیب",
- "text": "متن"
+ "text": "متن",
+ "filtered_threads": "رشتههای فیلتر شده"
}
\ No newline at end of file
diff --git a/public/translations/fi/default.json b/public/translations/fi/default.json
index c79041be..ed89eb7f 100644
--- a/public/translations/fi/default.json
+++ b/public/translations/fi/default.json
@@ -231,5 +231,6 @@
"pattern": "Malli",
"enable": "Ota käyttöön",
"order": "Järjestys",
- "text": "Teksti"
+ "text": "Teksti",
+ "filtered_threads": "Suodatetut ketjut"
}
\ No newline at end of file
diff --git a/public/translations/fil/default.json b/public/translations/fil/default.json
index 92d72bae..236265de 100644
--- a/public/translations/fil/default.json
+++ b/public/translations/fil/default.json
@@ -231,5 +231,6 @@
"pattern": "Pattern",
"enable": "I-enable",
"order": "Kaayusan",
- "text": "Teksto"
+ "text": "Teksto",
+ "filtered_threads": "Na-filter na mga thread"
}
\ No newline at end of file
diff --git a/public/translations/fr/default.json b/public/translations/fr/default.json
index eb1696c8..9cda61cc 100644
--- a/public/translations/fr/default.json
+++ b/public/translations/fr/default.json
@@ -231,5 +231,6 @@
"pattern": "Modèle",
"enable": "Activer",
"order": "Ordre",
- "text": "Texte"
+ "text": "Texte",
+ "filtered_threads": "Threads filtrés"
}
\ No newline at end of file
diff --git a/public/translations/he/default.json b/public/translations/he/default.json
index 8192f3af..69017065 100644
--- a/public/translations/he/default.json
+++ b/public/translations/he/default.json
@@ -231,5 +231,6 @@
"pattern": "תבנית",
"enable": "הפעל",
"order": "סדר",
- "text": "טקסט"
+ "text": "טקסט",
+ "filtered_threads": "אשכולות ממוינים"
}
\ No newline at end of file
diff --git a/public/translations/hi/default.json b/public/translations/hi/default.json
index 65126a05..f79e6d21 100644
--- a/public/translations/hi/default.json
+++ b/public/translations/hi/default.json
@@ -231,5 +231,6 @@
"pattern": "पैटर्न",
"enable": "सक्षम करें",
"order": "क्रम",
- "text": "पाठ"
+ "text": "पाठ",
+ "filtered_threads": "फ़िल्टर किए गए थ्रेड्स"
}
\ No newline at end of file
diff --git a/public/translations/hu/default.json b/public/translations/hu/default.json
index b4ba5efa..6cff3556 100644
--- a/public/translations/hu/default.json
+++ b/public/translations/hu/default.json
@@ -231,5 +231,6 @@
"pattern": "Minta",
"enable": "Engedélyez",
"order": "Rendelés",
- "text": "Szöveg"
+ "text": "Szöveg",
+ "filtered_threads": "Szűrt szálak"
}
\ No newline at end of file
diff --git a/public/translations/id/default.json b/public/translations/id/default.json
index e6ebd4d9..8ac959ec 100644
--- a/public/translations/id/default.json
+++ b/public/translations/id/default.json
@@ -231,5 +231,6 @@
"pattern": "Pola",
"enable": "Aktifkan",
"order": "Urutan",
- "text": "Teks"
+ "text": "Teks",
+ "filtered_threads": "Thread yang difilter"
}
\ No newline at end of file
diff --git a/public/translations/it/default.json b/public/translations/it/default.json
index e7002042..07424503 100644
--- a/public/translations/it/default.json
+++ b/public/translations/it/default.json
@@ -231,5 +231,6 @@
"pattern": "Modello",
"enable": "Abilita",
"order": "Ordine",
- "text": "Testo"
+ "text": "Testo",
+ "filtered_threads": "Thread filtrati"
}
\ No newline at end of file
diff --git a/public/translations/ja/default.json b/public/translations/ja/default.json
index 90594a77..f343c653 100644
--- a/public/translations/ja/default.json
+++ b/public/translations/ja/default.json
@@ -231,5 +231,6 @@
"pattern": "パターン",
"enable": "有効にする",
"order": "順序",
- "text": "テキスト"
+ "text": "テキスト",
+ "filtered_threads": "フィルタリングされたスレッド"
}
\ No newline at end of file
diff --git a/public/translations/ko/default.json b/public/translations/ko/default.json
index d26698e8..232f3c3c 100644
--- a/public/translations/ko/default.json
+++ b/public/translations/ko/default.json
@@ -231,5 +231,6 @@
"pattern": "패턴",
"enable": "사용",
"order": "순서",
- "text": "텍스트"
+ "text": "텍스트",
+ "filtered_threads": "필터링된 스레드"
}
\ No newline at end of file
diff --git a/public/translations/mr/default.json b/public/translations/mr/default.json
index 966c6a06..9c652d20 100644
--- a/public/translations/mr/default.json
+++ b/public/translations/mr/default.json
@@ -231,5 +231,6 @@
"pattern": "पॅटर्न",
"enable": "सक्षम करा",
"order": "आदेश",
- "text": "पाठ"
+ "text": "पाठ",
+ "filtered_threads": "फिल्टर केलेले ध糹रे"
}
\ No newline at end of file
diff --git a/public/translations/nl/default.json b/public/translations/nl/default.json
index b9f5337a..996ac291 100644
--- a/public/translations/nl/default.json
+++ b/public/translations/nl/default.json
@@ -231,5 +231,6 @@
"pattern": "Patroon",
"enable": "Inschakelen",
"order": "Volgorde",
- "text": "Tekst"
+ "text": "Tekst",
+ "filtered_threads": "Gefilterde threads"
}
\ No newline at end of file
diff --git a/public/translations/no/default.json b/public/translations/no/default.json
index a7974ec4..39c41233 100644
--- a/public/translations/no/default.json
+++ b/public/translations/no/default.json
@@ -231,5 +231,6 @@
"pattern": "Mønster",
"enable": "Aktiver",
"order": "Rekkefølge",
- "text": "Tekst"
+ "text": "Tekst",
+ "filtered_threads": "Filtrerte tråder"
}
\ No newline at end of file
diff --git a/public/translations/pl/default.json b/public/translations/pl/default.json
index 0c5cddc2..9dac3e8a 100644
--- a/public/translations/pl/default.json
+++ b/public/translations/pl/default.json
@@ -231,5 +231,6 @@
"pattern": "Wzór",
"enable": "Włącz",
"order": "Kolejność",
- "text": "Tekst"
+ "text": "Tekst",
+ "filtered_threads": "Filtrowane wątki"
}
\ No newline at end of file
diff --git a/public/translations/pt/default.json b/public/translations/pt/default.json
index b2f2b35d..62882f0d 100644
--- a/public/translations/pt/default.json
+++ b/public/translations/pt/default.json
@@ -231,5 +231,6 @@
"pattern": "Padrão",
"enable": "Ativar",
"order": "Ordem",
- "text": "Texto"
+ "text": "Texto",
+ "filtered_threads": "Threads filtrados"
}
\ No newline at end of file
diff --git a/public/translations/ro/default.json b/public/translations/ro/default.json
index 65037c55..d605b60f 100644
--- a/public/translations/ro/default.json
+++ b/public/translations/ro/default.json
@@ -231,5 +231,6 @@
"pattern": "Model",
"enable": "Activare",
"order": "Ordine",
- "text": "Text"
+ "text": "Text",
+ "filtered_threads": "Fire filtrate"
}
\ No newline at end of file
diff --git a/public/translations/ru/default.json b/public/translations/ru/default.json
index 34062f79..163bfceb 100644
--- a/public/translations/ru/default.json
+++ b/public/translations/ru/default.json
@@ -231,5 +231,6 @@
"pattern": "Шаблон",
"enable": "Включить",
"order": "Порядок",
- "text": "Текст"
+ "text": "Текст",
+ "filtered_threads": "Отфильтрованные темы"
}
\ No newline at end of file
diff --git a/public/translations/sq/default.json b/public/translations/sq/default.json
index fa3beff2..178fd403 100644
--- a/public/translations/sq/default.json
+++ b/public/translations/sq/default.json
@@ -231,5 +231,6 @@
"pattern": "Model",
"enable": "Aktivizo",
"order": "Rendit",
- "text": "Tekst"
+ "text": "Tekst",
+ "filtered_threads": "Tema të filtruar"
}
\ No newline at end of file
diff --git a/public/translations/sv/default.json b/public/translations/sv/default.json
index 4aaaa577..dddabc73 100644
--- a/public/translations/sv/default.json
+++ b/public/translations/sv/default.json
@@ -231,5 +231,6 @@
"pattern": "Mönster",
"enable": "Aktivera",
"order": "Ordning",
- "text": "Text"
+ "text": "Text",
+ "filtered_threads": "Filtrerade trådar"
}
\ No newline at end of file
diff --git a/public/translations/te/default.json b/public/translations/te/default.json
index 1578d263..0ec40ee5 100644
--- a/public/translations/te/default.json
+++ b/public/translations/te/default.json
@@ -231,5 +231,6 @@
"pattern": "ప్యాటర్న్",
"enable": "చేర్చు",
"order": "ఆర్డర్",
- "text": "పాఠం"
+ "text": "పాఠం",
+ "filtered_threads": "ఫిల్టర్ చేయబడిన థ్రెడ్లు"
}
\ No newline at end of file
diff --git a/public/translations/th/default.json b/public/translations/th/default.json
index 233c6408..bd6871a2 100644
--- a/public/translations/th/default.json
+++ b/public/translations/th/default.json
@@ -231,5 +231,6 @@
"pattern": "รูปแบบ",
"enable": "เปิดใช้งาน",
"order": "ลำดับ",
- "text": "ข้อความ"
+ "text": "ข้อความ",
+ "filtered_threads": "กระทู้ที่กรองแล้ว"
}
\ No newline at end of file
diff --git a/public/translations/tr/default.json b/public/translations/tr/default.json
index 3a1939be..9cd9cf29 100644
--- a/public/translations/tr/default.json
+++ b/public/translations/tr/default.json
@@ -231,5 +231,6 @@
"pattern": "Desen",
"enable": "Etkinleştir",
"order": "Sıra",
- "text": "Metin"
+ "text": "Metin",
+ "filtered_threads": "Filtrelenmiş başlıklar"
}
\ No newline at end of file
diff --git a/public/translations/uk/default.json b/public/translations/uk/default.json
index 2cf13783..88fbe0c6 100644
--- a/public/translations/uk/default.json
+++ b/public/translations/uk/default.json
@@ -231,5 +231,6 @@
"pattern": "Шаблон",
"enable": "Увімкнути",
"order": "Порядок",
- "text": "Текст"
+ "text": "Текст",
+ "filtered_threads": "Відфільтровані треди"
}
\ No newline at end of file
diff --git a/public/translations/ur/default.json b/public/translations/ur/default.json
index 162a3311..1aba0d29 100644
--- a/public/translations/ur/default.json
+++ b/public/translations/ur/default.json
@@ -231,5 +231,6 @@
"pattern": "نمونہ",
"enable": "فعال کریں",
"order": "ترتیب",
- "text": "متن"
+ "text": "متن",
+ "filtered_threads": "فلٹر کیے گئے تھریڈز"
}
\ No newline at end of file
diff --git a/public/translations/vi/default.json b/public/translations/vi/default.json
index eba3ff84..2a06a18f 100644
--- a/public/translations/vi/default.json
+++ b/public/translations/vi/default.json
@@ -231,5 +231,6 @@
"pattern": "Mẫu",
"enable": "Kích hoạt",
"order": "Thứ tự",
- "text": "Văn bản"
+ "text": "Văn bản",
+ "filtered_threads": "Các chủ đề đã lọc"
}
\ No newline at end of file
diff --git a/public/translations/zh/default.json b/public/translations/zh/default.json
index 660b8320..8532e16d 100644
--- a/public/translations/zh/default.json
+++ b/public/translations/zh/default.json
@@ -231,5 +231,6 @@
"pattern": "模式",
"enable": "启用",
"order": "顺序",
- "text": "文本"
+ "text": "文本",
+ "filtered_threads": "已过滤的帖子"
}
\ No newline at end of file
diff --git a/src/app.tsx b/src/app.tsx
index ce795174..0e8eb1ff 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -46,8 +46,8 @@ const BoardLayout = () => {
{isMobile
? (subplebbitAddress || isInAllView || isInSubscriptionsView || pendingPost?.subplebbitAddress) && (
<>
-
+
>
)
: (subplebbitAddress || isInAllView || isInSubscriptionsView || pendingPost?.subplebbitAddress) && (
diff --git a/src/components/board-buttons/board-buttons.module.css b/src/components/board-buttons/board-buttons.module.css
index 08e92ef9..00c1e533 100644
--- a/src/components/board-buttons/board-buttons.module.css
+++ b/src/components/board-buttons/board-buttons.module.css
@@ -11,6 +11,32 @@
margin: 5px 2px;
}
+.mobileBoardButtons .secondRow {
+ margin-top: -5px;
+ padding-bottom: 20px;
+}
+
+.mobileBoardButtons {
+ margin-top: -3px;
+}
+
+.mobileBoardButtons .autoCheckbox {
+ margin: 0 3px 0 0;
+ position: relative;
+ top: -2px;
+ border-radius: 0;
+ height: 10px;
+ width: 10px;
+}
+
+.disabledButton {
+ opacity: 0.5 !important;
+}
+
+.disabledButton:hover {
+ cursor: not-allowed !important;
+}
+
.mobileBoardButtons a, .desktopBoardButtons a {
all: unset;
}
@@ -53,6 +79,20 @@
padding-top: 15px;
}
+.filteredThreadsCount {
+ text-transform: none !important;
+}
+
+.mobileBoardButtons {
+ text-transform: capitalize;
+}
+
+.mobileBoardButtons .filteredThreadsCount {
+ display: block;
+ margin-top: 3px;
+ margin-bottom: 15px;
+}
+
@media (max-width: 640px) {
.desktopBoardButtons {
display: none;
diff --git a/src/components/board-buttons/board-buttons.tsx b/src/components/board-buttons/board-buttons.tsx
index 190710cf..b95cae18 100644
--- a/src/components/board-buttons/board-buttons.tsx
+++ b/src/components/board-buttons/board-buttons.tsx
@@ -11,6 +11,9 @@ import styles from './board-buttons.module.css';
import Tooltip from '../tooltip';
import useCountLinksInReplies from '../../hooks/use-count-links-in-replies';
import _ from 'lodash';
+import useIsMobile from '../../hooks/use-is-mobile';
+import useCatalogFiltersStore from '../../stores/use-catalog-filters-store';
+import { useEffect } from 'react';
interface BoardButtonsProps {
address?: string | undefined;
@@ -85,6 +88,49 @@ const RefreshButton = () => {
);
};
+const UpdateButton = () => {
+ const { t } = useTranslation();
+ const isMobile = useIsMobile();
+
+ return (
+ <>
+ {/* TODO: Implement update button once available in API */}
+ {isMobile ? (
+
+ ) : (
+
+ )}
+ >
+ );
+};
+
+const AutoButton = () => {
+ const { t } = useTranslation();
+ const isMobile = useIsMobile();
+
+ return (
+ <>
+ {isMobile ? (
+
+ ) : (
+
+ )}
+ >
+ );
+};
+
const SortOptions = () => {
const { t } = useTranslation();
const { sortType, setSortType } = useSortingStore();
@@ -176,6 +222,7 @@ export const TimeFilter = ({ isInAllView, isInCatalogView, isInSubscriptionsView
};
export const MobileBoardButtons = () => {
+ const { t } = useTranslation();
const params = useParams();
const location = useLocation();
const isInAllView = isAllView(location.pathname, params);
@@ -187,6 +234,14 @@ export const MobileBoardButtons = () => {
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress;
+ const { filteredCount, resetFilteredCount } = useCatalogFiltersStore();
+
+ useEffect(() => {
+ if (subplebbitAddress) {
+ resetFilteredCount();
+ }
+ }, [subplebbitAddress, resetFilteredCount]);
+
return (
{isInPostView || isInPendingPostPage ? (
@@ -194,6 +249,10 @@ export const MobileBoardButtons = () => {
+
>
) : (
<>
@@ -204,6 +263,12 @@ export const MobileBoardButtons = () => {
)}
{!(isInAllView || isInSubscriptionsView) &&
}
+ {isInCatalogView && filteredCount > 0 && (
+
+ {' '}
+ — {t('filtered_threads')}: {filteredCount}
+
+ )}
{isInCatalogView && (
<>
@@ -247,6 +312,7 @@ const PostPageStats = () => {
};
export const DesktopBoardButtons = () => {
+ const { t } = useTranslation();
const params = useParams();
const location = useLocation();
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
@@ -257,6 +323,14 @@ export const DesktopBoardButtons = () => {
const isInPostView = isPostPageView(location.pathname, params);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams());
+ const { filteredCount, resetFilteredCount } = useCatalogFiltersStore();
+
+ useEffect(() => {
+ if (subplebbitAddress) {
+ resetFilteredCount();
+ }
+ }, [subplebbitAddress, resetFilteredCount]);
+
return (
<>
@@ -266,7 +340,10 @@ export const DesktopBoardButtons = () => {
[
] [
-
]
+
] [
+
+ ] [
+
]
@@ -285,6 +362,12 @@ export const DesktopBoardButtons = () => {
>
)}
[
]
+ {isInCatalogView && filteredCount > 0 && (
+
+ {' '}
+ — {t('filtered_threads')}: {filteredCount}
+
+ )}
{isInCatalogView && (
<>
diff --git a/src/components/comment-media/comment-media.module.css b/src/components/comment-media/comment-media.module.css
index abca8390..67287ce1 100644
--- a/src/components/comment-media/comment-media.module.css
+++ b/src/components/comment-media/comment-media.module.css
@@ -80,6 +80,7 @@
.content img, .content video, .content iframe, .content audio {
max-width: 100%;
max-height: 100%;
+ object-fit: contain;
}
.content img {
@@ -128,8 +129,15 @@
padding: 3px 20px 5px 20px;
}
+.mediaDesktopOp {
+ max-width: calc(100% - 40px);
+ box-sizing: border-box;
+}
+
.mediaDesktopOp img, .mediaDesktopOp video, .mediaDesktopOp iframe, .mediaDesktopOp audio {
- padding: 3px 20px 5px 0;
+ padding: 3px 20px 5px 20px;
+ max-width: 100%;
+ box-sizing: border-box;
}
.fileDeleted {
diff --git a/src/components/comment-media/comment-media.tsx b/src/components/comment-media/comment-media.tsx
index ebdaf4ec..96464484 100644
--- a/src/components/comment-media/comment-media.tsx
+++ b/src/components/comment-media/comment-media.tsx
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Comment } from '@plebbit/plebbit-react-hooks';
import styles from './comment-media.module.css';
-import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail } from '../../lib/utils/media-utils';
+import { CommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils';
import { getHostname } from '../../lib/utils/url-utils';
import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame';
import useIsMobile from '../../hooks/use-is-mobile';
@@ -109,6 +109,7 @@ const Media = ({ commentMediaInfo, isReply, setShowThumbnail }: MediaProps) => {
const { thumbnail, type, url } = commentMediaInfo || {};
const isMobile = useIsMobile();
const mediaClass = isMobile ? styles.mediaMobile : isReply ? styles.mediaDesktopReply : styles.mediaDesktopOp;
+ const mediaDimensions = getMediaDimensions(commentMediaInfo);
return (
@@ -128,7 +129,8 @@ const Media = ({ commentMediaInfo, isReply, setShowThumbnail }: MediaProps) => {
{url && url.length > 30 ? url.slice(0, 30) + '...' : url}
{' '}
- ({getDisplayMediaInfoType(type, t)})
+ ({getDisplayMediaInfoType(type, t)}
+ {mediaDimensions && `, ${mediaDimensions}`})
)}
{isMobile && (type === 'iframe' || type === 'video' || type === 'audio') && (
diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx
index 7b5ed3c9..11e521fe 100644
--- a/src/components/post-desktop/post-desktop.tsx
+++ b/src/components/post-desktop/post-desktop.tsx
@@ -4,7 +4,7 @@ import { Link, useLocation, useParams } from 'react-router-dom';
import { Comment, useAccount, useAuthorAvatar, useComment, useEditedComment } from '@plebbit/plebbit-react-hooks';
import Plebbit from '@plebbit/plebbit-js/dist/browser/index.js';
import styles from '../../views/post/post.module.css';
-import { getCommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail } from '../../lib/utils/media-utils';
+import { getCommentMediaInfo, getDisplayMediaInfoType, getHasThumbnail, getMediaDimensions } from '../../lib/utils/media-utils';
import { hashStringToColor, getTextColorForBackground } from '../../lib/utils/post-utils';
import { getFormattedDate, getFormattedTimeAgo } from '../../lib/utils/time-utils';
import { isValidURL } from '../../lib/utils/url-utils';
@@ -16,6 +16,7 @@ import useAuthorAddressClick from '../../hooks/use-author-address-click';
import useCountLinksInReplies from '../../hooks/use-count-links-in-replies';
import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame';
import useHide from '../../hooks/use-hide';
+import usePostCidForPendingPost from '../../hooks/use-post-cid';
import useReplies from '../../hooks/use-replies';
import useStateString from '../../hooks/use-state-string';
import CommentMedia from '../comment-media';
@@ -70,9 +71,11 @@ const PostInfo = ({ openReplyModal, post, postReplyCount = 0, roles, isHidden }:
// comment.author.shortAddress is undefined while the comment publishing state is pending, use account instead
// in anon mode, use the newly generated signer.address instead, which will be comment.author.address
const { anonMode } = useAnonMode();
- const { currentAnonSignerAddress } = useAnonModeStore();
+ const { getThreadSigner, currentAnonSignerAddress } = useAnonModeStore();
+ const postCidForSigner = usePostCidForPendingPost(parentCid);
+ const anonSignerAddress = postCidForSigner ? getThreadSigner(postCidForSigner)?.address || currentAnonSignerAddress : null;
const account = useAccount();
- const pendingShortAddress = anonMode ? currentAnonSignerAddress && Plebbit.getShortAddress(currentAnonSignerAddress) : account?.author?.shortAddress;
+ const pendingShortAddress = anonMode ? anonSignerAddress && Plebbit.getShortAddress(anonSignerAddress) : account?.author?.shortAddress;
const handleUserAddressClick = useAuthorAddressClick();
const numberOfPostsByAuthor = document.querySelectorAll(`[data-author-address="${shortAddress}"][data-post-cid="${postCid}"]`).length;
@@ -229,6 +232,8 @@ const PostMedia = ({ post }: PostProps) => {
const hasThumbnail = getHasThumbnail(commentMediaInfo, link);
const [showThumbnail, setShowThumbnail] = useState(true);
+ const mediaDimensions = getMediaDimensions(commentMediaInfo);
+
return (
@@ -236,7 +241,8 @@ const PostMedia = ({ post }: PostProps) => {
{spoiler ? _.capitalize(t('spoiler')) : url && url.length > 30 ? url.slice(0, 30) + '...' : url}
{' '}
- ({type && _.lowerCase(getDisplayMediaInfoType(type, t))})
+ ({type && _.lowerCase(getDisplayMediaInfoType(type, t))}
+ {mediaDimensions && `, ${mediaDimensions}`})
{!showThumbnail && (type === 'iframe' || type === 'video' || type === 'audio') && (
{' '}
diff --git a/src/components/post-form/post-form.module.css b/src/components/post-form/post-form.module.css
index 82373d42..2124f76a 100644
--- a/src/components/post-form/post-form.module.css
+++ b/src/components/post-form/post-form.module.css
@@ -16,6 +16,7 @@
.postFormMobile {
text-align: center;
margin-top: -2px;
+ padding-bottom: 7px;
}
.closed {
diff --git a/src/components/post-form/post-form.tsx b/src/components/post-form/post-form.tsx
index ce19159b..29e367d6 100644
--- a/src/components/post-form/post-form.tsx
+++ b/src/components/post-form/post-form.tsx
@@ -449,7 +449,6 @@ const PostForm = () => {
{showForm ? t('close_post_form') : isInPostView ? t('post_a_reply') : t('start_new_thread')}
{showForm && setShowForm(false)} postCid={postCid} />}
-
>
)}
diff --git a/src/components/post-mobile/post-mobile.tsx b/src/components/post-mobile/post-mobile.tsx
index fbe1b93d..660084b7 100644
--- a/src/components/post-mobile/post-mobile.tsx
+++ b/src/components/post-mobile/post-mobile.tsx
@@ -14,6 +14,7 @@ import useAnonMode from '../../hooks/use-anon-mode';
import useAuthorAddressClick from '../../hooks/use-author-address-click';
import useCountLinksInReplies from '../../hooks/use-count-links-in-replies';
import useHide from '../../hooks/use-hide';
+import usePostCidForPendingPost from '../../hooks/use-post-cid';
import useReplies from '../../hooks/use-replies';
import useStateString from '../../hooks/use-state-string';
import CommentMedia from '../comment-media';
@@ -51,9 +52,11 @@ const PostInfoAndMedia = ({ openReplyModal, post, postReplyCount = 0, roles }: P
// comment.author.shortAddress is undefined while the comment publishing state is pending, use account instead
// in anon mode, use the newly generated signer.address instead, which will be comment.author.address
const { anonMode } = useAnonMode();
- const { currentAnonSignerAddress } = useAnonModeStore();
+ const { getThreadSigner, currentAnonSignerAddress } = useAnonModeStore();
+ const postCidForSigner = usePostCidForPendingPost(parentCid);
+ const anonSignerAddress = postCidForSigner ? getThreadSigner(postCidForSigner)?.address || currentAnonSignerAddress : null;
const account = useAccount();
- const pendingShortAddress = anonMode ? currentAnonSignerAddress && Plebbit.getShortAddress(currentAnonSignerAddress) : account?.author?.shortAddress;
+ const pendingShortAddress = anonMode ? anonSignerAddress && Plebbit.getShortAddress(anonSignerAddress) : account?.author?.shortAddress;
const stateString = useStateString(post);
diff --git a/src/components/reply-quote-preview/reply-quote-preview.tsx b/src/components/reply-quote-preview/reply-quote-preview.tsx
index 407aae8c..90982e4d 100644
--- a/src/components/reply-quote-preview/reply-quote-preview.tsx
+++ b/src/components/reply-quote-preview/reply-quote-preview.tsx
@@ -3,6 +3,7 @@ import { createPortal } from 'react-dom';
import { Link, useNavigate } from 'react-router-dom';
import { Comment, useAccount } from '@plebbit/plebbit-react-hooks';
import { useFloating, offset, shift, size, autoUpdate, Placement } from '@floating-ui/react';
+import useAnonModeStore from '../../stores/use-anon-mode-store';
import useIsMobile from '../../hooks/use-is-mobile';
import styles from '../../views/post/post.module.css';
import { Post } from '../../views/post';
@@ -143,6 +144,8 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
);
const account = useAccount();
+ const { getThreadSigner } = useAnonModeStore();
+ const threadSigner = quotelinkReply?.postCid ? getThreadSigner(quotelinkReply?.postCid) : null;
const replyQuotelink = (
<>
@@ -155,7 +158,7 @@ const DesktopQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, i
onClick={(e) => handleClick(e, quotelinkReply?.cid, quotelinkReply?.subplebbitAddress)}
>
{quotelinkReply?.shortCid && `c/${quotelinkReply?.shortCid}`}
- {quotelinkReply?.author?.address === account?.author?.address && ' (You)'}
+ {(quotelinkReply?.author?.address === account?.author?.address || quotelinkReply?.author?.address === threadSigner?.address) && ' (You)'}
{hoveredCid === quotelinkReply?.cid &&
@@ -252,6 +255,8 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
);
const account = useAccount();
+ const { getThreadSigner } = useAnonModeStore();
+ const threadSigner = quotelinkReply?.postCid ? getThreadSigner(quotelinkReply?.postCid) : null;
const replyQuotelink = (
<>
@@ -262,7 +267,7 @@ const MobileQuotePreview = ({ backlinkReply, quotelinkReply, isBacklinkReply, is
onMouseLeave={() => handleMouseLeave(quotelinkReply?.cid)}
>
{quotelinkReply?.shortCid && `c/${quotelinkReply?.shortCid}`}
- {quotelinkReply?.author?.address === account?.author?.address && ' (You)'}
+ {(quotelinkReply?.author?.address === account?.author?.address || quotelinkReply?.author?.address === threadSigner?.address) && ' (You)'}
{quotelinkReply?.shortCid && (
{
{renderSubplebbits(projectsSubs)}
{renderSubplebbits(interestsSubs)}
{renderSubplebbits(randomSubs)}
- {renderSubplebbits(internationalSubs)}
- {/* [
+ {renderSubplebbits(internationalSubs)}[
{
e.preventDefault();
- alert('work in progress');
}}
>
Create
] [
{
e.preventDefault();
- alert('work in progress');
}}
>
Vote
- ] */}
+ ]
[{t('settings')}] [
diff --git a/src/hooks/use-post-cid.ts b/src/hooks/use-post-cid.ts
new file mode 100644
index 00000000..075d1808
--- /dev/null
+++ b/src/hooks/use-post-cid.ts
@@ -0,0 +1,43 @@
+import { useEffect, useReducer } from 'react';
+import { useComment } from '@plebbit/plebbit-react-hooks';
+
+type State = {
+ resolvedPostCid: string | null;
+ currentParentCid: string | undefined;
+};
+
+type Action = { type: 'SET_POST_CID'; payload: string } | { type: 'SET_PARENT_CID'; payload: string };
+
+const reducer = (state: State, action: Action): State => {
+ switch (action.type) {
+ case 'SET_POST_CID':
+ return { ...state, resolvedPostCid: action.payload };
+ case 'SET_PARENT_CID':
+ return { ...state, currentParentCid: action.payload };
+ default:
+ return state;
+ }
+};
+
+const usePostCidForPendingPost = (initialParentCid: string | undefined): string | null => {
+ const [state, dispatch] = useReducer(reducer, {
+ resolvedPostCid: null,
+ currentParentCid: initialParentCid,
+ });
+
+ const comment = useComment({ commentCid: state.currentParentCid });
+
+ useEffect(() => {
+ if (comment) {
+ if (comment.postCid) {
+ dispatch({ type: 'SET_POST_CID', payload: comment.postCid });
+ } else if (comment.parentCid) {
+ dispatch({ type: 'SET_PARENT_CID', payload: comment.parentCid });
+ }
+ }
+ }, [comment]);
+
+ return state.resolvedPostCid;
+};
+
+export default usePostCidForPendingPost;
diff --git a/src/hooks/use-theme.ts b/src/hooks/use-theme.ts
index e5fea198..bcff9cb8 100644
--- a/src/hooks/use-theme.ts
+++ b/src/hooks/use-theme.ts
@@ -5,6 +5,7 @@ import useThemeStore from '../stores/use-theme-store';
import useDefaultSubplebbits from './use-default-subplebbits';
import useInitialTheme from './use-initial-theme';
import { nsfwTags } from '../views/home/home';
+import { useAccountComment } from '@plebbit/plebbit-react-hooks';
const themeClasses = ['yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon'];
@@ -15,9 +16,14 @@ const updateThemeClass = (newTheme: string) => {
}
};
-const useTheme = (pendingPostSubplebbitAddress?: string): [string, (theme: string) => void] => {
+const useTheme = (): [string, (theme: string) => void] => {
const location = useLocation();
const params = useParams<{ subplebbitAddress: string }>();
+ const pendingPostParams = useParams<{ accountCommentIndex?: string }>();
+ const pendingPostCommentIndex = pendingPostParams?.accountCommentIndex ? parseInt(pendingPostParams.accountCommentIndex) : undefined;
+ const pendingPost = useAccountComment({ commentIndex: pendingPostCommentIndex });
+ const pendingPostSubplebbitAddress = pendingPost?.subplebbitAddress;
+
const setThemeStore = useThemeStore((state) => state.setTheme);
const getTheme = useThemeStore((state) => state.getTheme);
const loadThemes = useThemeStore((state) => state.loadThemes);
@@ -27,7 +33,7 @@ const useTheme = (pendingPostSubplebbitAddress?: string): [string, (theme: strin
const [currentTheme, setCurrentTheme] = useState(initialTheme);
const getCurrentTheme = useCallback(() => {
- const subplebbitAddress = params?.subplebbitAddress;
+ const subplebbitAddress = params?.subplebbitAddress || pendingPostSubplebbitAddress;
const isInAllView = isAllView(location.pathname, params);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, params);
@@ -44,7 +50,7 @@ const useTheme = (pendingPostSubplebbitAddress?: string): [string, (theme: strin
}
return storedTheme || initialTheme;
- }, [location.pathname, params, getTheme, subplebbits, initialTheme]);
+ }, [location.pathname, params, getTheme, subplebbits, initialTheme, pendingPostSubplebbitAddress]);
useEffect(() => {
const newTheme = getCurrentTheme();
@@ -60,7 +66,7 @@ const useTheme = (pendingPostSubplebbitAddress?: string): [string, (theme: strin
const setSubplebbitTheme = useCallback(
async (newTheme: string) => {
- const subplebbitAddress = params?.subplebbitAddress;
+ const subplebbitAddress = params?.subplebbitAddress || pendingPostSubplebbitAddress;
const isInAllView = isAllView(location.pathname, params);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, params);
@@ -78,7 +84,7 @@ const useTheme = (pendingPostSubplebbitAddress?: string): [string, (theme: strin
setCurrentTheme(newTheme);
updateThemeClass(newTheme);
},
- [location.pathname, params, setThemeStore, subplebbits],
+ [location.pathname, params, setThemeStore, subplebbits, pendingPostSubplebbitAddress],
);
return [currentTheme, setSubplebbitTheme];
diff --git a/src/lib/utils/media-utils.ts b/src/lib/utils/media-utils.ts
index dd676416..61f879a8 100644
--- a/src/lib/utils/media-utils.ts
+++ b/src/lib/utils/media-utils.ts
@@ -9,6 +9,7 @@ export interface CommentMediaInfo {
type: string;
thumbnail?: string;
patternThumbnailUrl?: string;
+ post?: Comment;
}
export const getDisplayMediaInfoType = (type: string, t: any) => {
@@ -106,8 +107,46 @@ export const getCommentMediaInfo = (comment: Comment): CommentMediaInfo | undefi
}
const linkInfo = comment.link ? getLinkMediaInfo(comment.link) : undefined;
if (linkInfo) {
- linkInfo.thumbnail = comment.thumbnailUrl || linkInfo.thumbnail;
- return linkInfo;
+ return {
+ ...linkInfo,
+ thumbnail: comment.thumbnailUrl || linkInfo.thumbnail,
+ post: comment,
+ };
}
return;
};
+
+export const getMediaDimensions = (commentMediaInfo: CommentMediaInfo | undefined): string => {
+ if (!commentMediaInfo) return '';
+
+ const { type, url, post } = commentMediaInfo;
+
+ if (type === 'iframe' && url) {
+ const embedUrl = new URL(url);
+ if (canEmbed(embedUrl)) {
+ // hardcoded dimensions from embed.module.css
+ if (embedUrl.hostname.includes('youtube.com') || embedUrl.hostname.includes('youtu.be')) {
+ return '800x450';
+ } else if (embedUrl.hostname.includes('instagram.com')) {
+ return '360x420';
+ } else if (embedUrl.hostname.includes('reddit.com')) {
+ return '500x520';
+ } else if (embedUrl.hostname.includes('tiktok.com')) {
+ return '400x780';
+ } else if (embedUrl.hostname.includes('x.com') || embedUrl.hostname.includes('twitter.com')) {
+ return '550x580';
+ } else if (embedUrl.hostname.includes('soundcloud.com')) {
+ return '700x166';
+ }
+ }
+ } else if (type === 'audio') {
+ return '700x240'; // hardcoded dimensions from embed.module.css
+ } else if (type === 'image' || type === 'video' || type === 'gif') {
+ // media dimensions calculated by API
+ if (post?.linkWidth && post?.linkHeight) {
+ return `${post.linkWidth}x${post.linkHeight}`;
+ }
+ }
+
+ return '';
+};
diff --git a/src/stores/use-catalog-filters-store.ts b/src/stores/use-catalog-filters-store.ts
index 543f7478..921d1b5b 100644
--- a/src/stores/use-catalog-filters-store.ts
+++ b/src/stores/use-catalog-filters-store.ts
@@ -1,5 +1,7 @@
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
+import { Comment } from '@plebbit/plebbit-react-hooks';
+import { getCommentMediaInfo, getHasThumbnail } from '../lib/utils/media-utils';
interface FilterItem {
text: string;
@@ -16,15 +18,23 @@ interface CatalogFiltersStore {
filterText: string;
setFilterText: (value: string) => void;
filterItems: FilterItem[];
- setFilterItems: (items: FilterItem[]) => void; // New method to set all filter items at once
- saveAndApplyFilters: (items: FilterItem[]) => void; // Updated to accept items
+ setFilterItems: (items: FilterItem[]) => void;
+ saveAndApplyFilters: (items: FilterItem[]) => void;
+ filter: ((comment: Comment) => boolean) | undefined;
+ updateFilter: () => void;
+ initializeFilter: () => void;
+ filteredCount: number;
+ resetFilteredCount: () => void;
}
const useCatalogFiltersStore = create(
persist(
- (set) => ({
+ (set, get) => ({
showTextOnlyThreads: false,
- setShowTextOnlyThreads: (value: boolean) => set({ showTextOnlyThreads: value }),
+ setShowTextOnlyThreads: (value: boolean) => {
+ set({ showTextOnlyThreads: value, filteredCount: 0 });
+ get().updateFilter();
+ },
showAdultBoards: false,
setShowAdultBoards: (value: boolean) => set({ showAdultBoards: value }),
showGoreBoards: false,
@@ -38,13 +48,59 @@ const useCatalogFiltersStore = create(
},
saveAndApplyFilters: (items: FilterItem[]) => {
const nonEmptyItems = items.filter((item) => item.text.trim() !== '');
- set({ filterItems: nonEmptyItems });
+ set({ filterItems: nonEmptyItems, filteredCount: 0 });
+ get().updateFilter();
},
+ filter: undefined,
+ updateFilter: () => {
+ const filteredCids = new Set();
+ set((state) => ({
+ filter: (comment: Comment) => {
+ const { showTextOnlyThreads, filterItems } = state;
+
+ const shouldShow = (() => {
+ if (!showTextOnlyThreads && !getHasThumbnail(getCommentMediaInfo(comment), comment?.link)) {
+ return false;
+ }
+
+ const title = comment?.title?.toLowerCase() || '';
+ const content = comment?.content?.toLowerCase() || '';
+
+ return !filterItems
+ .filter((item) => item.enabled)
+ .some((item) => {
+ const text = item.text.toLowerCase();
+ return title.includes(text) || content.includes(text);
+ });
+ })();
+
+ if (!shouldShow && !filteredCids.has(comment.cid)) {
+ filteredCids.add(comment.cid);
+ set((state) => ({ filteredCount: state.filteredCount + 1 }));
+ }
+
+ return shouldShow;
+ },
+ }));
+ },
+ initializeFilter: () => {
+ const { updateFilter } = get();
+ updateFilter();
+ },
+ filteredCount: 0,
+ resetFilteredCount: () => set({ filteredCount: 0 }),
}),
{
name: 'catalog-filters-storage',
+ onRehydrateStorage: () => (state) => {
+ if (state) {
+ state.updateFilter();
+ }
+ },
},
),
);
+useCatalogFiltersStore.getState().updateFilter();
+
export default useCatalogFiltersStore;
diff --git a/src/views/board/board.tsx b/src/views/board/board.tsx
index 290a5730..80b1ce95 100644
--- a/src/views/board/board.tsx
+++ b/src/views/board/board.tsx
@@ -168,19 +168,19 @@ const Board = () => {
subplebbitAddress={postSubplebbitAddress}
/>
)}
+ {((description && description.length > 0) || isInAllView) && (
+
+ )}
{feed.length !== 0 ? (
<>
{rules && rules.length > 0 && }
- {((description && description.length > 0) || isInAllView) && (
-
- )}
{
+const FiltersTable = ({
+ localFilterItems,
+ setLocalFilterItems,
+ onSave,
+}: {
+ localFilterItems: any[];
+ setLocalFilterItems: React.Dispatch>;
+ onSave: () => void;
+}) => {
const { t } = useTranslation();
- const { filterItems, saveAndApplyFilters } = useCatalogFiltersStore();
-
- const [localFilterItems, setLocalFilterItems] = useState(filterItems);
+ const { saveAndApplyFilters } = useCatalogFiltersStore();
const handleAddFilter = useCallback(() => {
setLocalFilterItems((prev) => [...prev, { text: '', enabled: true }]);
- }, []);
+ }, [setLocalFilterItems]);
const handleSave = useCallback(() => {
const nonEmptyFilters = localFilterItems.filter((item) => item.text.trim() !== '');
saveAndApplyFilters(nonEmptyFilters);
- }, [saveAndApplyFilters, localFilterItems]);
+ onSave();
+ }, [saveAndApplyFilters, localFilterItems, onSave]);
- const updateLocalFilterItem = useCallback((index: number, item: any) => {
- setLocalFilterItems((prev) => prev.map((f, i) => (i === index ? item : f)));
- }, []);
+ const updateLocalFilterItem = useCallback(
+ (index: number, item: any) => {
+ setLocalFilterItems((prev) => prev.map((f, i) => (i === index ? item : f)));
+ },
+ [setLocalFilterItems],
+ );
- const removeLocalFilterItem = useCallback((index: number) => {
- setLocalFilterItems((prev) => prev.filter((_, i) => i !== index));
- }, []);
+ const removeLocalFilterItem = useCallback(
+ (index: number) => {
+ setLocalFilterItems((prev) => prev.filter((_, i) => i !== index));
+ },
+ [setLocalFilterItems],
+ );
- const moveLocalFilterItemUp = useCallback((index: number) => {
- if (index === 0) return;
- setLocalFilterItems((prev) => {
- const newItems = [...prev];
- [newItems[index - 1], newItems[index]] = [newItems[index], newItems[index - 1]];
- return newItems;
- });
- }, []);
+ const moveLocalFilterItemUp = useCallback(
+ (index: number) => {
+ if (index === 0) return;
+ setLocalFilterItems((prev) => {
+ const newItems = [...prev];
+ [newItems[index - 1], newItems[index]] = [newItems[index], newItems[index - 1]];
+ return newItems;
+ });
+ },
+ [setLocalFilterItems],
+ );
return (
@@ -99,12 +115,38 @@ const FiltersTable = () => {
const FiltersModal = ({ closeModal }: { closeModal: () => void }) => {
const { t } = useTranslation();
- const { showAdultBoards, setShowAdultBoards, showGoreBoards, setShowGoreBoards, showTextOnlyThreads, setShowTextOnlyThreads } = useCatalogFiltersStore();
+ const { showAdultBoards, setShowAdultBoards, showGoreBoards, setShowGoreBoards, showTextOnlyThreads, setShowTextOnlyThreads, filterItems, saveAndApplyFilters } =
+ useCatalogFiltersStore();
+
+ const [localShowAdultBoards, setLocalShowAdultBoards] = useState(showAdultBoards);
+ const [localShowGoreBoards, setLocalShowGoreBoards] = useState(showGoreBoards);
+ const [localShowTextOnlyThreads, setLocalShowTextOnlyThreads] = useState(showTextOnlyThreads);
+ const [localFilterItems, setLocalFilterItems] = useState(filterItems);
+
const location = useLocation();
const params = useParams();
const isInCatalogView = isCatalogView(location.pathname, params);
const isInAllView = isAllView(location.pathname, params);
+ const handleSave = useCallback(() => {
+ setShowAdultBoards(localShowAdultBoards);
+ setShowGoreBoards(localShowGoreBoards);
+ setShowTextOnlyThreads(localShowTextOnlyThreads);
+ const nonEmptyFilters = localFilterItems.filter((item) => item.text.trim() !== '');
+ saveAndApplyFilters(nonEmptyFilters);
+ closeModal();
+ }, [
+ localShowAdultBoards,
+ localShowGoreBoards,
+ localShowTextOnlyThreads,
+ localFilterItems,
+ setShowAdultBoards,
+ setShowGoreBoards,
+ setShowTextOnlyThreads,
+ saveAndApplyFilters,
+ closeModal,
+ ]);
+
return (
<>
@@ -117,7 +159,7 @@ const FiltersModal = ({ closeModal }: { closeModal: () => void }) => {
{isInCatalogView && (
@@ -126,20 +168,20 @@ const FiltersModal = ({ closeModal }: { closeModal: () => void }) => {
)}
- {isInCatalogView && }
+ {isInCatalogView && }
>
);
diff --git a/src/views/catalog/catalog.tsx b/src/views/catalog/catalog.tsx
index ee7bc0fc..5afc8eaa 100644
--- a/src/views/catalog/catalog.tsx
+++ b/src/views/catalog/catalog.tsx
@@ -1,9 +1,8 @@
import { useEffect, useMemo, useRef } from 'react';
import { useLocation, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
-import { Comment, useAccount, useFeed, useSubplebbit, useBlock } from '@plebbit/plebbit-react-hooks';
+import { useAccount, useFeed, useSubplebbit, useBlock } from '@plebbit/plebbit-react-hooks';
import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso';
-import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils';
import { isAllView, isSubscriptionsView } from '../../lib/utils/view-utils';
import useCatalogFeedRows from '../../hooks/use-catalog-feed-rows';
import useDefaultSubplebbits from '../../hooks/use-default-subplebbits';
@@ -21,25 +20,6 @@ import styles from './catalog.module.css';
const lastVirtuosoStates: { [key: string]: StateSnapshot } = {};
-const threadsWithImagesFilter = (comment: Comment) => {
- const commentMediaInfo = getCommentMediaInfo(comment);
- const hasThumbnail = getHasThumbnail(commentMediaInfo, comment?.link);
- return hasThumbnail;
-};
-
-const textFilter = (comment: Comment, filterItems: any[]) => {
- if (!filterItems) return true;
- if (filterItems.length === 0) return true;
- const titleLower = comment?.title?.toLowerCase() || '';
- const contentLower = comment?.content?.toLowerCase() || '';
-
- return filterItems.every((item) => {
- if (!item.enabled) return true;
- const pattern = item.text.toLowerCase();
- return !(titleLower.includes(pattern) || contentLower.includes(pattern));
- });
-};
-
const Catalog = () => {
const { t } = useTranslation();
const location = useLocation();
@@ -47,7 +27,7 @@ const Catalog = () => {
const isInAllView = isAllView(location.pathname, useParams());
const defaultSubplebbits = useDefaultSubplebbits();
- const { showAdultBoards, showGoreBoards, showTextOnlyThreads, filterItems } = useCatalogFiltersStore();
+ const { filter, showAdultBoards, showGoreBoards } = useCatalogFiltersStore();
const account = useAccount();
const subscriptions = account?.subscriptions;
@@ -80,31 +60,25 @@ const Catalog = () => {
const columnWidth = imageSize === 'Large' ? 270 : 180;
const columnCount = Math.floor(useWindowWidth() / columnWidth);
- // postPerPage based on columnCount for optimized feed, dont change value after first render
- // eslint-disable-next-line
- const postsPerPage = useMemo(() => (columnCount <= 2 ? 10 : columnCount === 3 ? 15 : columnCount === 4 ? 20 : 25), []);
+ const postsPerPage = columnCount <= 2 ? 10 : columnCount === 3 ? 15 : columnCount === 4 ? 20 : 25;
const { timeFilterSeconds } = useTimeFilter();
const { sortType } = useSortingStore();
- const feedOptions: any = useMemo(
- () => ({
+ const feedOptions = useMemo(() => {
+ const options: any = {
subplebbitAddresses,
sortType,
postsPerPage: isInAllView || isInSubscriptionsView ? 10 : postsPerPage,
- filter: (comment: Comment) => {
- if (!showTextOnlyThreads && !threadsWithImagesFilter(comment)) {
- return false;
- }
- return textFilter(comment, filterItems);
- },
- }),
- [subplebbitAddresses, sortType, isInAllView, isInSubscriptionsView, postsPerPage, showTextOnlyThreads, filterItems],
- );
+ filter,
+ };
- if (isInAllView || isInSubscriptionsView) {
- feedOptions.newerThan = timeFilterSeconds;
- }
+ if (isInAllView || isInSubscriptionsView) {
+ options.newerThan = timeFilterSeconds;
+ }
+
+ return options;
+ }, [subplebbitAddresses, sortType, isInAllView, isInSubscriptionsView, postsPerPage, timeFilterSeconds, filter]);
const { feed, hasMore, loadMore, reset } = useFeed(feedOptions);
diff --git a/src/views/pending-post/pending-post.tsx b/src/views/pending-post/pending-post.tsx
index 72980b28..fedea830 100644
--- a/src/views/pending-post/pending-post.tsx
+++ b/src/views/pending-post/pending-post.tsx
@@ -4,7 +4,6 @@ import { useAccountComment } from '@plebbit/plebbit-react-hooks';
import { isSettingsView } from '../../lib/utils/view-utils';
import { Post } from '../post';
import SettingsModal from '../../components/settings-modal';
-import useTheme from '../../hooks/use-theme';
const PendingPost = () => {
const { accountCommentIndex } = useParams<{ accountCommentIndex?: string }>();
@@ -15,8 +14,6 @@ const PendingPost = () => {
const params = useParams();
const isInSettingsView = isSettingsView(location.pathname, params);
- useTheme(post?.subplebbitAddress);
-
useEffect(() => window.scrollTo(0, 0), []);
useEffect(() => {
diff --git a/src/views/post/post.module.css b/src/views/post/post.module.css
index 9ca8c0e5..9266596d 100644
--- a/src/views/post/post.module.css
+++ b/src/views/post/post.module.css
@@ -160,6 +160,7 @@
.postDesktop .postMessage, .replyDesktop .postMessage {
padding: 1em 40px;
+ overflow: hidden;
}
.postDesktop .abbr {
@@ -328,6 +329,7 @@
.postMobile .postMessage {
padding: 10px;
font-size: var(--post-mobile-content-font-size);
+ overflow: hidden;
word-break: break-word;
}