Commit Graph
266 Commits
Author SHA1 Message Date
Tommaso CasaburiandGitHub 17c63bb2e6 feat(reply modal): add sci tex preview button (#1170)
* feat(sci): add 4chan-style TeX support with MathJax on /sci/

- [math]/[eqn] tags typeset with MathJax 3 (lazy chunk, only on /sci/ with math present)
- 4chan-identical config: Safe mode, left-aligned eqn, neutered \color/\newcommand macros
- TeX button in reply modal title bar opens live TeX Preview modal
- /sci/ post form rules bullets for [math]/[eqn] usage and right-click source
- MathJax context menu on right-click (Show Math As > TeX Commands)
- woff fonts served from node_modules in dev and emitted into build

* feat(sci): finish TeX support: configmacros fix, preview preload, translations, tests

- add configmacros package so the 4chan macro neutering (\color, \newcommand, ...) applies
- preload MathJax when the TeX Preview opens, like 4chan
- stable closeModal callback for the preview modal
- pre-bundle mathjax components in vite optimizeDeps to avoid dev mid-session reload
- translate the 6 new TeX keys into all 35 languages
- markdown math segment component tests + math-tags unit tests

* feat(reply modal): add sci tex preview button

* fix(tex-preview): clear MathJax bookkeeping and pending typeset on close

Addresses Cursor Bugbot: the preview output was typeset via typesetMathElement but
never passed to clearMathElement on unmount, so repeated open/close cycles kept
detached nodes in MathJax's math list. Also cancels the pending debounce timer.

* fix(reply-modal): reset TeX preview state when the reply modal closes

Addresses CodeRabbit: showTexPreview persisted across close/reopen like the
bbcode preview flags, so the TeX preview would auto-open on the next reply.
2026-06-11 16:12:38 +07:00
Tommaso CasaburiandGitHub 2f938d59ae fix(post-form): convert twimg query-format links in the reply modal (#1168)
Share getPublishLinkOptions between the inline post form and the reply modal so the modal publishes twimg ?format= links in their .jpg/.png form (previously raw), and rewrite the link field on blur in both so the conversion is visible. Also gate the dev service worker's runtime asset cache to production so dev no longer serves stale /src modules.
2026-06-09 19:24:28 +07:00
Tommaso CasaburiandGitHub c0f1a77958 fix(post ids): fall back to comment cid for missing ids (#1167)
* fix(post ids): fall back to comment cid for missing ids

* fix(post ids): count cid-resolved account replies
2026-06-09 19:08:02 +07:00
Tommaso Casaburi dbf672f11a Merge branch 'codex/fix/link-file-filename-validation' 2026-06-09 12:34:18 +07:00
Tommaso Casaburi 27558ded18 fix(post-form): hide filename for non-file media links
Only show pasted link filenames when the URL resolves to publishable
file media, so bare paths like imgur album IDs are not shown as files.
2026-06-09 12:34:13 +07:00
Tommaso CasaburiandGitHub 245d3164c3 fix(media playback): stop hidden and offscreen media (#1164)
* fix(media playback): stop hidden and offscreen media

* fix(media playback): keep offscreen embeds suspended
2026-06-08 22:55:30 +07:00
Tommaso CasaburiandGitHub 075b917c36 chore(flags): derive flag-test coords from board-flags source (#1165)
* feat(board-header): show subtitle on /all view

Add all_subtitle copy and render it in the board header when browsing
the aggregated all-directories feed.

* chore(flags): derive flag-test coords from board-flags source

comment-flags.test.ts hard-coded the pol/pony sprite x/y, duplicating the literals already pinned in board-flags.test.ts. A recent sprite remap updated one file and not the other, leaving master red. Derive the coords from getBoardFlagDefinition (the same source the runtime uses) so the assertion can't drift; labels stay literal as readable pins, and board-flags.test.ts remains the single place pinning the actual values.
2026-06-08 22:47:04 +07:00
Tommaso CasaburiandGitHub cf43934708 test(flags): correct stale pony AJ sprite x-coord expectation (#1163)
The pony sprite-coordinate remap (cbdd4edf7) moved AJ to x:48 and updated board-flags.test.ts, but comment-flags.test.ts still expected the old x:80, leaving master's full test suite red. Align the comment-flags expectation with the live board-flags definition (and the passing board-flags.test.ts).
2026-06-08 18:58:20 +07:00
Tommaso Casaburi cbdd4edf7b fix(flags): map pony flags to sprite sheet coordinates
Pony flag selector order differs from the sprite layout, so derive
positions from explicit coordinates instead of entry index.
2026-06-08 17:12:59 +07:00
Tommaso Casaburi 46aa197562 Merge branch 'codex/fix/flag-verification-scope' 2026-06-08 15:43:39 +07:00
Tommaso Casaburi 32dbabb7c7 fix(flags): limit challenge requests to country flags 2026-06-08 15:43:12 +07:00
Tommaso CasaburiandGitHub c2b222c4d5 fix(thread update): refresh stale reply caches (#1160)
* fix(thread update): refresh stale reply caches

Evict the current thread comment and known reply-page cache entries before manual refresh so stale local data does not keep replies hidden. Also defer broader multiboard suggestion feeds until the current /all time window is exhausted to reduce renderer pressure.

* fix(thread update): evict alternate reply page caches

* fix(board): hide stale time-window suggestions
2026-06-08 14:44:38 +07:00
Tommaso Casaburi 404a464310 feat: use s.5chan.app share links and remove report menu items
Copy share links as path-based s.5chan.app URLs so the share server can render social previews, rename the menu label, remove the stub report action, and update the FAQ.
2026-06-06 19:06:04 +07:00
Tommaso CasaburiandGitHub 0493492f55 fix(react-doctor): correct test exclusion + React-Compiler lint policy + state-sync fix (#1155)
* fix(react-doctor): correctly exclude test files from scoring

The intended test-file ignore in react-doctor.config.json was never
applied: react-doctor's config precedence reads the "reactDoctor" key
in package.json (which had no ignore), shadowing the config file. On
top of that, react-doctor 0.4.0's ignore.files matcher is broken — any
non-empty value collapses scan scope and drops real product files, not
just tests.

Consolidate to a single canonical doctor.config.json using
ignore.overrides (which works correctly): only test files are excluded
while all product code is still scored. Remove the shadowing
package.json key and the dead react-doctor.config.json.

Product-code baseline is 55 (92 errors, 515 warnings, 118 files).

* chore(react-doctor): add long-running task tracking for score effort

* refactor(react): remove compiler-redundant memoization in verified files

Delete manual useMemo/useCallback/memo that the React Compiler already
handles, in 7 files validated to be behavior-preserving (factories are
pure functions of compiler-trackable reactive inputs). Kept memos whose
factories read external mutable DOM/theme state with load-bearing deps
(e.g. use-reply-height-estimates metrics). Also hoists a regex and reads
a localStorage value once.

Note: this is code-quality cleanup; react-doctor's score is error-
weighted, so warning cleanup like this does not move the score. See
docs/agent-runs/react-doctor-score/progress.md.

* fix(react-doctor): adopt React-Compiler lint policy + fix one state-sync bug

react-doctor's score is dominated by React-Compiler optimizability
diagnostics that flag intentional patterns (the latest-ref idiom) and
current compiler limitations (try/finally, throw-in-try/catch the
compiler can't lower yet), not bugs. Rewriting that working code to
satisfy them would degrade it.

- Replace doctor.config.json with a documented doctor.config.jsonc that
  does not enforce the react-hooks-js (React Compiler) rules or
  react-compiler-no-manual-memoization. All real code-quality, a11y, and
  performance rules stay enforced.
- Fix one genuine state-sync bug: use-now-seconds refreshed 'now' via a
  synchronous setState inside an effect (an extra render with a stale
  value); move it to a render-time prev-prop comparison (React's
  adjust-during-render pattern), behavior-equivalent.

Score 54 (broken config) -> 63. type-check/lint/1051 tests pass; browser
smoke confirms timestamps render with no re-render regression. The
remaining no-adjust-state-on-prop-change diagnostics are real bugs but
entangled with legitimate side effects (navigate/ref-cancel/async) in
critical flows; left for careful follow-up.

* chore(react-doctor): remove the vanity score badge, keep PR-diff review

The single 0-100 react-doctor score mostly reflects React-Compiler
optimizability and isn't a meaningful health grade to display (see
docs/agent-runs/react-doctor-score). Remove the README badge and its now-
dead generation infra (CI write/upload/publish steps + the
write-react-doctor-badge.mjs script + doctor:badge package script).

Kept: react-doctor's actual value -- the PR step that runs
'yarn doctor --diff <base> --annotations' on pull requests touching React
files, surfacing newly-introduced issues inline. Coverage badge untouched.

* docs(react-doctor): document why the score is not a target to chase

Record the reasoning so future agents/contributors don't re-attempt to
grind the react-doctor score: it overwhelmingly reflects React-Compiler
optimizability (most 'errors' flag intentional patterns and current
compiler limitations, not bugs) and saturates on the fraction of clean
files, so ~63 is the honest ceiling and 90 only comes from disabling the
linter.

- Add a known-surprises entry with the full reasoning + mitigation.
- Reframe the AGENTS.md react-doctor verification line: it's a PR-diff
  reviewer for newly-introduced issues, not an aggregate score to raise.
2026-06-05 22:21:30 +07:00
Tommaso CasaburiandGitHub 69ee15786b fix(quotes): handle cross-thread quotes (publish + hover preview) (#1153)
* fix(quotes): publish only same-thread quoted cids

Quoting a post from another thread failed to publish with "One or more
quoted CIDs are not under the same post". That message is the protocol
error ERR_QUOTED_CID_NOT_UNDER_POST from @pkcprotocol/pkc-js, not a custom
5chan error: a reply's quotedCids must all live under the reply's own
thread.

The reply publish path resolved every >>number quotelink to a CID through
the board-scoped number map and sent them all as quotedCids, so any
cross-thread quotelink made the protocol reject the whole post.

Track each comment's thread (postCid) in usePostNumberStore and filter the
merged quotedCids to same-thread entries before publishing. Cross-thread
quotelinks still render and navigate via their >>number text; only the
published metadata changes. Same-thread replies resolved on demand by the
external-quote resolver are preserved because the resolver registers what
it finds.

Regression introduced in 9f14a6326 (populate quotedCids when publishing
replies with quote references).

* fix(quotes): show hover preview for cross-thread quotelinks

Hovering a >>number quote whose thread was not loaded showed nothing: the
quotelink rendered as an inert span with no floating preview. NumberQuoteLink
only fell back to the lazy resolver when the number->cid mapping was unknown.
When the cid was known but the comment body was not cached, it rendered
ReplyQuotePreview with an undefined comment, which is treated as pending
resolution and rendered as inert text that never fetched the body (the lookup
used onlyIfCached).

Load the body lazily on hover instead: NumberQuoteLink keeps onlyIfCached until
the quotelink is hovered, and ReplyQuotePreview's pending quotelink is now
hoverable when its cid is known so it can request that fetch and prime the
floating-preview position. Once the body resolves the preview appears without
re-hovering. Same-thread quotes stay cached, so this never fetches for them.

* fix(quotes): filter the final quotedCids payload to same-thread

Apply the same-thread filter to the merged publish options rather than only the
derived subset, so any quotedCids carried on stored publishCommentOptions cannot
bypass the guard. Defense in depth for the protocol's same-thread requirement
(ERR_QUOTED_CID_NOT_UNDER_POST); addresses PR review feedback.
2026-06-05 17:45:42 +07:00
Tommaso Casaburi ae16ae3dd3 feat(markdown): add /g/ [code] tag syntax highlighting
Parse [code] blocks on /g/ into Prettify-style highlighted code boxes while leaving the tags as literal text on other boards.
2026-06-05 17:02:44 +07:00
Tommaso Casaburi 3ece699a6f fix(post form): publish twimg query-format links with path extension
Normalize pbs.twimg.com media URLs that use ?format= to their file-extension form at publish time without rewriting the input field.
2026-06-04 18:00:25 +07:00
Tommaso Casaburi 0f6d74592e fix(flags): label Tor country flag 2026-06-04 17:18:35 +07:00
Tommaso CasaburiandGitHub 608402b5c8 fix(board): prevent transient no threads state (#1151)
* fix(board): prevent transient no threads state

* fix(board): scope raw thread fallback by sort

* fix(board): keep flash table loading during feed sync
2026-06-04 13:43:52 +07:00
Tommaso CasaburiandGitHub d09d2d05d1 fix(fortune): scope s5s fortune markup (#1150)
* fix(markdown): scope fortune markup to fortune boards

* fix(fortune): store fortune output as bbcode

* fix(fortune): keep legacy fortune rendering

* fix(tests): resolve catalog button mock merge

* fix(fortune): validate hidden fortune length
2026-06-03 13:49:35 +07:00
Tommaso Casaburi 0a601c9392 fix(post-form): auto-convert YouTube links to thumbnail URLs
Add a countdown notice and shared hook to replace YouTube watch links
with img.youtube.com thumbnails in post and reply forms, with i18n copy.
2026-06-02 14:59:14 +07:00
Tommaso Casaburi 75c805c822 fix(post options): link sage warning to FAQ 2026-06-02 12:16:22 +07:00
Tommaso Casaburi 342a8f53a7 Merge branch 'master' of github.com:bitsocialnet/5chan 2026-06-01 13:01:42 +07:00
Tommaso CasaburiandGitHub 829b672053 fix(embed): restore youtube thumbnails and file-row labels (#1148)
* fix(comment-content): render reason text as comment content

* fix(post-form): use native browser styling for flash tag select

Exclude the flash tag dropdown from themed post-form select styling so it
renders with the browser's default select appearance, matching the flag selector.

* fix(p2p-stats): show peer flags for DNS6 relay hostnames

Extract embedded IPv6 addresses from dns6 multiaddrs so geo lookup and country flags work for relay peers that publish IPv6 via DNS hostnames.

* fix(flags): hide geolocation-only selectors on /int/ and /sp/

Country-only boards auto-publish geographic location flags without
showing a flag dropdown, matching existing /bant/ behavior.

* fix(embed): restore youtube thumbnails and file-row labels

Restore thumbnail-first previews for YouTube embeds in post media and markdown hover.
Desktop posts show File with the thumbnail image URL and a youtube video type label.

* fix(embed): address youtube thumbnail review feedback

Translate the youtube video label, handle mobile/music YouTube hosts as standard YouTube URLs, keep affected mocks current, and cap default Vitest workers to reduce local CPU spikes.
2026-06-01 12:57:17 +07:00
Tommaso Casaburi b9ab1ba470 merge: show specific role in moderation posting warning 2026-06-01 12:48:47 +07:00
Tommaso Casaburi 812b6bc79c fix(post): show specific role in moderation posting warning
Replace the generic "posting as moderator" label with the effective role
(5chan dev, owner, admin, or moderator) in post and reply forms.
2026-06-01 12:48:42 +07:00
Tommaso Casaburi d038e7b2f8 merge: sync codex/fix/flash-no-catalog with master 2026-06-01 12:42:45 +07:00
Tommaso Casaburi b686def1a1 fix(board-buttons): hide catalog controls on flash upload boards
Flash boards do not use catalog view, so hide catalog links and OP search
without leaving empty bracket placeholders in desktop board controls.
2026-06-01 12:42:21 +07:00
Tommaso Casaburi 1bd8d6dc34 fix(flags): hide geolocation-only selectors on /int/ and /sp/
Country-only boards auto-publish geographic location flags without
showing a flag dropdown, matching existing /bant/ behavior.
2026-06-01 10:57:13 +07:00
Tommaso Casaburi 3480dc0505 fix(p2p-stats): show peer flags for DNS6 relay hostnames
Extract embedded IPv6 addresses from dns6 multiaddrs so geo lookup and country flags work for relay peers that publish IPv6 via DNS hostnames.
2026-05-31 18:02:20 +07:00
Tommaso CasaburiandGitHub b442e05191 feat(rules page): rebuild directory rules page with vendored lists (#1147)
* feat(rules page): rebuild directory rules page with vendored lists

Mirror per-directory JSON from lists into src/data/5chan-directories, rework /rules layout to match 4chan (sidebar nav, category boxes, P2P load), and keep spoiler markup visible in rule text via parseSpoilers.

* fix(rules): keep directory defaults cache atomic

* fix(rules): derive defaults from shared directory refresh

* fix(rules): address directory refresh edge cases
2026-05-31 11:39:40 +07:00
Tommaso CasaburiandGitHub e4638ac8c7 fix(media): embed additional direct image formats (#1146) 2026-05-30 23:45:21 +07:00
Tommaso CasaburiandGitHub 9b3a95dd95 feat(flash board): add SWF posting support (#1145) 2026-05-30 16:07:41 +07:00
Tommaso CasaburiandGitHub 56894700c1 feat(oekaki): add drawing flow for /i/ (#1144)
* feat(oekaki): add drawing flow for /i/

* fix(oekaki): address review feedback

* fix(oekaki): reset Tegaki edit sessions

* fix(oekaki): block drawing during export

* fix(oekaki): destroy Tegaki on preload errors

* fix(oekaki): preserve drawing on export failure

* fix(oekaki): unlock controls after export failure
2026-05-30 15:06:47 +07:00
Tommaso Casaburi 0469f61a45 feat(theme): add halloween special theme 2026-05-29 17:45:18 +07:00
Tommaso Casaburi c220c62b82 fix(i18n): disable i18next Locize support notice
Suppress the runtime Locize promo console message during i18next initialization.
2026-05-27 17:43:01 +07:00
Tommaso CasaburiandGitHub 029939089f fix(flags): align board flag rendering (#1142)
* fix(flags): align board flag rendering

* ci: run react doctor on changed pr files
2026-05-27 16:06:13 +07:00
Tommaso Casaburi 633542a1f7 fix(flags): move reply flag below link and auto-geo on /bant/
Hide the flag selector on /bant/ while still publishing geographic location, and place the reply modal flag field after the link field.
2026-05-24 23:38:15 +07:00
Tommaso Casaburi 639c627a04 fix(p2p stats): prefer browser IPv4 for own endpoint 2026-05-24 23:18:42 +07:00
Tommaso Casaburi 271cb14ae6 Merge branch 'master' of github.com:bitsocialnet/5chan
# Conflicts:
#	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
2026-05-24 23:18:28 +07:00
Tommaso CasaburiandGitHub f74b33f43b feat(flags): add comment flags (#1140)
* feat(flags): add comment flags

* fix(flags): address review feedback

* fix(flags): clear stale flag publish data
2026-05-24 23:14:36 +07:00
Tommaso Casaburi 31329f7856 Merge branch 'codex/fix/option-board-support-alert' 2026-05-24 19:17:55 +07:00
Tommaso Casaburi 5fad3c73ba fix(post): link board-specific option errors to supported boards
When fortune or dice options are used on the wrong board, show which
boards support them with clickable links in the post form and reply modal.
2026-05-24 19:17:50 +07:00
Tommaso CasaburiandGitHub 804c14fc35 Improve P2P stats peer locations and Kubo display (#1139)
* feat(p2p stats): plot peers by ip location

* fix(p2p stats): show own node map marker

* feat(p2p stats): support full node peers

* fix(p2p stats): clean up kubo stats

* fix(p2p stats): address review feedback
2026-05-24 17:32:05 +07:00
Tommaso CasaburiandGitHub f5039285a7 fix(p2p stats): improve own-IP geolocation and world map accuracy (#1138)
* fix(p2p stats): improve own-IP geolocation and world map accuracy

Resolve the user's public endpoint when libp2p only advertises private listen addresses, look up an accurate country flag for "Your IP", snap peer markers to country centroids, and add leeching seeder link plus panel layout tweaks.

* fix(p2p stats): skip caching own-IP lookups cancelled by abort

When the P2P stats panel unmounts mid-request, its AbortSignal cancels
the in-flight fetchOwnPublicEndpoint / fetchOwnIpCountryCode calls. Those
empty results were still cached for 30-60s, so reopening the panel within
that window showed "Your IP" as unavailable or without a country flag even
though nothing had actually failed. Skip caching when the signal aborted so
a later open retries. Addresses Cursor Bugbot finding.
2026-05-23 22:47:41 +07:00
Tommaso Casaburi 9c4bb28940 Merge branch 'codex/feature/prettier-peer-list' 2026-05-23 18:34:05 +07:00
Tommaso Casaburi 782a1f466f feat(p2p stats): redesign connected peers with world map and country flags
Restyle the connected-peers list in the classic square, flat imageboard style,
move it to the end of the panel, and open it by default. Add an offline
approximate world map and per-peer country flags (sprite order taken from the
original 4chan flags.css), plus codify the old-school design rules in DESIGN.md
and point agents to them from AGENTS.md.
2026-05-23 18:33:00 +07:00
Tommaso Casaburi fb1dbb3917 Merge branch 'master' of github.com:bitsocialnet/5chan 2026-05-23 17:20:18 +07:00
Tommaso CasaburiandGitHub 22c1b4f123 feat(post options): support nonoko board redirects (#1137) 2026-05-23 16:54:38 +07:00
Tommaso Casaburi d13f2240e3 fix(mod queue): dedupe board filters 2026-05-23 15:36:39 +07:00