moved friend cursor data aggregation from frontend to backend

This commit is contained in:
2026-03-09 12:30:29 +08:00
parent 23c778a0bb
commit 69cfebee3d
8 changed files with 201 additions and 96 deletions

View File

@@ -1,81 +1,32 @@
import { writable } from "svelte/store";
import {
events,
type CursorPositions,
type DollDto,
type OutgoingFriendCursorPayload,
} from "$lib/bindings";
import { createEventSource, removeFromStore } from "./listener-utils";
type FriendCursorData = {
position: CursorPositions;
lastUpdated: number;
};
import { events, type CursorPositions } from "$lib/bindings";
import { createEventSource } from "./listener-utils";
export const friendsCursorPositions = writable<Record<string, CursorPositions>>(
{},
);
export const friendsActiveDolls = writable<Record<string, DollDto | null>>({});
// Here for now. Will extract into shared
// util when there's more similar cases.
function toCursorPositionsRecord(
payload: Partial<Record<string, CursorPositions>>,
): Record<string, CursorPositions> {
return Object.fromEntries(
Object.entries(payload).filter(
(entry): entry is [string, CursorPositions] => {
return entry[1] !== undefined;
},
),
);
}
export const {
start: startFriendCursorTracking,
stop: stopFriendCursorTracking,
} = createEventSource(async (addEventListener) => {
let friendCursorState: Record<string, FriendCursorData> = {};
addEventListener(
await events.friendCursorPositionUpdated.listen((event) => {
const data: OutgoingFriendCursorPayload = event.payload;
friendCursorState[data.userId] = {
position: data.position,
lastUpdated: Date.now(),
};
friendsCursorPositions.update((current) => {
return {
...current,
[data.userId]: data.position,
};
});
}),
);
addEventListener(
await events.friendDisconnected.listen((event) => {
const data = event.payload;
if (friendCursorState[data.userId]) {
delete friendCursorState[data.userId];
}
friendsCursorPositions.update((current) =>
removeFromStore(current, data.userId),
);
}),
);
addEventListener(
await events.friendActiveDollChanged.listen((event) => {
const payload = event.payload;
if (!payload.doll) {
friendsActiveDolls.update((current) => {
const next = { ...current };
next[payload.friendId] = null;
return next;
});
friendsCursorPositions.update((current) =>
removeFromStore(current, payload.friendId),
);
} else {
friendsActiveDolls.update((current) => {
return {
...current,
[payload.friendId]: payload.doll,
};
});
}
await events.friendCursorPositionsUpdated.listen((event) => {
friendsCursorPositions.set(toCursorPositionsRecord(event.payload));
}),
);
});