Fix only the cases that are unambiguous anti-patterns; leave the
event-driven setState patterns (useNitroEvent / useMessageEvent
subscriptions, async fetches with cleanup) alone since they're
legitimate in this architecture.
- src/components/catalog/views/catalog-header/CatalogHeaderView.tsx:
displayImageUrl was pure-derived from imageUrl. Drop the useState +
useEffect entirely; compute in render.
- src/components/navigator/views/NavigatorRoomCreatorView.tsx:
the maxVisitors list (10..100 step 10) and roomModels/selectedModel
came from static config; convert to module-level MAX_VISITORS_LIST
constant + useState lazy initializers. Removes 2 init effects.
setCategory(categories[0].id) is left as-is because categories
arrives async from a hook.
- src/components/login/LoginView.tsx:
Replace useEffect(() => setLocalError(null), [step]) with the
React-recommended "track previous prop" render-time reset:
if(prevStep !== step) { setPrevStep(step); setLocalError(null); }
Same observable behavior, no extra render.
- src/components/room/widgets/choosers/ChooserWidgetView.tsx:
Wrap the selectItem callback prop call in useEffectEvent so a
parent re-render that changes selectItem identity doesn't
re-fire the visualizer side-effects.
Net: 4 fewer set-state-in-effect violations; behavior preserved.
The remaining ~328 violations across the codebase are predominantly
legitimate event-bus / async-fetch patterns and need per-case
review with running app, not a sweep.
https://claude.ai/code/session_01GrR87LAqnAEyKG2ZbmQt5Q
Run eslint --fix across src/ to clear ~1900 mechanical lint errors
surfaced by the @typescript-eslint v8 + react-hooks v7 + react-compiler
upgrade in the React 19 modernization PR.
Issues fixed automatically:
- brace-style (Allman): try/catch one-liners reformatted to multi-line
- indent: tab-vs-space and depth corrections
- semi: missing trailing semicolons
- no-trailing-spaces
No semantic changes. Remaining 701 errors are real-code issues
(set-state-in-effect, rules-of-hooks, no-unsafe-* type checks) that
need manual per-file review.
https://claude.ai/code/session_01GrR87LAqnAEyKG2ZbmQt5Q
Adds a "Cards" tab to the Profile Background picker (BackgroundsView)
that selects a pattern applied to the entire user info card and the
extended profile container, in addition to the existing avatar-pad
background/stand/overlay layers.
- AvatarInfoUser/Utilities: propagate cardBackgroundId from RoomUserData.
- InfoStandWidgetUserView: stateful cardBackgroundId, applied as
.profile-card-background.card-background-{id} on the outer Column
with bg-color suppressed when active.
- UserContainerView: same class on the wrapper of the extended profile.
- BackgroundsView: 4th tab "cards" backed by cards.data config
(falls back to backgrounds.data); sends 4-id message via the
extended sendBackgroundMessage signature.
- ui-config.example: cards.data dataset (15 entries).
- BackgroundsView.css: 188 .card-background-{N} rules cloned from
background-{N} (repeat-tiled) plus 15 CSS-pattern overrides for the
provisional dataset (gradients, stripes, dots, grid, checker).
Read user.badges.max.slots from config instead of hardcoded 5. InfoStand
layout adapts: 5 slots shows group badge, 6 slots replaces group with
6th badge. Double-click on InfoStand badge removes it. Badge received
toast now directly equips the badge via toggleBadge and closes.
Fix slot 0 drag bug ('0' is falsy), prevent badge duplication from stale
props fallback in InfoStand, add sparse slot support, fix race condition
with pending server updates. Add drag preview, glow animations, drop
settle effect, and remove-badge indicator overlay.
- Catalog page for creating custom prefixes with text, per-letter colors, emoji icon and visual effects
- Emoji picker via @emoji-mart/react with createPortal + Shadow DOM blur fix
- Inventory prefix management (activate/deactivate/delete)
- Chat bubble rendering with multi-color prefix and effect support
- Prefix utilities (getPrefixEffectStyle, parsePrefixColors, PREFIX_EFFECT_KEYFRAMES)
- All UI text in English
Server-authoritative command list via packet 4050, merged with
client-only commands. Supports keyboard navigation, filtering,
and module-level caching to handle login-time packet timing.
Co-Authored-By: medievalshell <medievalshell@users.noreply.github.com>
- Drag & drop badges between active slots in InfoStand (own user only)
- Mini badge picker on empty slot click with search
- Swap/reorder badges between occupied slots
- Hover animation (scale, glow) on badge slots
- Race condition fix: localChangeRef prevents server response from overwriting local changes
- Fixed-size array logic to prevent badge disappearing on room enter
- Use avatarInfo badges as fallback when hook data not yet loaded