Skip to content

Add hidden trash board#1183

Merged
tomcasaburi merged 4 commits into
masterfrom
codex/feature/trash-board
Jul 2, 2026
Merged

Add hidden trash board#1183
tomcasaburi merged 4 commits into
masterfrom
codex/feature/trash-board

Conversation

@tomcasaburi

@tomcasaburi tomcasaburi commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary

  • add a hidden /trash/ special board that routes to off-topic.bso without appearing in directory navigation
  • expose /trash/ - Off-topic in moderator transfer targets and board metadata, theme, and favicon handling
  • filter special boards out of generic directory hydration and vendored candidate lookup so the public seeder list can include /trash/ safely

The matching bitsocialnet/lists seed-list file is already merged to master so existing bitsocial-seeder instances can discover off-topic.bso through the current GitHub contents source.

Verification

  • corepack yarn lint
  • corepack yarn type-check
  • corepack yarn test
  • corepack yarn build
  • corepack yarn doctor (known baseline failure: ace-builds Socket score and existing post-form effect diagnostics)
  • Playwright route checks in Chrome, Firefox, and WebKit on desktop/mobile
  • live .189 readback verified off-topic.bso resolves to the new public key and matches random-nsfw.bso published features/challenges

Note

Medium Risk
Touches routing, directory hydration, and moderator transfer flows across many call sites; mistakes could hide boards incorrectly or break transfers, but behavior is heavily covered by new tests.

Overview
Introduces a hidden /trash/ board (off-topic.bso) via a new special-boards registry: routable by code and aliases, but not shown in public directory lists.

Routing & discovery: getBoardPath / getCommunityAddress resolve trash without treating it as a normal directory route. Remote and vendored directory hydration filters special boards out of listings and lookup helpers so seed lists can still mention the board safely.

UI & moderation: Headers, board page titles, NSFW theme bucket, and favicon logic use special-board metadata when there is no directory entry. The post transfer modal adds trash as a target, resolves it as a source (including alias matching), and omits re-transfer to trash when the source is identified by public key.

Transfer copy: Source moderation reasons use /trash/ and plain “the rules” instead of a rules-page link for special boards.

Reviewed by Cursor Bugbot for commit dc806dc. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Added support for a special “trash/off-topic” board throughout the app.
    • Board titles, routes, and transfer targets now recognize this board consistently.
  • Bug Fixes

    • The trash board is now hidden from regular directory listings while still remaining accessible where needed.
    • Page titles and headers now display the correct trash board name and address even without a directory entry.
    • NSFW/SFW handling and favicon behavior now correctly reflect the trash board status.

@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
5chan Ready Ready Preview, Comment Jul 2, 2026 2:04pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces a special-boards module defining a hidden "trash" board with metadata (address, code, title, nsfw flag, aliases). It integrates this special board into route resolution, directory list filtering/normalization, theme/favicon NSFW detection, board title display, and post-transfer modal target options, with accompanying tests.

Changes

Special Board Introduction and Integration

