mirror of
https://git.sanhost.net/sanasol/hytale-f2p
synced 2026-03-02 18:31:51 -03:00
fix: presence field name (f.state not f.presence) and WS message routing via data.convo
Bug 1: Butter API returns friend presence in `state` field, not `presence`.
All 7 occurrences (friends list sort, count, display, DM header) now use f.state.
Bug 2: WS messages use `data.convo` for conversation routing ("global" or convo ID).
Message object may not have toId/to fields, causing all messages to fall into DM branch.
Now checks data.convo first with msg field fallbacks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -684,19 +684,19 @@ function renderFriendsList() {
|
||||
|
||||
// Sort: online first, then alphabetical
|
||||
const sorted = [...friends].sort((a, b) => {
|
||||
const aOnline = a.presence !== 'offline' ? 1 : 0;
|
||||
const bOnline = b.presence !== 'offline' ? 1 : 0;
|
||||
const aOnline = a.state !== 'offline' ? 1 : 0;
|
||||
const bOnline = b.state !== 'offline' ? 1 : 0;
|
||||
if (aOnline !== bOnline) return bOnline - aOnline;
|
||||
return (a.handle || '').localeCompare(b.handle || '');
|
||||
});
|
||||
|
||||
const onlineCount = sorted.filter(f => f.presence !== 'offline').length;
|
||||
const onlineCount = sorted.filter(f => f.state !== 'offline').length;
|
||||
|
||||
let html = `<div class="matcha-section-header">Friends \u2014 ${onlineCount} connected (${friends.length} total)</div>`;
|
||||
|
||||
sorted.forEach(f => {
|
||||
const presenceClass = f.presence === 'offline' ? 'offline' : (f.presence === 'in_game' ? 'ingame' : 'online');
|
||||
const presenceText = f.presence === 'offline' ? 'Offline' : (f.presence === 'in_game' ? 'In Game' : 'Online');
|
||||
const presenceClass = f.state === 'offline' ? 'offline' : (f.state === 'in_game' ? 'ingame' : 'online');
|
||||
const presenceText = f.state === 'offline' ? 'Offline' : (f.state === 'in_game' ? 'In Game' : 'Online');
|
||||
const unread = matchaState.unreadDms[f.id] || 0;
|
||||
const unreadBadge = unread > 0 ? `<span class="matcha-unread-dot">${unread}</span>` : '';
|
||||
const avUrl = avatarUrl(f.id);
|
||||
@@ -925,8 +925,8 @@ function renderDmChat(body, header) {
|
||||
const target = matchaState.dmTarget;
|
||||
// Find friend for presence/avatar info
|
||||
const friend = matchaState.friends.find(f => f.id === target.id);
|
||||
const presenceClass = friend?.presence === 'offline' ? 'offline' : (friend?.presence === 'in_game' ? 'ingame' : 'online');
|
||||
const presenceText = friend?.presence === 'offline' ? 'Offline' : (friend?.presence === 'in_game' ? 'In Game' : 'Online');
|
||||
const presenceClass = friend?.state === 'offline' ? 'offline' : (friend?.state === 'in_game' ? 'ingame' : 'online');
|
||||
const presenceText = friend?.state === 'offline' ? 'Offline' : (friend?.state === 'in_game' ? 'In Game' : 'Online');
|
||||
const avUrl = avatarUrl(friend?.id);
|
||||
|
||||
header.innerHTML = `
|
||||
@@ -1598,12 +1598,13 @@ function setupWsListeners() {
|
||||
});
|
||||
|
||||
matcha.onWsMessage((data) => {
|
||||
// The WS data has type:"message" + message fields at top level
|
||||
// WS data has: type:"message", convo:"global"|<convoId>, message:{...}
|
||||
const msg = data.message || data;
|
||||
const isOwnMessage = !!msg.fromId && String(msg.fromId) === String(matchaState.user?.id || '');
|
||||
const isGlobal = msg.toId === 'global' || msg.to === 'global';
|
||||
// Use data.convo (Butter's WS format) as primary routing, fallback to msg fields
|
||||
const isGlobal = data.convo === 'global' || msg.toId === 'global' || msg.to === 'global';
|
||||
|
||||
mlog.log('WS msg:', msg.fromHandle, '->', msg.toId || msg.to, '| own:', isOwnMessage, '| fromId:', msg.fromId, '| userId:', matchaState.user?.id);
|
||||
mlog.log('WS msg:', msg.fromHandle, '-> convo:', data.convo, 'toId:', msg.toId, '| own:', isOwnMessage, '| fromId:', msg.fromId, '| userId:', matchaState.user?.id);
|
||||
|
||||
if (isGlobal) {
|
||||
// Skip if own message (already rendered optimistically)
|
||||
@@ -1632,8 +1633,8 @@ function setupWsListeners() {
|
||||
updateUnreadBadges();
|
||||
}
|
||||
} else {
|
||||
// DM
|
||||
const otherId = isOwnMessage ? msg.toId : msg.fromId;
|
||||
// DM — use data.convo as conversation identifier, fallback to msg fields
|
||||
const otherId = data.convo || (isOwnMessage ? msg.toId : msg.fromId);
|
||||
|
||||
// Skip own messages (already rendered optimistically)
|
||||
if (isOwnMessage) {
|
||||
|
||||
Reference in New Issue
Block a user