Skip to content

feat(flash board): add SWF posting support#1145

Merged
tomcasaburi merged 2 commits into
masterfrom
codex/feature/flash-board-swf
May 30, 2026
Merged

feat(flash board): add SWF posting support#1145
tomcasaburi merged 2 commits into
masterfrom
codex/feature/flash-board-swf

Conversation

@tomcasaburi
Copy link
Copy Markdown
Member

@tomcasaburi tomcasaburi commented May 30, 2026

Summary

  • add the /f/ flash directory metadata for flash-posting.bso with required tags, SWF links, and classic board rules
  • support SWF direct links through media detection, Catbox/direct-url upload flows, Android picker MIME types, and sandboxed Ruffle playback
  • render /f/ as a compact 4chan-style table with tag flairs and an empty-state row

Verification

  • corepack yarn install
  • corepack yarn lint
  • corepack yarn type-check
  • corepack yarn knip
  • corepack yarn test
  • corepack yarn test src/views/board/tests/board.test.tsx
  • corepack yarn build
  • playwright-cli Chrome, Firefox, and WebKit desktop/mobile verification for https://codex-feature-flash-board-swf.5chan.localhost/#/f

Notes

  • yarn doctor was run during implementation and still reports the existing repo-wide baseline; the new flash table component was clean after the React review pass.

Note

Medium Risk
New directory rules and SWF playback via Ruffle add client surface area (third-party runtime, external SWF URLs); mitigations are sandbox-style Ruffle settings but hosts/CORS still affect reliability.

Overview
Adds /f/ – Flash as a first-class directory (flash-posting.bso) with mandatory tag flairs, required post links, and classic tagging rules, wired through directory sync/bootstrap and 5chan-directory-lists.json.

SWF end-to-end: .swf is treated as direct media (web, Electron, Android MIME types, file picker accept). Posts and threads render SWF with a [SWF] thumbnail and Ruffle on expand (restricted networking/script access; runtime copied under /ruffle/ at build/dev). Upload flows and copy steer users toward direct HTTPS .swf URLs (e.g. Catbox).

/f/ board UX: the index uses a 4chan-style table (FlashBoardTable) instead of the normal Virtuoso feed, with tag short labels on rows and in posts (PostFlashTag). The post form adds a tag dropdown and Catbox-oriented upload guidance; selected tags publish as flash:* post flairs.

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

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Flash (.swf) media support with integrated emulation and rendering
    • Introduced /f/ - Flash directory with dedicated table-based post view
    • Added flash tagging system (hentai, porn, anime, game, loop, Japanese, other)
    • Added flash upload guidance prompts in 30+ languages
    • Expanded file upload acceptance to include Flash formats (.gifv extensions)
  • UI Improvements

    • Flash tag selector in post form for flash boards
    • Flash tags displayed on individual posts
    • Dedicated flash board table layout for organized content viewing

Review Change Stack

@vercel
Copy link
Copy Markdown

vercel Bot commented May 30, 2026

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

Project Deployment Actions Updated (UTC)
5chan Ready Ready Preview, Comment May 30, 2026 8:55am

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

📝 Walkthrough

Walkthrough

This PR introduces comprehensive Flash (.swf) media support to 5chan, including Ruffle-based SWF playback in comments, a dedicated flash board (/f/) with tag-based post organization, flash tag selection in post forms, and translations across 36 languages. Core infrastructure spans media type recognition, file upload acceptance, Ruffle runtime integration, and directory metadata with rules support.

Changes

Flash Media & Directory Integration

Layer / File(s) Summary
Ruffle Player & Flash Media Type
src/types/ruffle.d.ts, src/components/comment-media/ruffle-player.tsx, src/components/comment-media/comment-media.module.css, src/lib/utils/media-utils.ts, src/lib/utils/__tests__/media-utils.test.ts
SWF recognized as a distinct media type. RufflePlayer React component lazy-loads @ruffle-rs/ruffle, configures the runtime with publicPath and common settings, mounts a Ruffle player element, and handles load success/failure/loading states. Media utility functions classify SWF links and return "SWF" display labels. CSS styles Ruffle containers, hidden/loading/fallback states, and theme overrides.
Flash Tag System & Model
src/lib/flash-tags.ts, src/lib/__tests__/flash-tags.test.ts
Fixed set of flash tag codes (hentai, porn, japanese, anime, game, loop, other). FlashTagOption includes display/short labels and a flair object. Exported helpers: isFlashDirectoryCode, isFlashDirectory (normalize code from directoryCode or title), getFlashTagOption, getFlashTagPublishOptionsForDirectoryCode, and getFlashTagOptionFromComment (parse comment flairs). Comprehensive test coverage validates tag options, publish logic gating for /f/, and flair extraction.
Post Form Flash Tag UI & Publishing
src/components/post-form/post-form.tsx, src/components/post-form/__tests__/post-form.test.tsx, src/components/post-flash-tag.tsx, src/components/post-desktop/post-desktop.tsx, src/components/post-mobile/post-mobile.tsx
Post form integrates flash tag selector dropdown (conditional on flash directory), displays post_form_flash_upload_prompt guidance, and merges flash-tag flairs with flag flairs during publish. PostFlashTag component displays selected tag in post headers (both desktop and mobile). Tests verify UI presence, tag selection, flair publishing, and omission when no tag selected.
Flash Board Table & Directory Detection
src/components/flash-board-table/flash-board-table.tsx, src/components/flash-board-table/flash-board-table.module.css, src/views/board/board.tsx, src/views/board/__tests__/board.test.tsx
FlashBoardTable component renders flash posts in a table (rows with thread links, file embeds, tag/subject/date/reply cells). Board view detects flash directories via isFlashDirectory, disables infinite scroll in flash mode, and conditionally renders FlashBoardTable. CSS defines table layout, header/cell styling with theme-aware overrides (yotsuba, futaba, tomorrow, photon, etc.). Tests verify table rendering, empty/loading states, and row cell content.
Directory Sync, Rules Support & /f/ Bootstrap
scripts/sync-directories.js, src/lib/utils/directory-list-utils.ts, src/lib/utils/__tests__/directory-list-utils.test.ts, src/data/5chan-directory-lists.json, src/hooks/__tests__/use-directories.test.tsx
Directory-list-utils extends DirectoryList interface with optional rules: string[]. Sync script defines FLASH_DIRECTORY_RULES and bootstraps a /f/ directory with full metadata, features (requirePostFlairs: true), rules, and flash-posting.bso board. Directory code order updated to place f after a. Normalization helpers sanitize and propagate rules across entries. Tests verify sorting and rules preservation.
File Upload & Media Classification for SWF
android/app/src/main/java/fivechan/android/FileUploaderPlugin.java, src/hooks/use-file-upload.ts, src/hooks/__tests__/use-file-upload.test.ts, electron/media-upload-automation.js, electron/media-upload-automation.test.js, src/lib/media-hosting/direct-url.ts, src/lib/media-hosting/__tests__/direct-url.test.ts
Android FileUploaderPlugin MIME type allowlist expanded to include Flash types. File picker input configured to accept .swf and flash MIME types. Direct media URL classification adds .swf extension. Media upload automation adds .gifv extension. Tests validate SWF/GIFV recognition in upload flows.
Comment Media SWF Rendering & Mocking
src/components/comment-media/comment-media.tsx, src/components/comment-media/comment-media.module.css, src/components/comment-media/__tests__/comment-media.test.tsx
CommentMedia component adds SWF placeholder button and RufflePlayer rendering (conditional on media type). Placeholder styling includes hover effects. Tests mock Ruffle runtime via window.RufflePlayer, verify collapsed/expanded SWF rendering, and validate Ruffle load configuration (networking allowed, autoplay off, script access disabled, openUrlMode confirm).

