) => {
const inputValue = e.target.value.trim();
// If empty or invalid, restore to current value or default to 1
if (inputValue === '' || isNaN(parseInt(inputValue, 10))) {
const safeValue = alertThresholdValue >= 1 ? alertThresholdValue : 1;
setAlertThreshold(safeValue, alertThresholdUnit);
}
};
return (
);
};
const ModQueueViewSelector = () => {
const { t } = useTranslation();
const { viewMode, setViewMode } = useModQueueStore();
return (
);
};
const ShowOPCommentOption = () => {
const { t } = useTranslation();
const { showOPComment, setShowOPComment } = useCatalogStyleStore();
return (
<>
{t('show_op_comment')}:
>
);
};
const AllFeedFilter = () => {
const { t } = useTranslation();
const { filter, setFilter } = useAllFeedFilterStore();
return (
<>
{t('show')}:
>
);
};
export const MobileBoardButtons = () => {
const { t } = useTranslation();
const params = useParams();
const location = useLocation();
const isInAllView = isAllView(location.pathname);
const isInCatalogView = isCatalogView(location.pathname, params);
const isInPendingPostPage = isPendingPostView(location.pathname, params);
const isInPostView = isPostPageView(location.pathname, params);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams());
const isInModView = isModView(location.pathname);
const isInModQueueView = isModQueueView(location.pathname);
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
const resolvedAddress = useResolvedSubplebbitAddress();
const subplebbitAddress = resolvedAddress || accountComment?.subplebbitAddress;
const { filteredCount, searchText } = useCatalogFiltersStore();
const enableInfiniteScroll = useFeedViewSettingsStore((state) => state.enableInfiniteScroll);
const isMultiboard = isInAllView || isInSubscriptionsView || isInModView;
const effectiveInfiniteScroll = isMultiboard || enableInfiniteScroll;
const showBottomButton = (isInCatalogView || isInPostView || isInPendingPostPage) && !effectiveInfiniteScroll;
// Check if we should show the vote button (only for directory boards)
const directories = useDirectories();
const boardIdentifier = params.boardIdentifier || params.subplebbitAddress;
const showVoteButton = boardIdentifier && isDirectoryBoard(boardIdentifier, directories);
return (
{isInPostView || isInPendingPostPage ? (
<>
{showBottomButton &&
}
>
) : isInModQueueView ? (
<>
>
) : (
<>
{isInCatalogView ? (
) : (
)}
{showVoteButton &&
}
{!(isInAllView || isInSubscriptionsView || isInModView) &&
}
{!(isInAllView || isInSubscriptionsView) &&
}
{showBottomButton &&
}
{isInCatalogView && searchText ? (
{' '}
— {t('search_results_for')}: {searchText}
) : (
isInCatalogView &&
filteredCount > 0 && (
{' '}
— {t('filtered_threads')}: {filteredCount}
)
)}
{isInAllView && (
<>
>
)}
{isInCatalogView && (
<>
>
)}
>
)}
);
};
export const PostPageStats = () => {
const { t } = useTranslation();
const params = useParams();
const location = useLocation();
const commentCid = params?.commentCid as string | undefined;
const resolvedAddress = useResolvedSubplebbitAddress();
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
const subplebbitAddress = resolvedAddress || accountComment?.subplebbitAddress;
const comment = useComment({ commentCid });
const postCid = comment?.postCid ?? commentCid;
const post = useComment({ commentCid: postCid });
const { closed, pinned, replyCount } = post || {};
const linkCount = useCountLinksInReplies(post);
const directoryEntry = useDirectoryByAddress(subplebbitAddress);
const requirePostLinkIsMedia = directoryEntry?.features?.requirePostLinkIsMedia === true;
const isThreadView = isPostPageView(location.pathname, params);
const pageNumber = usePostPageNumber({
subplebbitAddress,
postCid,
enabled: isThreadView,
});
const displayReplyCount = replyCount !== undefined ? replyCount.toString() : '?';
const replyCountTooltip = replyCount !== undefined ? capitalize(t('replies')) : t('loading');
return (
{pinned && `${capitalize(t('sticky'))} / `}
{closed && `${capitalize(t('closed'))} / `}
{displayReplyCount} /{' '}
{linkCount?.toString()}
{isThreadView && (
<>
{' '}
/ {pageNumber?.toString() ?? '?'}
>
)}
);
};
export const DesktopBoardButtons = () => {
const { t } = useTranslation();
const params = useParams();
const location = useLocation();
const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any });
const resolvedAddress = useResolvedSubplebbitAddress();
const subplebbitAddress = resolvedAddress || accountComment?.subplebbitAddress;
const isInCatalogView = isCatalogView(location.pathname, params);
const isInAllView = isAllView(location.pathname);
const isInPendingPostPage = isPendingPostView(location.pathname, params);
const isInPostView = isPostPageView(location.pathname, params);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams());
const isInModView = isModView(location.pathname);
const isInModQueueView = isModQueueView(location.pathname);
const { filteredCount, searchText } = useCatalogFiltersStore();
const enableInfiniteScroll = useFeedViewSettingsStore((state) => state.enableInfiniteScroll);
const isMultiboard = isInAllView || isInSubscriptionsView || isInModView;
const effectiveInfiniteScroll = isMultiboard || enableInfiniteScroll;
const showBottomButton = (isInCatalogView || isInPostView || isInPendingPostPage) && !effectiveInfiniteScroll;
// Check if we should show the vote button (only for directory boards)
const directories = useDirectories();
const boardIdentifier = params.boardIdentifier || params.subplebbitAddress;
const showVoteButton = boardIdentifier && isDirectoryBoard(boardIdentifier, directories);
return (
<>
{isInPostView || isInPendingPostPage ? (
<>
[
] [
]
{showBottomButton && (
<>
{' '}
[
]
>
)}{' '}
[
] [
]
>
) : isInModQueueView ? (
<>
[
] [
]
>
) : (
<>
{isInCatalogView ? (
<>
[
]{' '}
>
) : (
<>
[
]{' '}
>
)}
{showVoteButton && (
<>
{' '}
[
]
>
)}
{showBottomButton && (
<>
{' '}
[
]
>
)}{' '}
[
]
{!(isInAllView || isInSubscriptionsView) && (
<>
{' '}
>
)}
{isInCatalogView && searchText ? (
{' '}
— {t('search_results_for')}: {searchText}
) : (
isInCatalogView &&
filteredCount > 0 && (
{' '}
— {t('filtered_threads')}: {filteredCount}
)
)}
{isInCatalogView && (
<>
>
)}
{isInAllView && }
{!(isInAllView || isInSubscriptionsView || isInModView) && (
<>
[]
>
)}{' '}
{isInCatalogView && (
<>
[]
>
)}
>
)}
>
);
};
const SearchOPsBar = () => {
const { t } = useTranslation();
const navigate = useNavigate();
const params = useParams();
const location = useLocation();
const isInAllView = isAllView(location.pathname);
const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams());
const isInModView = isModView(location.pathname);
const directories = useDirectories();
const resolvedAddress = useResolvedSubplebbitAddress();
const boardPath = resolvedAddress ? getBoardPath(resolvedAddress, directories) : params?.boardIdentifier || params?.subplebbitAddress;
const handleSearch = (event: React.KeyboardEvent) => {
if (event.key === 'Enter') {
const searchQuery = (event.target as HTMLInputElement).value.trim();
if (searchQuery) {
let catalogUrl = '';
if (isInAllView) {
catalogUrl = `/all/catalog?q=${encodeURIComponent(searchQuery)}`;
} else if (isInSubscriptionsView) {
catalogUrl = `/subs/catalog?q=${encodeURIComponent(searchQuery)}`;
} else if (isInModView) {
catalogUrl = `/mod/catalog?q=${encodeURIComponent(searchQuery)}`;
} else {
catalogUrl = `/${boardPath}/catalog?q=${encodeURIComponent(searchQuery)}`;
}
navigate(catalogUrl);
}
}
};
return ;
};