Commit Graph

761 Commits

Author SHA1 Message Date
simoleo89 bd71d326fb style(toolbar): solid bottom bar (classic Habbo look, less glassy) 2026-06-14 18:58:07 +02:00
simoleo89 b27f48f2a2 feat(furni-editor): sync empty public_name from furnidata name
When a furni has a matching furnidata entry with a display name but its
items_base.public_name (the DB fallback) is empty, the editor now shows a
'Sync from furnidata' button next to the Public Name field. It reuses the
generic item update (a partial { publicName } payload) to fill the DB column
from the stored furnidata name, so the read-only fallback stops being blank.
Button shows only when the entry's classname matches, the DB field is empty,
and the furnidata name is present; it disappears after the sync re-fetch.
2026-06-14 16:41:55 +02:00
simoleo89 1676b3c871 fix(furni-editor): surface upsert failures and revert optimistic name on error
When creating a furnidata entry for a furni whose sprite id is already used
by another classname, the server rejects with ID_COLLISION. The client showed
the optimistic public-name change but never reverted it, so a failed create
looked like it had succeeded. On any FurniEditorResult failure, re-fetch the
item detail to restore the true state (the error alert was already shown).
2026-06-14 14:44:25 +02:00
simoleo89 101c1b901f fix(marketplace): re-priced offer vanished when the server kept the same id
The "price raised" (case 3) handler did `set(item.offerId, item)` then an
unconditional `delete(requestedOfferId)`. When the re-priced offer kept the same
id (offerId === requestedOfferId), the set was immediately undone and the offer
disappeared from the list though it was still buyable. Delete the old key first,
then set under the new id.
2026-06-13 18:15:39 +02:00
simoleo89 26d7ccd62b fix(marketplace): reset creditsWaiting after redeeming sold offers
redeemSoldOffers optimistically removed the sold offers but never reset
creditsWaiting, so the redeem panel (gated on creditsWaiting > 0) kept rendering
"get 0 sold items for N credits" with an active Redeem button until the server
re-pushed the offers. Reset creditsWaiting to 0 on redeem.
2026-06-13 18:15:39 +02:00
simoleo89 8e82935312 fix(purse): HC status never reports EXPIRED for ex-Club (non-VIP) users
clubStatus computed `(purse.pastVipDays > 0) || (purse.pastVipDays > 0)` — the
same field twice. The first operand was meant to be `pastClubDays`, so a user who
previously had Habbo Club but never VIP got ClubStatus.NONE instead of EXPIRED,
showing the wrong HC Center status text and Buy-vs-Extend button. Use pastClubDays.
2026-06-13 18:15:36 +02:00
simoleo89 9c57d6a431 fix(groups): colour-picker highlight follows the live selection
The selected-swatch ring compared each swatch against `groupData.groupColors`,
which is only written back on save — so clicking a colour updated the local
`colors` state (and the top preview swatches) but the highlight ring never moved,
leaving the two in visible disagreement until you left and reopened the tab.
Compare against `colors[0]`/`colors[1]` (the live state) instead.
2026-06-13 18:15:34 +02:00
simoleo89 a776960650 fix(camera): full roll no longer discards the newest photo
When the roll hit CAMERA_ROLL_LIMIT the capture path alerted "full" then did
clone.pop() (dropping the NEWEST photo) and pushed the new one — so once full the
roll was pinned at the limit and every further shot just replaced the most-recent
picture. Block the shot instead (return after the alert).
2026-06-13 18:15:31 +02:00
simoleo89 d6cac249c6 fix(camera): reset selected picture index after deleting a photo
The 'delete' action spliced the selected picture out of the roll but never moved
selectedPictureIndex, so it kept pointing at the slot the deleted photo vacated —
now a different picture (or past the end), making the preview show the wrong
photo or vanish while the UI still thinks one is selected. Move the selection
back one after delete.
2026-06-13 18:15:31 +02:00
simoleo89 ed5c9296a8 fix(mod-tools): typos in moderation-action result alerts
The ModeratorActionResultMessageEvent alerts (hardcoded, not LocalizeText) read
"successfull" and "applying tht moderation action". Fix to "successful" / "the".
2026-06-13 18:15:29 +02:00
simoleo89 149b1db38c fix(mod-tools): default-sanction sent the topic array index, not the topic id
sendDefaultSanction passed `selectedTopic` (the index into the topics array) as
the CFH topic id to DefaultSanctionMessageComposer, so the emulator applied the
default sanction against whatever topic happened to sit at that array position.
The sibling sendSanction (and the topic label) correctly use
`topics[selectedTopic].id`. Pass `category.id`, and move the `category` lookup
after the `selectedTopic === -1` guard (+ a `!category` guard).
2026-06-13 18:15:29 +02:00
simoleo89 742f7ee5f7 fix(wired): date-range condition saved NaN for empty/invalid dates
The save guard `if(startDateInstance && endDateInstance)` is always true — a bad
input parses to a truthy *Invalid Date*, so `getTime()/1000` wrote NaN into the
int params. A never-configured furni was worse: the read effect only seeded the
inputs when `intData.length >= 2`, so the first save sent `new Date('')` → NaN.
Guard on `isNaN(getTime())` and seed both inputs to "now" for the empty case.
2026-06-13 18:15:26 +02:00
simoleo89 728eceab65 fix(wired): @altitude shown 100x too large and round-trip-edited wrong
`liveState.altitude` is already z*100, but the @altitude inspector rows multiplied
by 100 again (showing z*10000). The edit-commit path parses the field back as
`parsed / 100` (expecting z*100), so the displayed value and the edit parser
disagreed: tweaking the shown number wrote a wildly wrong altitude (clamped to the
40 ceiling). Display the raw `altitude` so it round-trips with the editor.
2026-06-13 18:15:26 +02:00
simoleo89 648cea698d fix(room): word-quiz countdown mutates Map value objects in place
The 1s tick did `value.secondsLeft--` on the VoteValue objects held by the
previous state Map and returned the same Map reference when nothing expired — an
in-place state mutation (breaks memoization / StrictMode double-invoke). Rebuild
new value objects in a new Map each tick (and drop expired entries).
2026-06-13 18:15:24 +02:00
simoleo89 a2f8a4dd61 fix(room): pet-fertilize chat bubble — bad localization key + wrong target user
Two bugs in the pet rebreed/fertilize chat path: the localization key had a
stray trailing semicolon (`'widget.chatbubble.petrefertilized;'`) so the lookup
failed and the raw key rendered; and the target user was resolved via
`newRoomObject = getRoomObject(event.extraParam)` but then read back by
`roomObject.id` (the speaker), so `userName` was the speaker, not the target.
Use `newRoomObject.id`.
2026-06-13 18:15:24 +02:00
simoleo89 53463b8322 fix(room): name bubbles cleared for the wrong user on USER_REMOVED
The USER_REMOVED handler for a UNIT filtered name bubbles with
`bubble.roomIndex === event.id`, which KEEPS only the leaving user's bubble and
drops everyone else's (the two sibling filters on the next lines correctly use
`!==`). When any user left view, all other floating name bubbles vanished while
the departed user's lingered. Flip to `!==`.
2026-06-13 18:15:24 +02:00
simoleo89 f873d68ee9 fix(messenger): mark thread read in an effect, not during render
FriendsMessengerThreadView called `thread.setRead()` in the render body — a side
effect during render that mutates the MessengerThread instance the messenger hook
also reads to compute the unread indicator, making unread state order-dependent
(and it would NPE if `thread` was null). Move it into a no-dependency useEffect
(runs after every commit, same cadence as before) and guard the null thread.
2026-06-13 18:15:21 +02:00
simoleo89 af6f65b194 fix(inventory): drop leaking badge pending-counter; trust server active set
sendActiveBadges incremented pendingUpdatesRef on every edit, and the BadgesEvent
handler skipped applying the server's active badges while the counter was > 0,
decrementing once per BadgesEvent. The assumption was "one BadgesEvent echo per
SetActivatedBadges" — but the emulator's UserWearBadgeEvent answers with a
UserBadgesComposer room broadcast, NOT a BadgesEvent, so nothing ever decrements
the counter. It leaks upward with every toggle/reorder/swap and then silently
drops legitimate later BadgesEvent updates (the server-authoritative active set
never reapplies). Remove the counter and always apply the server's active badges
on BadgesEvent (edits are already persisted server-side, so this is correct).
2026-06-13 18:15:19 +02:00
simoleo89 39fbfdd9e2 fix(inventory): derive active prefix from the fresh list, not a stale closure
The ActivePrefixUpdatedEvent handler set the active prefix via
`setActivePrefix(prev => { const found = prefixes.find(...) })`, reading the
`prefixes` state from the closure — which lags by a render and is stale/empty when
the prefix was added earlier in the same event batch, so `found` was undefined and
the active prefix fell back to a partial item missing icon/color/displayName. Move
the derivation inside the `setPrefixes` updater so it reads the freshly-mapped list.
2026-06-13 18:15:19 +02:00
simoleo89 9cc9ef86c0 fix(inventory): stop unseen-tracker mutating shared state arrays in place
resetItems/removeUnseen/the UnseenItemsEvent handler each did `new Map(prevValue)`
(a shallow copy) then spliced/pushed the per-category array returned by
`.get(category)` — the SAME array reference still held by the previous Map. That
mutates state outside React's data flow (breaks under StrictMode double-invoke and
any updater replay). resetItems additionally did `splice(existing.indexOf(id), 1)`
with no guard, so an id not present (indexOf === -1) spliced off the wrong LAST
element. Replace each in-place splice/push with a cloned array set back on the new
Map (filter for removals, spread+push for the merge).
2026-06-13 18:15:19 +02:00
simoleo89 74cbeccb52 feat(furni-editor): create furnidata entry when missing (upsert Save)
When a furni has no furnidata entry (furniDataEntry === null), unlock the
name/description fields instead of locking them: the Save button becomes
"Create entry" and sends the existing FurniEditorUpdateFurnidataComposer (10046),
which the emulator now upserts (creates a complete entry from items_base). The
classname-mismatch case (entry resolved by id but for a different classname)
stays locked to avoid an id collision. On success the hook already re-fetches the
detail, so the panel flips to normal edit mode. Name input prefills (placeholder)
from the DB Public Name.
2026-06-13 18:01:02 +02:00
hotellidev caf80e5386 Merge branch 'duckietm:main' into multicolorfurnifix 2026-06-12 03:15:02 +03:00
duckietm de38371069 🆙 100% Guild Furni Catalog Page 2026-06-11 13:16:29 +02:00
duckietm 40864cf880 🆙 Fix scrollbar 2026-06-11 10:31:24 +02:00
duckietm 5aa9dcd650 🆙 Added colored background to items in group furni & fix catalog price 2026-06-11 10:14:27 +02:00
hotellidev afaea87bcd Fix multicolor furni names 2026-06-11 04:07:06 +03:00
duckietm 9fcbfba22f 🆙 Fix Group Forum buy 2026-06-10 14:16:18 +02:00
duckietm 4bfd5e96ec 🆙 Update catalogue Forum view 2026-06-10 10:17:20 +02:00
duckietm e5ca4936ea 🆙 Detached Theme from original NitroV3 2026-06-10 07:23:02 +02:00
simoleo89 e6519c301f fix(catalog): honor skip purchase confirmation setting
Wire both classic and modern catalog purchase widgets to the shared catalogSkipPurchaseConfirmation setting used by User Settings. When enabled, the primary buy/rent button now calls the purchase flow directly instead of first switching to the CONFIRM state. Existing validation, gift purchases, club checks, limited sold-out handling, and Builders Club placement flows remain unchanged.
2026-06-09 22:29:11 +02:00
duckietm 3ea6ec70a4 🆙 Update Purse 2026-06-09 13:55:33 +02:00
duckietm 3e92e718e5 🆙 Fix avatar head in friends chat 2026-06-09 07:11:28 +02:00
duckietm ce8e6fa61f 🆙 Fix the avatar head in send pressent 2026-06-08 11:06:01 +02:00
duckietm b1f0fe64c0 🆙 Fix navigator fav. 2026-06-08 10:39:39 +02:00
duckietm 05653e7034 🆙 Better HK icoon 2026-06-08 10:16:03 +02:00
duckietm c427298926 🆙 Small fix for the clasic catalogue mobile view 2026-06-08 09:51:27 +02:00
duckietm cad30673ef 🆙 Updated Housekeeping icon 2026-06-08 08:50:41 +02:00
duckietm 4c36b595f5 🆙 Update the wheel of fortune icon 2026-06-08 08:42:01 +02:00
DuckieTM 50d4920194 Merge pull request #219 from duckietm/main
Sync Main to DEV
2026-06-08 07:29:21 +02:00
hotellidev 10e3a9c93d Merge branch 'duckietm:main' into item-descriptions 2026-06-08 00:24:52 +03:00
hotellidev e5097b824e Add back missing <hr> separator. Cleaned previous commits. 2026-06-08 00:21:11 +03:00
hotellidev 8e834261d0 Add configuration to limit itemLocation to people with access. 2026-06-08 00:21:11 +03:00
hotellidev 0daa2aea66 Config options for description and location 2026-06-08 00:21:11 +03:00
hotellidev 9e21cf5be4 Fix position 2026-06-08 00:21:11 +03:00
hotellidev 4a966d0d3d Add description to items 2026-06-08 00:21:11 +03:00
DuckieTM 2581cc62e9 Merge pull request #217 from medievalshell/feat/catalog-modern
feat(catalog): created two different catalog one nitro v3 and one 1 to 1 habbo
2026-06-07 23:17:23 +02:00
medievalshell e02c1fab8a fix(badge): group badge nero nell'HUD (race onload in LayoutBadgeImageView) 2026-06-07 23:00:06 +02:00
medievalshell 21d3a62b7a feat(catalog): catalogo modern Hippiehotel in albero separato (catalog-modern) 2026-06-07 23:00:06 +02:00
simoleo89 f5d8aacc2c feat: show furnidata diagnostics in editor 2026-06-07 21:21:21 +02:00
simoleo89 288b59f168 fix(chat-input): restore RoomWidgetUpdateChatInputContentEvent.TEXT mode
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.
2026-06-07 12:31:45 +02:00