Layer / File(s) Summary
Special boards module
src/lib/special-boards.ts
New module defines SpecialBoard interface, trash board constants (TRASH_BOARD_ADDRESS, TRASH_BOARD_CODE, TRASH_BOARD_TITLE, TRASH_BOARD_PUBLIC_KEY), the SPECIAL_BOARDS array, and lookup/predicate functions (getSpecialBoardByCode, getSpecialBoardByAddress, isSpecialBoardCode, isSpecialBoardAddress).
Route mapping and directory-list filtering
src/lib/utils/route-utils.ts, src/lib/utils/directory-list-lookup-utils.ts, src/lib/utils/__tests__/*
getBoardPath/getCommunityAddress short-circuit for special boards; vendored directory list filtering and address/code lookups exclude special boards; tests verify hidden-board mapping and lookup exclusion.
Directory normalization filtering
src/hooks/use-directories.ts, src/hooks/__tests__/use-directories.test.tsx
A new isVisibleDirectoryCommunity filter excludes special-board entries from normalized directory data; test confirms trash board is excluded from directories/addresses.
Theme and favicon NSFW detection
src/hooks/use-theme.ts, src/lib/update-favicon.ts, src/lib/__tests__/update-favicon.test.ts
Theme selection and favicon SFW detection now consult the special board's nsfw flag alongside community data; test verifies trash board is not SFW.
Board header/title resolution
src/components/board-header/board-header.tsx, src/views/board/board.tsx, related tests
Board title fallback chains now prefer the special board's title; tests confirm trash board title/address render correctly.
Post-transfer modal and mod-queue target options
src/components/post-transfer-modal/post-transfer-modal.tsx, related tests, src/views/mod-queue/__tests__/mod-queue.test.tsx
Transfer target options now include SPECIAL_BOARDS; source board resolution checks special boards first; tests verify trash board appears as a transfer option and transfer flow works.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant BoardView as Board/BoardHeader
    participant RouteUtils as route-utils
    participant SpecialBoards as special-boards module

    User->>BoardView: Navigate to /trash
    BoardView->>RouteUtils: getCommunityAddress(boardIdentifier)
    RouteUtils->>SpecialBoards: getSpecialBoardByCode(code)
    SpecialBoards-->>RouteUtils: TRASH_BOARD_ADDRESS
    RouteUtils-->>BoardView: resolved address
    BoardView->>SpecialBoards: getSpecialBoardByAddress(address)
    SpecialBoards-->>BoardView: specialBoard (title, nsfw)
    BoardView-->>User: Render TRASH_BOARD_TITLE, apply NSFW theme
Loading

Possibly related PRs

  • bitsocialnet/5chan#1073: The main PR's special-board title/address resolution changes in BoardHeader overlap with this PR's community-hook refactor that also rewires BoardHeader title/subtitle logic based on community/defaultCommunity.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a hidden trash special board.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/feature/trash-board

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread src/components/post-transfer-modal/post-transfer-modal.tsx
Comment thread src/lib/utils/directory-list-lookup-utils.ts
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
{}

Comment thread src/components/post-transfer-modal/post-transfer-modal.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/hooks/use-theme.ts (1)

68-115: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a focused test for the special-board theme branch in src/hooks/use-theme.ts The new currentTheme and setCommunityTheme paths for special boards still need direct coverage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/use-theme.ts` around lines 68 - 115, Add a focused test covering
the special-board branch in useTheme so both currentTheme resolution and
setCommunityTheme are exercised when getSpecialBoardByAddress returns an nsfw
board. Verify the hook picks themes.nsfw for special boards and that
setCommunityTheme calls setThemeStore with the nsfw bucket in that path, using
the existing useTheme, getSpecialBoardByAddress, and setThemeStore symbols to
target the new logic directly.

Source: Coding guidelines

🧹 Nitpick comments (2)
src/lib/utils/directory-list-lookup-utils.ts (1)

25-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing test coverage for the top-level directoryCode filter branch.

The new isSpecialBoardCode(directoryCode) check on this line filters out an entire vendored directory when the directory's own code is a special code. This branch isn't covered by directory-list-lookup-utils.test.ts, which only mocks a nested trash board under directory code 'b' (exercising the address-based guards at lines 43/55, not this line).

As per coding guidelines, "Add or update tests for bug fixes and non-trivial logic changes when the code is reasonably testable."

✅ Suggested additional test case
it('excludes an entire vendored directory whose own code is a special board code', async () => {
  const { getVendoredDirectoryLists } = await importLookupUtilsWithDirectoryLists([
    { directoryCode: 'trash', boards: [{ address: TRASH_BOARD_ADDRESS, publicKey: TRASH_BOARD_PUBLIC_KEY }] },
    { directoryCode: 'b', boards: [{ address: 'business.eth', publicKey: 'biz-key' }] },
  ]);

  expect(getVendoredDirectoryLists().map((d) => d.directoryCode)).toEqual(['b']);
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/utils/directory-list-lookup-utils.ts` at line 25, Add test coverage
for the top-level directoryCode filter in getVendoredDirectoryLists: the new
isSpecialBoardCode(directoryCode) branch should be exercised by a case where an
entire vendored directory is excluded because its own directoryCode is special,
not just by nested board address checks. Update
directory-list-lookup-utils.test.ts (or the existing lookup test helper) to
import getVendoredDirectoryLists via the current test setup and assert that a
directory with a special code is filtered out while a normal directory remains.

Source: Coding guidelines

src/hooks/use-theme.ts (1)

68-80: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the duplicated NSFW-resolution logic into a shared helper.

The community?.nsfw || specialBoard?.nsfw check is duplicated verbatim between currentTheme's memo (Lines 71-76) and setCommunityTheme (Lines 106-111). It also uses different combining semantics than isSfwBoard in src/lib/update-favicon.ts, which instead treats specialBoard as fully overriding the directory entry (if (specialBoard) return !specialBoard.nsfw;) rather than OR-ing the two flags. Today these are behaviorally equivalent because special boards are filtered out of directories, but the duplicated/divergent logic is fragile to future changes in that invariant.

Consider extracting a single resolveIsNsfwForAddress(address, directories) helper (e.g. alongside getSpecialBoardByAddress in src/lib/special-boards.ts) and reusing it in both files.

♻️ Suggested consolidation
+// src/lib/special-boards.ts
+export const resolveIsNsfwForAddress = (
+  address: string | undefined,
+  directories: { address: string; nsfw?: boolean }[],
+): boolean => {
+  const specialBoard = getSpecialBoardByAddress(address);
+  if (specialBoard) return !!specialBoard.nsfw;
+  const entry = directories.find((d) => d.address === address);
+  return !!entry?.nsfw;
+};
 } else if (communityAddress) {
-      const community = directories.find((entry) => entry.address === communityAddress);
-      const specialBoard = getSpecialBoardByAddress(communityAddress);
-      if (community?.nsfw || specialBoard?.nsfw) {
+      if (resolveIsNsfwForAddress(communityAddress, directories)) {
         storedTheme = themes.nsfw;
       } else {
         storedTheme = themes.sfw;
       }
     }

Also applies to: 100-115

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/use-theme.ts` around lines 68 - 80, Extract the duplicated
NSFW-resolution logic into a shared helper so both theme selection paths use the
same rules. Add a helper such as resolveIsNsfwForAddress(address, directories)
near getSpecialBoardByAddress in special-boards logic, and have currentTheme and
setCommunityTheme call it instead of repeating community?.nsfw ||
specialBoard?.nsfw. Also update isSfwBoard in update-favicon to use the same
helper/semantics so special-board override behavior stays consistent.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/post-transfer-modal/post-transfer-modal.tsx`:
- Around line 186-201: The board exclusion logic in boardOptions only checks
canonical addresses, so special-board aliases can still slip through as
selectable transfer targets. Update the filter in post-transfer-modal.tsx to
resolve the source board using the same alias-aware logic as sourceBoard,
including getSpecialBoardByAddress and any SPECIAL_BOARDS aliases, and then
exclude any matching board entry from boardOptions. Keep the change localized
around boardOptions, sourceCommunityAddress, and sourceBoard so the transfer
target list cannot include the current board under an alias.

---

Outside diff comments:
In `@src/hooks/use-theme.ts`:
- Around line 68-115: Add a focused test covering the special-board branch in
useTheme so both currentTheme resolution and setCommunityTheme are exercised
when getSpecialBoardByAddress returns an nsfw board. Verify the hook picks
themes.nsfw for special boards and that setCommunityTheme calls setThemeStore
with the nsfw bucket in that path, using the existing useTheme,
getSpecialBoardByAddress, and setThemeStore symbols to target the new logic
directly.

---

Nitpick comments:
In `@src/hooks/use-theme.ts`:
- Around line 68-80: Extract the duplicated NSFW-resolution logic into a shared
helper so both theme selection paths use the same rules. Add a helper such as
resolveIsNsfwForAddress(address, directories) near getSpecialBoardByAddress in
special-boards logic, and have currentTheme and setCommunityTheme call it
instead of repeating community?.nsfw || specialBoard?.nsfw. Also update
isSfwBoard in update-favicon to use the same helper/semantics so special-board
override behavior stays consistent.

In `@src/lib/utils/directory-list-lookup-utils.ts`:
- Line 25: Add test coverage for the top-level directoryCode filter in
getVendoredDirectoryLists: the new isSpecialBoardCode(directoryCode) branch
should be exercised by a case where an entire vendored directory is excluded
because its own directoryCode is special, not just by nested board address
checks. Update directory-list-lookup-utils.test.ts (or the existing lookup test
helper) to import getVendoredDirectoryLists via the current test setup and
assert that a directory with a special code is filtered out while a normal
directory remains.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 11f7489b-5112-4be2-b3d9-d8ca46765923

📥 Commits

Reviewing files that changed from the base of the PR and between 19530d1 and 52c84cd.

📒 Files selected for processing (17)
  • src/components/board-header/__tests__/board-header.test.tsx
  • src/components/board-header/board-header.tsx
  • src/components/post-transfer-modal/__tests__/post-transfer-modal.test.tsx
  • src/components/post-transfer-modal/post-transfer-modal.tsx
  • src/hooks/__tests__/use-directories.test.tsx
  • src/hooks/use-directories.ts
  • src/hooks/use-theme.ts
  • src/lib/__tests__/update-favicon.test.ts
  • src/lib/special-boards.ts
  • src/lib/update-favicon.ts
  • src/lib/utils/__tests__/directory-list-lookup-utils.test.ts
  • src/lib/utils/__tests__/route-utils.test.ts
  • src/lib/utils/directory-list-lookup-utils.ts
  • src/lib/utils/route-utils.ts
  • src/views/board/__tests__/board.test.tsx
  • src/views/board/board.tsx
  • src/views/mod-queue/__tests__/mod-queue.test.tsx

Comment thread src/components/post-transfer-modal/post-transfer-modal.tsx

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1a8db87. Configure here.

Comment thread src/components/post-transfer-modal/post-transfer-modal.tsx
@tomcasaburi tomcasaburi merged commit 099fdd6 into master Jul 2, 2026
12 checks passed
@tomcasaburi tomcasaburi deleted the codex/feature/trash-board branch July 2, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant