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; }