Localization: Flash Upload Prompts & Tags

Layer / File(s) Summary
Flash-related UI Translations
public/translations/*/default.json (36 locales: ar, bn, cs, da, de, el, en, es, fa, fi, fil, fr, he, hi, hu, id, it, ja, ko, mr, nl, no, pl, pt, ro, ru, sq, sv, te, th, tr, uk, ur, vi, zh)
Each locale file extended with tag label and post_form_flash_upload_prompt guidance message. Content consistent across languages with Catbox SWF host recommendation, direct HTTPS .swf URL requirement, and CORS-enabled host note.

Build Configuration & Component Styling

Layer / File(s) Summary
Vite Ruffle Runtime Plugin
vite.config.js
Implements custom Vite plugin to enumerate @ruffle-rs/ruffle runtime assets, serve them at /ruffle/ during development via middleware, and emit them into build output. Resolves publicPath during Ruffle component initialization.
CSS: Flash Tag & Post View Styling
src/views/post/post.module.css
Adds .flashTag CSS class with font-weight: bold for flash tag display in post headers.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • bitsocialnet/5chan#1134: Modifies directory-list syncing and normalization pipeline (scripts/sync-directories.js, directory code ordering, normalization logic); main PR's directory sync changes for /f/ bootstrap and rules support overlap with that PR's refactoring.

  • bitsocialnet/5chan#1143: Both PRs modify src/components/comment-media/comment-media.tsx for media rendering; main PR adds SWF/RufflePlayer support while that PR refactors thumbnail/media UI markup to semantic HTML.

Poem

🐇 A flash of Ruffle springs to life,
As .swf files play without strife—
The /f/ board stands proud and tall,
With tags and threads for one and all!
Now thirty-six tongues sing along,
While Catbox hosts the Flash-y throng.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely describes the main feature added: SWF posting support for the flash board. It directly summarizes the primary change across the entire changeset.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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/flash-board-swf

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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 and usage tips.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

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 and found 3 potential issues.

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 1590558. Configure here.

Comment thread src/components/comment-media/ruffle-player.tsx
Comment thread src/components/flash-board-table/flash-board-table.tsx
Comment thread scripts/sync-directories.js
@tomcasaburi
Copy link
Copy Markdown
Member Author

Addressed the valid Cursor Bugbot findings in c6920e3: separated the Ruffle imperative mount node from React-owned status UI, kept the flash table in a loading state until empty feeds finish syncing, and made directory sync preserve bootstrap entries for both local and GitHub sources. Local verification passed: install, lint, type-check, focused tests, full test suite, build, knip, React Doctor, and Chrome/Firefox/WebKit desktop+mobile table checks. No remaining review findings are being deferred.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

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

⚠️ Outside diff range comments (1)
src/views/board/board.tsx (1)

645-661: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid rendering two loading indicators for empty flash boards.

This branch shows a loading row inside FlashBoardTable, but it also renders the shared footer immediately afterward. With the current footer props, an empty /f/ board will show a second LoadingEllipsis below the table while syncing.

🤖 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/views/board/board.tsx` around lines 645 - 661, The footer is rendered
even when FlashBoardTable is showing its loading row, causing duplicate loading
indicators; update the render logic so footerComponents.Footer is only rendered
when not in the empty-flash loading state (use shouldShowFlashTableLoading or
displayFeed.length to decide). Specifically, when shouldUseFlashTable is true,
render FlashBoardTable with isLoading={shouldShowFlashTableLoading} but
conditionally render footerComponents.Footer only if
!shouldShowFlashTableLoading (or displayFeed.length > 0 / feed has succeeded) to
prevent the extra LoadingEllipsis for empty /f/ boards.
🟡 Minor comments (37)
public/translations/de/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Untranslated German entries in newly added keys

The new tag and post_form_flash_upload_prompt strings are English, so the German UI becomes mixed-language in the post form flow. Please localize these values.

🤖 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 `@public/translations/de/default.json` around lines 401 - 402, The two new keys
"tag" and "post_form_flash_upload_prompt" are still in English; update their
values to German translations—replace "tag" with the appropriate German term
(e.g., "Schlagwort" or "Tag") and translate the entire
"post_form_flash_upload_prompt" string into German keeping placeholders like
<catbox>Catbox</catbox> and the example URL intact so the message reads
naturally in German for the post form flow.
public/translations/ar/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize newly added strings in this locale

The new tag label and post_form_flash_upload_prompt are still in English, so Arabic users will see mixed-language UI in the posting flow. Please provide Arabic translations (or intentionally omit the keys to rely on fallback behavior consistently).

🤖 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 `@public/translations/ar/default.json` around lines 401 - 402, Translate the
two new keys "tag" and "post_form_flash_upload_prompt" into Arabic or remove
them to rely on fallback; specifically update the "tag" value with an Arabic
label (e.g., "علامة") and localize "post_form_flash_upload_prompt" to an Arabic
sentence that conveys the same instructions about Catbox, .swf upload and
requiring a direct HTTPS .swf URL with CORS enabled so Arabic users see a
consistent posting flow.
public/translations/bn/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

New Bengali keys are not translated yet

tag and post_form_flash_upload_prompt are added as English text, which causes mixed-language UI for Bengali users. Please localize these two strings (or omit them and rely on fallback intentionally).

🤖 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 `@public/translations/bn/default.json` around lines 401 - 402, The keys "tag"
and "post_form_flash_upload_prompt" in the Bengali translations are still in
English; replace those values with proper Bengali translations (or remove the
entries to rely on fallback if intentional). For "post_form_flash_upload_prompt"
keep the <catbox> tag wrapper and the example URL text/HTTPS mention intact
while translating surrounding text into Bengali, and ensure you preserve any
punctuation, URL examples, and CORS note so the meaning stays the same.
public/translations/el/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Greek translations are missing for new flash-posting keys

tag and post_form_flash_upload_prompt are currently English strings. Please provide Greek translations to keep the post form localized.

🤖 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 `@public/translations/el/default.json` around lines 401 - 402, Replace the
English values for the JSON keys "tag" and "post_form_flash_upload_prompt" with
their Greek translations; update "tag" to the Greek word for tag (e.g.,
"ετικέτα") and translate the full prompt for "post_form_flash_upload_prompt"
into Greek while preserving the embedded <catbox> tag and the direct
https://...swf URL text and escaping/quoting so the JSON stays valid.
public/translations/es/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Spanish locale has untranslated new keys

tag and post_form_flash_upload_prompt are currently English. Please translate both to Spanish so the flash posting flow remains fully localized.

🤖 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 `@public/translations/es/default.json` around lines 401 - 402, The JSON keys
"tag" and "post_form_flash_upload_prompt" are still in English; update their
values in public/translations/es/default.json to Spanish: change "tag" to
"etiqueta" (or appropriate short form) and replace the long prompt value for
"post_form_flash_upload_prompt" with a Spanish translation that preserves the
HTML tag <catbox>Catbox</catbox> and the instruction about uploading a .swf and
pasting the direct HTTPS URL with CORS enabled (e.g., "Host recomendado para
SWF: <catbox>Catbox</catbox>. Sube un .swf y luego pega el enlace directo HTTPS
https://files.catbox.moe/...swf en Enlace. Otros hosts deben ofrecer una URL
.swf directa por HTTPS con CORS habilitado.").
public/translations/da/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Danish locale currently contains English for new keys

tag and post_form_flash_upload_prompt were added but left in English. Please translate them to Danish to avoid mixed-language UX in posting.

🤖 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 `@public/translations/da/default.json` around lines 401 - 402, Replace the
English strings for the translation keys "tag" and
"post_form_flash_upload_prompt" with Danish text so the locale is fully
translated; update the value for "tag" to "etiket" and translate the upload
prompt string to Danish (e.g., something like: "Anbefalet SWF-host:
<catbox>Catbox</catbox>. Upload en .swf, og indsæt derefter det direkte
https://files.catbox.moe/...swf-link i Link. Andre hosts skal levere en direkte
HTTPS .swf-URL med CORS aktiveret."). Ensure you edit the values for the keys
"tag" and "post_form_flash_upload_prompt" only.
public/translations/cs/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Please translate the new Czech keys

The added tag and post_form_flash_upload_prompt entries are still English. This introduces mixed-language UI in the Czech post form flow.

🤖 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 `@public/translations/cs/default.json` around lines 401 - 402, Replace the two
English values with Czech translations: set "tag" to "štítek" and set
"post_form_flash_upload_prompt" to a Czech prompt such as "Doporučený hostitel
SWF: <catbox>Catbox</catbox>. Nahrajte soubor .swf a poté vložte přímý odkaz
https://files.catbox.moe/...swf do pole Odkaz. Ostatní hostitele musí poskytovat
přímou HTTPS .swf URL s povoleným CORS." Update the values for the keys "tag"
and "post_form_flash_upload_prompt" accordingly.
public/translations/fil/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new entries in the Filipino translation file.

tag and post_form_flash_upload_prompt are currently English-only, causing mixed-language UX in this locale.

🤖 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 `@public/translations/fil/default.json` around lines 401 - 402, Translate the
two untranslated keys in the Filipino JSON: replace the English values for "tag"
and "post_form_flash_upload_prompt" with appropriate Filipino translations while
preserving markup and placeholders (keep "<catbox>Catbox</catbox>" and the URL
example intact) so the keys "tag" and "post_form_flash_upload_prompt" in
public/translations/fil/default.json return fully localized Filipino strings.
public/translations/hi/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the added Flash text for Hindi.

tag and post_form_flash_upload_prompt are still English, which causes mixed-language UI for Hindi users.

🤖 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 `@public/translations/hi/default.json` around lines 401 - 402, The Hindi
translation file still contains English text for the keys "tag" and
"post_form_flash_upload_prompt"; update those entries ("tag" and
"post_form_flash_upload_prompt") with proper Hindi translations (and preserve
any HTML tags like <catbox> and the URL format/HTTPS requirement and CORS note)
so the UI is fully localized for Hindi users.
public/translations/fa/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the newly added strings for this locale.

tag and post_form_flash_upload_prompt are still English in the Persian file, so users will see mixed-language UI in the new Flash posting flow.

🤖 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 `@public/translations/fa/default.json` around lines 401 - 402, The two new keys
"tag" and "post_form_flash_upload_prompt" are left in English in the Persian
translation file; replace their values with proper Persian translations:
translate the "tag" label and localize the "post_form_flash_upload_prompt"
string (preserving the <catbox>...</catbox> tag and the example HTTPS SWF URL)
so the UI shows fully localized Persian text for the Flash posting flow.
public/translations/hu/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate new SWF-related strings in Hungarian.

tag and post_form_flash_upload_prompt remain English in this locale file, resulting in mixed-language content.

🤖 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 `@public/translations/hu/default.json` around lines 401 - 402, The keys "tag"
and "post_form_flash_upload_prompt" in the Hungarian locale are still in
English; translate both to Hungarian while preserving any inline markup and URL
placeholders (e.g., keep the <catbox>...</catbox> tag, the
https://files.catbox.moe/...swf pattern, and the .swf extension intact) so
update the "tag" value to the Hungarian equivalent and replace the
"post_form_flash_upload_prompt" string with a grammatically correct Hungarian
translation that retains the same structure and placeholders.
public/translations/id/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new keys in the Indonesian locale file.

tag and post_form_flash_upload_prompt are English-only right now, creating inconsistent Indonesian UI text.

🤖 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 `@public/translations/id/default.json` around lines 401 - 402, Replace the
English-only values for the JSON keys "tag" and "post_form_flash_upload_prompt"
with Indonesian translations: change "tag" to the Indonesian equivalent (e.g.,
"tag" -> "tag" or "label" -> "label" as appropriate) and translate the entire
sentence for "post_form_flash_upload_prompt" into fluent Indonesian while
preserving the <catbox>...</catbox> inline tag, the example URL pattern
(https://files.catbox.moe/...swf), the ".swf" file extension, "HTTPS" and "CORS"
technical terms, and the instruction structure so the message remains
functionally identical but in Indonesian.
public/translations/he/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Provide Hebrew translations for the new Flash keys.

The new tag and post_form_flash_upload_prompt values are English, so Hebrew users will see inconsistent language.

🤖 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 `@public/translations/he/default.json` around lines 401 - 402, Replace the
English values for the translation keys "tag" and
"post_form_flash_upload_prompt" with Hebrew translations so the UI is consistent
for Hebrew users; update the "tag" value to a concise Hebrew word such as "תג"
and replace "post_form_flash_upload_prompt" with a Hebrew sentence that conveys
the same instructions, e.g. "מארח SWF מומלץ: <catbox>Catbox</catbox>. העלה קובץ
.swf, ולאחר מכן הדבק את הקישור הישיר HTTPS https://files.catbox.moe/...swf בשדה
הקישור. מארחים אחרים חייבים לספק קובץ .swf ישיר דרך HTTPS עם CORS מופעל.",
keeping the existing <catbox> tag intact and ensuring punctuation and
placeholders remain unchanged.
public/translations/fr/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the newly added keys in the French locale.

tag and post_form_flash_upload_prompt are still English, which introduces mixed-language UI text.

🤖 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 `@public/translations/fr/default.json` around lines 401 - 402, Translate the
two English localization keys into French: replace the "tag" value with the
French equivalent (e.g., "étiquette" or "tag" depending on existing glossary)
and translate "post_form_flash_upload_prompt" into natural French while
preserving the embedded <catbox> tag, the example URL
https://files.catbox.moe/...swf, and the instruction about HTTPS and CORS;
update the values for keys "tag" and "post_form_flash_upload_prompt" accordingly
in the locale JSON.
public/translations/fi/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new Flash strings to Finnish.

Both tag and post_form_flash_upload_prompt are in English, which breaks locale consistency for Finnish users.

🤖 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 `@public/translations/fi/default.json` around lines 401 - 402, The two
translation keys "tag" and "post_form_flash_upload_prompt" are still in English;
update their Finnish values so locale is consistent: set "tag" to "tunniste" and
replace the English sentence in "post_form_flash_upload_prompt" with a Finnish
translation that preserves the <catbox>...</catbox> inline tag, the example
direct https://files.catbox.moe/...swf URL, the .swf extension, HTTPS mention,
and the CORS requirement (e.g., "Suositeltu SWF-isäntä: <catbox>Catbox</catbox>.
Lataa .swf-tiedosto ja liitä suora https://files.catbox.moe/...swf-linkki
Link-kenttään. Muihin isäntiin vaaditaan suora HTTPS .swf-URL ja
CORS-otsakkeet."). Ensure punctuation and markup remain intact.
public/translations/ko/default.json-402-402 (1)

402-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the flash upload prompt for Korean users.

Line 402 is not translated, so this feature text will appear in English under the Korean locale.

🤖 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 `@public/translations/ko/default.json` at line 402, The Korean locale is
missing a translation for the key "post_form_flash_upload_prompt"; replace the
English string with a Korean translation while preserving the embedded
<catbox>...</catbox> tag, the .swf extension, and the sample HTTPS URL pattern
(https://files.catbox.moe/...swf) exactly as-is so formatting/CORS instructions
remain intact.
public/translations/nl/default.json-402-402 (1)

402-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize flash upload instructions in Dutch.

Line 402 is currently English, so Dutch users will get mixed-language UX for upload guidance.

🤖 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 `@public/translations/nl/default.json` at line 402, The translation key
"post_form_flash_upload_prompt" currently contains English text; replace its
value with a Dutch translation so Dutch users see localized upload guidance.
Locate the "post_form_flash_upload_prompt" entry and update the string to a
Dutch sentence that conveys the same instructions (e.g., "Aanbevolen SWF-host:
<catbox>Catbox</catbox>. Upload een .swf en plak vervolgens de directe
https://files.catbox.moe/...swf-link in Link. Andere hosts moeten een directe
HTTPS .swf-URL met CORS ingeschakeld bieden."). Ensure the key name remains
unchanged and only the value is updated.
public/translations/ja/default.json-402-402 (1)

402-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new SWF upload guidance in the Japanese locale.

Line 402 is English-only and breaks locale consistency for users on Japanese.

🤖 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 `@public/translations/ja/default.json` at line 402, Replace the English value
for the "post_form_flash_upload_prompt" translation with a Japanese translation
that preserves meaning and placeholders (e.g., "<catbox>Catbox</catbox>" and the
example URL pattern), ensuring it informs users to upload a .swf to Catbox and
paste the direct HTTPS .swf link with CORS; update the value of the
"post_form_flash_upload_prompt" key in the JSON so the Japanese locale displays
the translated guidance.
public/translations/pt/default.json-402-402 (1)

402-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the SWF upload prompt in Portuguese locale.

Line 402 is English-only and should be localized for a consistent Portuguese UX.

🤖 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 `@public/translations/pt/default.json` at line 402, The English string for
"post_form_flash_upload_prompt" needs to be translated into Portuguese in
public/translations/pt/default.json; update the value of the key
"post_form_flash_upload_prompt" with a Portuguese translation that preserves the
<catbox>Catbox</catbox> tag, the example direct https://files.catbox.moe/...swf
URL, and the note about requiring a direct HTTPS .swf URL with CORS enabled so
the UX remains identical but localized.
public/translations/pl/default.json-402-402 (1)

402-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the flash upload guidance for Polish users.

Line 402 is still in English, causing mixed-language content in the Polish locale.

🤖 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 `@public/translations/pl/default.json` at line 402, The key
"post_form_flash_upload_prompt" contains English text; replace it with a Polish
translation while preserving the embedded <catbox> tag, the example HTTPS URL
format (https://files.catbox.moe/...swf) and the CORS note. For example, update
the value to a Polish sentence conveying: recommended SWF host Catbox, upload a
.swf and paste the direct HTTPS files.catbox.moe/...swf link into "Link", and
that other hosts must provide a direct HTTPS .swf URL with CORS enabled.
public/translations/no/default.json-402-402 (1)

402-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the SWF upload prompt in Norwegian locale.

Line 402 is English and should be localized to keep Norwegian UI consistent.

🤖 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 `@public/translations/no/default.json` at line 402, The JSON value for the key
"post_form_flash_upload_prompt" is still in English; replace it with a Norwegian
translation while preserving the inline tag <catbox> and the example HTTPS URL
and .swf mention; for example translate to: "Anbefalt SWF-vert:
<catbox>Catbox</catbox>. Last opp en .swf-fil, og lim deretter den direkte
HTTPS-lenken (https://files.catbox.moe/...swf) inn i Feltet for lenke. Andre
verter må gi en direkte HTTPS .swf-URL med CORS aktivert." Ensure you update the
value only (keep the JSON key intact) and maintain any punctuation and
placeholders exactly as in the original.
public/translations/it/default.json-402-402 (1)

402-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new flash upload prompt for Italian UI.

Line 402 is still English, so Italian users will see mixed-language UX for this new feature.

🤖 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 `@public/translations/it/default.json` at line 402, Replace the English value
for the translation key "post_form_flash_upload_prompt" in
public/translations/it/default.json with an Italian localized string so Italian
users see a fully localized UI; update the value for
"post_form_flash_upload_prompt" to a natural Italian translation (e.g. "Host SWF
consigliato: <catbox>Catbox</catbox>. Carica un .swf, quindi incolla il link
diretto HTTPS https://files.catbox.moe/...swf nel campo Link. Altri host devono
fornire un URL .swf diretto via HTTPS con CORS abilitato.") ensuring the
placeholder <catbox> remains unchanged.
public/translations/mr/default.json-402-402 (1)

402-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new SWF upload prompt in Marathi locale.

Line 402 remains English, which creates inconsistent localization in Marathi UI.

🤖 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 `@public/translations/mr/default.json` at line 402, Replace the English string
value for the JSON key "post_form_flash_upload_prompt" in the Marathi locale
with a proper Marathi translation; update the value to something like: "शिफारस
केलेला SWF होस्ट: Catbox. .swf फाइल अपलोड करा, नंतर Link मध्ये थेट
https://files.catbox.moe/...swf असा HTTPS लिंक पेस्ट करा. इतर होस्टसाठी CORS
सक्षम असलेला थेट HTTPS .swf URL आवश्यक आहे." ensuring the key
"post_form_flash_upload_prompt" remains unchanged.
public/translations/te/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new flash-posting strings.

tag and post_form_flash_upload_prompt are still in English in this Telugu locale file. That ships a mixed-language posting flow and makes missing translations harder to spot later because the keys now look populated.

🤖 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 `@public/translations/te/default.json` around lines 401 - 402, The Telugu
locale file still has untranslated English strings for the keys "tag" and
"post_form_flash_upload_prompt"; update public/translations/te/default.json by
replacing the values for "tag" and "post_form_flash_upload_prompt" with proper
Telugu translations (preserve any inline markup like <catbox> and the URL
example), ensuring the translated text conveys the same meaning and formatting
so the posting flow is fully localized.
public/translations/uk/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new flash-posting strings.

tag and post_form_flash_upload_prompt are still in English in this Ukrainian locale file. That ships a mixed-language posting flow and makes missing translations harder to spot later because the keys now look populated.

🤖 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 `@public/translations/uk/default.json` around lines 401 - 402, Translate the
two English values into Ukrainian: replace the value for the "tag" key and the
value for "post_form_flash_upload_prompt" with proper Ukrainian translations so
the locale file is fully localized; update the string for "tag" (the label) and
the long prompt text for "post_form_flash_upload_prompt" (the Catbox
recommendation and upload instructions) preserving any tags like <catbox> and
any URL/example fragments.
public/translations/ru/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new flash-posting strings.

tag and post_form_flash_upload_prompt are still in English in this Russian locale file. That ships a mixed-language posting flow and makes missing translations harder to spot later because the keys now look populated.

🤖 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 `@public/translations/ru/default.json` around lines 401 - 402, The two
translation keys "tag" and "post_form_flash_upload_prompt" are still in English;
update their values in this locale file by replacing the English strings with
proper Russian translations while preserving markup/URL parts (keep the
<catbox>Catbox</catbox> tag and the example HTTPS .swf link format intact) so
the posting flow is fully localized; edit the values for "tag" and
"post_form_flash_upload_prompt" accordingly in the JSON.
public/translations/sq/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new flash-posting strings.

tag and post_form_flash_upload_prompt are still in English in this Albanian locale file. That ships a mixed-language posting flow and makes missing translations harder to spot later because the keys now look populated.

🤖 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 `@public/translations/sq/default.json` around lines 401 - 402, Replace the
English values for the translation keys "tag" and
"post_form_flash_upload_prompt" with their Albanian equivalents so the posting
flow is fully localized; for "post_form_flash_upload_prompt" preserve the inline
<catbox>...</catbox> tag, the example HTTPS .swf URL, and any
punctuation/formatting while translating the surrounding text into Albanian
(ensure the .swf and URL remain unchanged and CORS wording is conveyed
appropriately).
public/translations/tr/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new flash-posting strings.

tag and post_form_flash_upload_prompt are still in English in this Turkish locale file. That ships a mixed-language posting flow and makes missing translations harder to spot later because the keys now look populated.

🤖 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 `@public/translations/tr/default.json` around lines 401 - 402, The Turkish
locale has two untranslated values: the "tag" key and
"post_form_flash_upload_prompt" key; replace their English values with proper
Turkish translations while leaving the JSON keys, surrounding punctuation, and
embedded markup/URLs intact (preserve the <catbox>...</catbox> tag and the
example https://files.catbox.moe/...swf snippet). Update "tag" to the Turkish
equivalent (e.g., "etiket") and provide a natural Turkish translation for
"post_form_flash_upload_prompt" that conveys the same instructions and retains
the direct HTTPS .swf and CORS wording/formatting.
public/translations/th/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new flash-posting strings.

tag and post_form_flash_upload_prompt are still in English in this Thai locale file. That ships a mixed-language posting flow and makes missing translations harder to spot later because the keys now look populated.

🤖 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 `@public/translations/th/default.json` around lines 401 - 402, The locale
entries "tag" and "post_form_flash_upload_prompt" are left in English; replace
their values with Thai translations while preserving any markup and URLs (e.g.,
keep the <catbox>...</catbox> tag and the https://... link intact). Update the
"tag" string to the Thai equivalent for "tag" and translate the full
"post_form_flash_upload_prompt" message into natural Thai, ensuring CORS/HTTPS
phrasing and host instructions remain clear.
public/translations/sv/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new flash-posting strings.

tag and post_form_flash_upload_prompt are still in English in this Swedish locale file. That ships a mixed-language posting flow and makes missing translations harder to spot later because the keys now look populated.

🤖 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 `@public/translations/sv/default.json` around lines 401 - 402, The keys "tag"
and "post_form_flash_upload_prompt" in the Swedish locale still contain English;
replace their values with proper Swedish translations while preserving any
inline markup/tags (e.g., the <catbox>Catbox</catbox> element) and the HTTPS
example URL format so interpolation/HTML remains intact; update the "tag" value
to the Swedish word (e.g., "tagg") and translate the sentence in
"post_form_flash_upload_prompt" to fluent Swedish, keeping the direct link
example and CORS note unchanged.
public/translations/ro/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the new flash-posting strings.

tag and post_form_flash_upload_prompt are still in English in this Romanian locale file. That ships a mixed-language posting flow and makes missing translations harder to spot later because the keys now look populated.

🤖 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 `@public/translations/ro/default.json` around lines 401 - 402, Translate the
two English strings for the locale keys "tag" and
"post_form_flash_upload_prompt" into Romanian, preserving any markup and URLs
(keep the <catbox>...</catbox> tag and the example
https://files.catbox.moe/...swf intact); update the values for the "tag" and
"post_form_flash_upload_prompt" entries so the posting flow is fully localized
and keys remain populated with correct Romanian text.
public/translations/ur/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize new Urdu strings instead of shipping English placeholders.

"tag" and "post_form_flash_upload_prompt" are still English in the Urdu locale file, which will surface mixed-language UI in /f/ posting flows. Please translate both values while preserving placeholders/markup (<catbox>...</catbox>, URL, .swf, CORS, HTTPS).

🤖 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 `@public/translations/ur/default.json` around lines 401 - 402, Translate the
two Urdu locale strings: replace the English value for the "tag" key with the
appropriate Urdu word for "tag" and translate the
"post_form_flash_upload_prompt" value into Urdu while preserving the inline
markup and technical tokens exactly as-is (keep the <catbox>...</catbox> tag,
the example URL pattern https://files.catbox.moe/...swf, the file extension
.swf, and the acronyms CORS and HTTPS unchanged).
public/translations/zh/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add Chinese localization for the newly introduced flash strings.

"tag" and "post_form_flash_upload_prompt" are still English, creating inconsistent UX in zh locale. Please translate both and keep structured tokens intact (<catbox>...</catbox>, URL, .swf, HTTPS, CORS).

🤖 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 `@public/translations/zh/default.json` around lines 401 - 402, Translate the
two untranslated keys "tag" and "post_form_flash_upload_prompt" in the zh locale
JSON to Chinese while preserving embedded tokens exactly as-is (keep the
<catbox>...</catbox> tag, the example URL pattern, ".swf", "HTTPS", and "CORS"
unchanged); update the values for the "tag" key and the
"post_form_flash_upload_prompt" key to natural Chinese phrasing that maintains
those tokens and the original meaning about recommended host and direct HTTPS
.swf links with CORS enabled.
public/translations/vi/default.json-401-402 (1)

401-402: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Translate the new Vietnamese keys to avoid mixed-language UI.

Both new entries are currently English. Please localize "tag" and "post_form_flash_upload_prompt" in Vietnamese, keeping the technical tokens/markup unchanged (<catbox>, URL, .swf, HTTPS, CORS).

🤖 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 `@public/translations/vi/default.json` around lines 401 - 402, The two
translation values for keys "tag" and "post_form_flash_upload_prompt" are still
in English—replace "tag" with the Vietnamese "thẻ" and localize
"post_form_flash_upload_prompt" to Vietnamese (e.g. "Máy chủ SWF được khuyến
nghị: <catbox>Catbox</catbox>. Tải lên tệp .swf, sau đó dán đường dẫn trực tiếp
HTTPS như https://files.catbox.moe/...swf vào trường Link. Các host khác phải
cung cấp URL .swf trực tiếp qua HTTPS với CORS được bật.") making sure to keep
the technical tokens/markup exactly as-is (<catbox>, the example URL, .swf,
HTTPS, CORS) and update the JSON values for the "tag" and
"post_form_flash_upload_prompt" keys.
src/components/comment-media/comment-media.module.css-150-168 (1)

150-168: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a visible focus state for the new [SWF] button.

.swfPlaceholder is interactive, but this selector only defines default and hover styles. Keyboard users won't get a visible focus indicator on the collapsed SWF control. Please mirror the existing .mediaToggleButton:focus-visible treatment here.

🤖 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/components/comment-media/comment-media.module.css` around lines 150 -
168, The .swfPlaceholder interactive element lacks a keyboard focus indicator;
add a :focus-visible rule for .swfPlaceholder mirroring the existing
.mediaToggleButton:focus-visible treatment (same outline/color/box-shadow and
border-radius/offsets) so keyboard users see a visible focus state when the
collapsed SWF control receives focus; update the CSS to include
.swfPlaceholder:focus-visible with the same visual properties used by
.mediaToggleButton:focus-visible.
electron/media-upload-automation.js-17-17 (1)

17-17: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep SWF detection consistent between extension list and extraction regex.

You added .swf to DIRECT_MEDIA_EXTENSIONS (Line 17), but hasMediaExtension inside extractUrl (Line 191) still omits swf. This can miss SWF URLs when they appear inside extracted text blocks, leading to false upload timeouts.

Proposed fix
-          function hasMediaExtension(url) {
-            return /\\.(?:jpe?g|png|gif|webp|bmp|avif|mp4|webm|mov|avi|mkv|gifv)(?:[?#].*)?$/i.test(url);
-          }
+          function hasMediaExtension(url) {
+            return /\\.(?:jpe?g|png|gif|webp|bmp|avif|mp4|webm|mov|avi|mkv|gifv|swf)(?:[?#].*)?$/i.test(url);
+          }
🤖 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 `@electron/media-upload-automation.js` at line 17, The DIRECT_MEDIA_EXTENSIONS
array includes '.swf' but the hasMediaExtension check in
extractUrl/hasMediaExtension still omits 'swf', causing SWF URLs to be missed;
update the hasMediaExtension logic used by extractUrl (or its regex) to include
'swf' (match .swf case-insensitively) so the extension list and extraction
regex/validator are consistent (refer to DIRECT_MEDIA_EXTENSIONS and the
extractUrl/hasMediaExtension functions).
src/components/flash-board-table/flash-board-table.tsx-61-63 (1)

61-63: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Route the remaining table copy through i18n.

No. and no posts are still hard-coded, so /f/ falls back to English for those cells even though the rest of the table uses t(...). Please reuse an existing key or add dedicated translation keys for these labels.

Also applies to: 95-99

🤖 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/components/flash-board-table/flash-board-table.tsx` around lines 61 - 63,
The table header "No." and the empty-state cell "no posts" are hard-coded in the
FlashBoardTable component (look for the <th className={styles.postblock}> and
the branch rendering when posts.length === 0); replace these strings with i18n
calls (e.g., t('...')) using existing translation keys if available or add new
keys like "table.column.number" and "table.empty.noPosts", then use
t('table.column.number') for the header and t('table.empty.noPosts') for the
empty-state cell so all table copy is routed through i18n.
🧹 Nitpick comments (1)
src/views/board/__tests__/board.test.tsx (1)

551-663: ⚡ Quick win

Add the direct-address flash-board case too.

These tests cover /f, but the new production branch also enables the flash table when the board is opened by resolved address (isFlashDirectory(communityDirectory)). A case like /flash-posting.bso would protect the second path this change introduced.

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

🤖 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/views/board/__tests__/board.test.tsx` around lines 551 - 663, The added
tests only exercise the `/f` path; add duplicate cases that open the board by
its resolved address (e.g., initialEntry '/flash-posting.bso') to cover the new
branch that enables the flash table via isFlashDirectory(communityDirectory).
For each of the three specs (renders flash rows, renders empty flash table,
keeps loading until sync) replicate the setup but call renderBoard with
initialEntry '/flash-posting.bso' (keeping routePath '/:boardIdentifier/*'),
ensure testState.resolvedCommunityAddress and testState.community.shortAddress
are 'flash-posting.bso', and assert the same DOM queries (`#flash-list`,
[data-testid="post"], [data-testid="loading-ellipsis"], text expectations and
absence of load_more) so the direct-address flash-board path is tested.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a5048b56-68e2-4975-9489-b85b5680a680

📥 Commits

Reviewing files that changed from the base of the PR and between 5689470 and c6920e3.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (68)
  • android/app/src/main/java/fivechan/android/FileUploaderPlugin.java
  • electron/media-upload-automation.js
  • electron/media-upload-automation.test.js
  • package.json
  • public/translations/ar/default.json
  • public/translations/bn/default.json
  • public/translations/cs/default.json
  • public/translations/da/default.json
  • public/translations/de/default.json
  • public/translations/el/default.json
  • public/translations/en/default.json
  • public/translations/es/default.json
  • public/translations/fa/default.json
  • public/translations/fi/default.json
  • public/translations/fil/default.json
  • public/translations/fr/default.json
  • public/translations/he/default.json
  • public/translations/hi/default.json
  • public/translations/hu/default.json
  • public/translations/id/default.json
  • public/translations/it/default.json
  • public/translations/ja/default.json
  • public/translations/ko/default.json
  • public/translations/mr/default.json
  • public/translations/nl/default.json
  • public/translations/no/default.json
  • public/translations/pl/default.json
  • public/translations/pt/default.json
  • public/translations/ro/default.json
  • public/translations/ru/default.json
  • public/translations/sq/default.json
  • public/translations/sv/default.json
  • public/translations/te/default.json
  • public/translations/th/default.json
  • public/translations/tr/default.json
  • public/translations/uk/default.json
  • public/translations/ur/default.json
  • public/translations/vi/default.json
  • public/translations/zh/default.json
  • scripts/sync-directories.js
  • src/components/comment-media/__tests__/comment-media.test.tsx
  • src/components/comment-media/comment-media.module.css
  • src/components/comment-media/comment-media.tsx
  • src/components/comment-media/ruffle-player.tsx
  • src/components/flash-board-table/flash-board-table.module.css
  • src/components/flash-board-table/flash-board-table.tsx
  • src/components/post-desktop/post-desktop.tsx
  • src/components/post-flash-tag.tsx
  • src/components/post-form/__tests__/post-form.test.tsx
  • src/components/post-form/post-form.tsx
  • src/components/post-mobile/post-mobile.tsx
  • src/data/5chan-directory-lists.json
  • src/hooks/__tests__/use-directories.test.tsx
  • src/hooks/__tests__/use-file-upload.test.ts
  • src/hooks/use-file-upload.ts
  • src/lib/__tests__/flash-tags.test.ts
  • src/lib/flash-tags.ts
  • src/lib/media-hosting/__tests__/direct-url.test.ts
  • src/lib/media-hosting/direct-url.ts
  • src/lib/utils/__tests__/directory-list-utils.test.ts
  • src/lib/utils/__tests__/media-utils.test.ts
  • src/lib/utils/directory-list-utils.ts
  • src/lib/utils/media-utils.ts
  • src/types/ruffle.d.ts
  • src/views/board/__tests__/board.test.tsx
  • src/views/board/board.tsx
  • src/views/post/post.module.css
  • vite.config.js

Comment on lines 160 to +166
const features = normalizeFeatures(raw.features);
const rules = normalizeRules(raw.rules);
return {
directoryCode: toString(raw.directoryCode) || code,
...(toString(raw.title) ? { title: toString(raw.title) } : {}),
...(features ? { features } : {}),
...(rules ? { rules } : {}),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Apply default-entry rules during list normalization.

normalizeDirectoryDefaultsEntry() now preserves rules, but normalizeDirectoryList() only reads raw.rules. That means any rules defined in 5chan-directories-defaults.json are silently dropped from the generated vendored data unless every directory duplicates them inline.

💡 Minimal fix
-  const rules = normalizeRules(raw.rules);
+  const rules = normalizeRules(defaultEntry?.rules) || normalizeRules(raw.rules);

Also applies to: 190-199

🤖 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 `@scripts/sync-directories.js` around lines 160 - 166, normalizeDirectoryList
is dropping rules coming from normalizeDirectoryDefaultsEntry because it uses
raw.rules instead of the normalized/merged rules variable; update the object
construction to use the computed rules (the result of normalizeRules(raw.rules)
or the merged value) just like features is handled — i.e., replace any
occurrence that reads raw.rules when assembling the return object with the
normalized rules variable (and do the same fix in the similar block around the
190-199 range) so rules preserved from defaults are included.

Comment on lines +40 to +42
interface RufflePlayerProps {
url: string;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pass media dimensions into the Ruffle player instead of hard-coding one viewport.

This component only accepts url, so the caller's linkWidth/linkHeight metadata is dropped. With the fixed wrapper size, every SWF renders as the same viewport, and on mobile it can shrink to 100% width while staying 480px tall. Please thread width/height or an aspect ratio into RufflePlayer and size the container from that data.

Also applies to: 110-123

🤖 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/components/comment-media/ruffle-player.tsx` around lines 40 - 42,
RufflePlayer currently only accepts url in RufflePlayerProps and hardcodes the
container size; update RufflePlayerProps to accept width and height (or a single
aspectRatio) and thread those props into the RufflePlayer component, then use
them to size the wrapper element (e.g., set inline styles or CSS class to apply
width:100% and height via aspect-ratio or computed percentage padding based on
width/height) so SWF instances use the caller's linkWidth/linkHeight metadata
instead of a fixed 480px height; update any callers to pass linkWidth/linkHeight
and adjust RufflePlayer rendering logic (RufflePlayer and its wrapper div) to
use these values.

Comment on lines 644 to +653
const flagPublishOptions = getCommentFlagPublishOptionsForDirectory(directoryEntry, flagRef.current?.value);
const flashTagPublishOptions = getFlashTagPublishOptionsForDirectoryCode(postOptionsDirectoryCode, flashTagRef.current?.value);
const flairs = mergeFlairs(flagPublishOptions.flairs, flashTagPublishOptions.flairs);
const publishOptions = {
...flagPublishOptions,
...(flairs ? { flairs } : {}),
};

nonokoRedirectPathRef.current = hasNonokoOption(currentOptions) ? getBoardIndexPath() : null;
publishPost({ content: publishContent, ...flagPublishOptions });
publishPost({ content: publishContent, ...publishOptions });
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Block /f/ thread publish when no flash tag is selected.

flashTagPublishOptions can be empty and publishPost() still runs. On /f/, the board is configured with requirePostFlairs: true, so this path lets new threads bypass the required-tag contract; the new test at Lines 763-780 in src/components/post-form/__tests__/post-form.test.tsx currently locks that behavior in.

🤖 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/components/post-form/post-form.tsx` around lines 644 - 653, The publish
path calls publishPost even when
getFlashTagPublishOptionsForDirectoryCode(postOptionsDirectoryCode,
flashTagRef.current?.value) returns empty, allowing threads on boards with
requirePostFlairs (e.g., /f/) to bypass required tags; update the logic around
publishPost to detect when flashTagPublishOptions is empty (or lacks flairs) and
the current directory requires flairs (use directoryEntry /
getCommentFlagPublishOptionsForDirectory or a requirePostFlairs flag), prevent
calling publishPost in that case and surface validation (e.g., block submission
or show an error) instead of proceeding; locate the code using
getFlashTagPublishOptionsForDirectoryCode, flashTagRef, publishPost,
hasNonokoOption and mergeFlairs to implement this guard.

Comment on lines 141 to 149
const directoryCode = toString(raw.directoryCode) ?? code;
const features = normalizeFeatures(raw.features);
const rules = normalizeRules(raw.rules);
return {
directoryCode,
...(toString(raw.title) ? { title: toString(raw.title)! } : {}),
...(features ? { features } : {}),
...(rules ? { rules } : {}),
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Default directory rules are still discarded at runtime.

This helper now parses defaultEntry.rules, but the normalized DirectoryList only uses raw.rules. Boards that rely on default-level rules will therefore lose them whenever the app normalizes fetched directory data.

💡 Minimal fix
-  const rules = normalizeRules(raw.rules);
+  const rules = normalizeRules(defaultEntry?.rules) ?? normalizeRules(raw.rules);

Also applies to: 232-242

🤖 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-utils.ts` around lines 141 - 149, The code
currently normalizes only raw.rules and discards any default-level rules; change
the rules computation to fall back to the directory's defaultEntry.rules (e.g.
const rules = normalizeRules(raw.rules ?? raw.defaultEntry?.rules)) so
normalized DirectoryList includes defaultEntry rules when raw.rules is missing,
and update the second occurrence (the block around lines 232-242) the same way;
keep directoryCode, features and title logic unchanged and continue using
normalizeRules, normalizeFeatures and toString as shown.

@tomcasaburi tomcasaburi merged commit 9b3a95d into master May 30, 2026
11 checks passed
@tomcasaburi tomcasaburi deleted the codex/feature/flash-board-swf branch May 30, 2026 09:07
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