The renderer pairing was hardcoded to the upstream repo. Make it owner-derived:
pair the client against <github.repository_owner>/Nitro_Render_V3 when that repo
carries the resolved ref, else fall back to the upstream renderer. So a fork's
client CI pairs with the fork's renderer when the companion code lives there,
and upstream still pairs with upstream. Keeps workflow_dispatch + vars.RENDERER_REPO/REF
overrides; probes ref existence via git ls-remote and warns+falls back if missing.
Pair the client against <repo owner>/Nitro_Render_V3 when that fork carries
the resolved ref, else fall back to the upstream renderer — instead of
hardcoding duckietm. Keeps dispatch-input and vars.RENDERER_REPO/REF
overrides; probes refs with 'git ls-remote' and warns+falls back if a ref
is missing. Fixes fork 'main' CI, whose client depends on fork-only
messenger composers (AddFriendCategoryComposer, ConsoleTypingComposer, …).
Replace the explicit per-package @nitrots/<pkg> entries with a single
'@nitrots/*' -> ../Nitro_Render_V3/packages/*/src/index.ts wildcard
(plus the umbrella '@nitrots/nitro-renderer' entry). Functionally
identical to a6e07c5 but far less verbose; yarn typecheck clean,
Vitest 545/545.
Replace the explicit per-package @nitrots/<pkg> entries with a single
'@nitrots/*' -> ../Nitro_Render_V3/packages/*/src/index.ts wildcard
(plus the umbrella '@nitrots/nitro-renderer' entry). Functionally
identical to a6e07c5 but far less verbose; yarn typecheck clean,
Vitest 545/545.
After syncing upstream, the client imports messenger composers/events
(AddFriendCategoryComposer, ConsoleTypingComposer, FriendIsTypingEvent, …)
that exist in fresh renderer source but tsgo resolved @nitrots to a stale
target predating them -> TS2305 'no exported member'. Mirror the vite.config
@nitrots/* aliases in tsconfig paths so typecheck reads the same source as
runtime. yarn typecheck now clean (0 errors); Vitest 545/545.
After syncing upstream, the client imports messenger composers/events
(AddFriendCategoryComposer, ConsoleTypingComposer, FriendIsTypingEvent, …)
that exist in fresh renderer source but tsgo resolved @nitrots to a stale
target predating them -> TS2305 'no exported member'. Mirror the vite.config
@nitrots/* aliases in tsconfig paths so typecheck reads the same source as
runtime. yarn typecheck now clean (0 errors); Vitest 545/545.
vite.config already aliases pixi.js to the renderer's copy, but tsconfig had no
matching path, so tsgo could not resolve the client-side import in src/pixiPatch.ts
(merge-introduced). Mirror the vite alias. Fixes TS2307.
Upstream 7007752 removed the TEXT constant + its handler case while migrating
in-component inserts to setChatValue, but NotificationDefaultAlertView still
dispatches TEXT to copy a command into the chat input (the only cross-component
path to set the input). Restore the constant and the handler case (setChatValue
+ focus, matching the command-selector path). Fixes TS2339.
vite.config already aliases pixi.js to the renderer's copy, but tsconfig had no
matching path, so tsgo could not resolve the client-side import in src/pixiPatch.ts
(merge-introduced). Mirror the vite alias. Fixes TS2307.
Upstream 7007752 removed the TEXT constant + its handler case while migrating
in-component inserts to setChatValue, but NotificationDefaultAlertView still
dispatches TEXT to copy a command into the chat input (the only cross-component
path to set the input). Restore the constant and the handler case (setChatValue
+ focus, matching the command-selector path). Fixes TS2339.
The "Edit Furni" button was nested inside the `(!avatarInfo.isWallItem
&& canMove)` guard, together with the floor-only Buildtools position/
height/rotation controls, so it never rendered for wall furni (e.g.
`ads_campguitar`). Move it out so it shows for any furni when
`godMode` + `isModerator`, leaving the position controls floor-only.
The onClick already resolved WALL vs FLOOR correctly.
While touching this file, clean up two pre-existing lint errors:
- hoist `getValidRoomObjectDirection` to module scope (it is pure and
uses no component state) so it is no longer accessed before its
declaration (react-hooks/immutability)
- expand the inline `'scale'` branch to Allman braces (brace-style)
The messenger rendered the participant figure straight from the frozen
thread participant, so offline friends (whose look used to be empty)
showed the anonymous/standard avatar. Read the live look from the friend
list via getFriend() - the same source the friends list renders - with
resolveAvatarFigure() as the final fallback, so the real avatar shows
even when offline (pairs with the server fix that now sends offline
looks). Applied to both the avatar-bar tab and the in-thread avatars.
Also fix the avatar-tab head framing: it positioned the head-only image
with full-body geometry (90x130, top:-31px), clipping the head. Render
the head at native size (background-size:auto, no scaling -> not grainy)
and centre it in the 36x36 tab.
Chat tagging:
- Any @user is a visible tag in chat bubbles (the .mention-tag CSS never
existed, so highlighting was invisible); self/alias mentions get a gold
emphasis. Fixes cross-room tags not being highlighted.
Mentions window:
- Redesigned: unread count in the header, restyled filter chips + a refresh
button, CSS-driven list/date-groups, adaptive height (compact when few,
capped + scroll when many), polished empty state.
- Rows: framed avatar (friends-list head crop so the face is never clipped),
per-row unread dot, type marker, icon action buttons (goto / remove).
- Re-requests from the server each time it opens.
Autocomplete:
- Never suggests the viewer themselves; suggests room users + online friends +
aliases.
Notifications:
- Mention toast removed; mentions flow through the client's standard
notification stream via a dedicated mention bubble (avatar + actions) in the
default position. EVERY received mention surfaces (independent of the generic
info-feed toggle, gated only by mentions_ui.enabled).
Refactor (behaviour-preserving):
- Centralised @-token classification in api/mentions/mentionTokens.
- Moved mentionsFormat -> api/mentions, useMentionActions -> hooks/mentions.
- Extracted ChatInputView @-autocomplete into a tested useChatMentions hook +
pure helper; removed the dead duplicate useMentionAutocomplete.
The toolbar renders a mentions button (`ToolbarItemView icon="mentions"` ->
`<div class="nitro-icon icon-mentions">`) and the asset
`assets/images/toolbar/icons/mentions.png` (72x64) exists, but icons.css had
no `.nitro-icon.icon-mentions` rule - so the element had no background image
and, since the base `.nitro-icon` sets no size, rendered at 0x0 (invisible).
Add the rule, sized at half the asset (36x32, preserving the 9:8 aspect) with
`background-size: contain`, matching the other toolbar icon definitions.
The leaderboard rows pulled each avatar head from habbo.com's imaging
service (`https://www.habbo.com/habbo-imaging/avatarimage?...headonly=1`)
via a plain <img>. The avatar `figure` is already present in the leaderboard
data (served by the CMS `/api/badges/leaderboard` endpoint), so there is no
need for an external request - render it locally instead.
Swap the <img> for the renderer-backed `LayoutAvatarImageView` (headOnly),
which draws the head through `GetAvatarRenderManager().createAvatarImage(...)`.
The head-only render is an absolutely-positioned background div rather than an
<img>, so the avatar CSS is reworked to frame it (relative, overflow-hidden
box with a head crop mirrored from the friends list), and the now-unused
`getAvatarHeadUrl` helper is removed.
Removes the last runtime dependency on habbo.com for this panel; avatars now
come entirely from the local renderer.