refactored svelte tauri events
This commit is contained in:
@@ -2,7 +2,7 @@ use crate::{
|
||||
commands::app_state::get_modules,
|
||||
services::{
|
||||
doll_editor::open_doll_editor_window,
|
||||
scene::{set_pet_menu_state, set_scene_interactive},
|
||||
scene::{get_scene_interactive, set_pet_menu_state, set_scene_interactive},
|
||||
},
|
||||
};
|
||||
use commands::app::{quit_app, restart_app, retry_connection};
|
||||
@@ -83,6 +83,7 @@ pub fn run() {
|
||||
save_client_config,
|
||||
open_client_config_manager,
|
||||
open_doll_editor_window,
|
||||
get_scene_interactive,
|
||||
set_scene_interactive,
|
||||
set_pet_menu_state,
|
||||
login,
|
||||
|
||||
@@ -82,6 +82,11 @@ pub fn set_scene_interactive(interactive: bool, should_click: bool) {
|
||||
update_scene_interactive(interactive, should_click);
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_scene_interactive() -> Result<bool, String> {
|
||||
Ok(scene_interactive_state().load(Ordering::SeqCst))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn set_pet_menu_state(id: String, open: bool) {
|
||||
let menus_arc = get_open_pet_menus();
|
||||
|
||||
@@ -9,14 +9,17 @@ export const appData = writable<UserData | null>(null);
|
||||
|
||||
const subscription = createListenerSubscription();
|
||||
|
||||
export async function initAppDataListener() {
|
||||
/**
|
||||
* Starts listening for app data refresh events.
|
||||
* Initializes app data from the backend.
|
||||
*/
|
||||
export async function startAppData() {
|
||||
try {
|
||||
if (subscription.isListening()) return;
|
||||
appData.set(await invoke("get_app_data"));
|
||||
const unlisten = await listen<UserData>(
|
||||
AppEvents.AppDataRefreshed,
|
||||
(event) => {
|
||||
console.log("app-data-refreshed", event.payload);
|
||||
appData.set(event.payload);
|
||||
},
|
||||
);
|
||||
@@ -28,8 +31,8 @@ export async function initAppDataListener() {
|
||||
}
|
||||
}
|
||||
|
||||
export function stopAppDataListener() {
|
||||
export function stopAppData() {
|
||||
subscription.stop();
|
||||
}
|
||||
|
||||
setupHmrCleanup(stopAppDataListener);
|
||||
setupHmrCleanup(stopAppData);
|
||||
|
||||
@@ -2,155 +2,31 @@ import { invoke } from "@tauri-apps/api/core";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { writable } from "svelte/store";
|
||||
import type { CursorPositions } from "../types/bindings/CursorPositions";
|
||||
import type { CursorPosition } from "../types/bindings/CursorPosition";
|
||||
import type { DollDto } from "../types/bindings/DollDto";
|
||||
import { AppEvents } from "../types/bindings/AppEventsConstants";
|
||||
import {
|
||||
createMultiListenerSubscription,
|
||||
parseEventPayload,
|
||||
removeFromStore,
|
||||
setupHmrCleanup,
|
||||
} from "./listener-utils";
|
||||
import { createListenerSubscription, setupHmrCleanup } from "./listener-utils";
|
||||
|
||||
export const cursorPositionOnScreen = writable<CursorPositions>({
|
||||
raw: { x: 0, y: 0 },
|
||||
mapped: { x: 0, y: 0 },
|
||||
});
|
||||
|
||||
export type FriendCursorPosition = {
|
||||
userId: string;
|
||||
position: CursorPositions;
|
||||
};
|
||||
|
||||
// Map of userId -> { position: CursorPositions, lastUpdated: number }
|
||||
// We store the timestamp to detect stale cursors
|
||||
type FriendCursorData = {
|
||||
position: CursorPositions;
|
||||
lastUpdated: number;
|
||||
};
|
||||
|
||||
// The exported store will only expose the position part to consumers,
|
||||
// but internally we manage the full data.
|
||||
// Actually, it's easier if we just export the positions and manage state internally.
|
||||
export const friendsCursorPositions = writable<Record<string, CursorPositions>>(
|
||||
{},
|
||||
);
|
||||
export const friendsActiveDolls = writable<Record<string, DollDto | null>>({});
|
||||
|
||||
const subscription = createMultiListenerSubscription();
|
||||
|
||||
// Internal state to track timestamps
|
||||
let friendCursorState: Record<string, FriendCursorData> = {};
|
||||
const subscription = createListenerSubscription();
|
||||
|
||||
/**
|
||||
* Initialize cursor tracking for this window.
|
||||
* Can be called from multiple windows - only the first call starts tracking on the Rust side,
|
||||
* but all windows can independently listen to the broadcast events.
|
||||
* Starts tracking the local cursor position.
|
||||
* Initializes cursor position from the backend and listens for updates.
|
||||
*/
|
||||
export async function initCursorTracking() {
|
||||
export async function startCursorTracking() {
|
||||
if (subscription.isListening()) return;
|
||||
|
||||
try {
|
||||
// Listen to cursor position events (each window subscribes independently)
|
||||
const unlistenCursor = await listen<CursorPositions>(
|
||||
const unlisten = await listen<CursorPositions>(
|
||||
AppEvents.CursorPosition,
|
||||
(event) => {
|
||||
cursorPositionOnScreen.set(event.payload);
|
||||
},
|
||||
);
|
||||
subscription.addUnlisten(unlistenCursor);
|
||||
|
||||
// Listen to friend cursor position events
|
||||
const unlistenFriendCursor = await listen<FriendCursorPosition>(
|
||||
AppEvents.FriendCursorPosition,
|
||||
(event) => {
|
||||
// We now receive a clean object from Rust
|
||||
const data = event.payload;
|
||||
|
||||
// Update internal state with timestamp
|
||||
friendCursorState[data.userId] = {
|
||||
position: data.position,
|
||||
lastUpdated: Date.now(),
|
||||
};
|
||||
|
||||
friendsCursorPositions.update((current) => {
|
||||
return {
|
||||
...current,
|
||||
[data.userId]: data.position,
|
||||
};
|
||||
});
|
||||
},
|
||||
);
|
||||
subscription.addUnlisten(unlistenFriendCursor);
|
||||
|
||||
// Listen to friend disconnected events
|
||||
const unlistenFriendDisconnected = await listen<
|
||||
[{ userId: string }] | { userId: string } | string
|
||||
>(AppEvents.FriendDisconnected, (event) => {
|
||||
const payload = parseEventPayload<
|
||||
[{ userId: string }] | { userId: string }
|
||||
>(event.payload, AppEvents.FriendDisconnected);
|
||||
if (!payload) return;
|
||||
|
||||
const data = Array.isArray(payload) ? payload[0] : payload;
|
||||
|
||||
// Remove from internal state
|
||||
if (friendCursorState[data.userId]) {
|
||||
delete friendCursorState[data.userId];
|
||||
}
|
||||
|
||||
// Update svelte store
|
||||
friendsCursorPositions.update((current) =>
|
||||
removeFromStore(current, data.userId),
|
||||
);
|
||||
});
|
||||
subscription.addUnlisten(unlistenFriendDisconnected);
|
||||
|
||||
// Listen to friend active doll changed events
|
||||
const unlistenFriendActiveDollChanged = await listen<
|
||||
| string
|
||||
| {
|
||||
friendId: string;
|
||||
doll: DollDto | null;
|
||||
}
|
||||
>(AppEvents.FriendActiveDollChanged, (event) => {
|
||||
const data = parseEventPayload<{
|
||||
friendId: string;
|
||||
doll: DollDto | null;
|
||||
}>(event.payload, AppEvents.FriendActiveDollChanged);
|
||||
if (!data) return;
|
||||
|
||||
// Cast to expected type after parsing
|
||||
const payload = data as { friendId: string; doll: DollDto | null };
|
||||
|
||||
if (!payload.doll) {
|
||||
// If doll is null, it means the friend deactivated their doll.
|
||||
|
||||
// Update the active dolls store to explicitly set this friend's doll to null
|
||||
// We MUST set it to null instead of deleting it, otherwise the UI might
|
||||
// fall back to the initial appData snapshot which might still have the old doll.
|
||||
friendsActiveDolls.update((current) => {
|
||||
const next = { ...current };
|
||||
next[payload.friendId] = null;
|
||||
return next;
|
||||
});
|
||||
|
||||
// Also remove from cursor positions so the sprite disappears
|
||||
friendsCursorPositions.update((current) =>
|
||||
removeFromStore(current, payload.friendId),
|
||||
);
|
||||
} else {
|
||||
// Update or add the new doll configuration
|
||||
friendsActiveDolls.update((current) => {
|
||||
return {
|
||||
...current,
|
||||
[payload.friendId]: payload.doll!,
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
subscription.addUnlisten(unlistenFriendActiveDollChanged);
|
||||
|
||||
subscription.setUnlisten(unlisten);
|
||||
subscription.setListening(true);
|
||||
} catch (err) {
|
||||
console.error("Failed to initialize cursor tracking:", err);
|
||||
@@ -158,10 +34,6 @@ export async function initCursorTracking() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop listening to cursor events in this window.
|
||||
* Note: This doesn't stop the Rust-side tracking, just stops this window from receiving events.
|
||||
*/
|
||||
export function stopCursorTracking() {
|
||||
subscription.stop();
|
||||
}
|
||||
|
||||
129
src/events/friend-cursor.ts
Normal file
129
src/events/friend-cursor.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { writable } from "svelte/store";
|
||||
import type { CursorPositions } from "../types/bindings/CursorPositions";
|
||||
import type { DollDto } from "../types/bindings/DollDto";
|
||||
import { AppEvents } from "../types/bindings/AppEventsConstants";
|
||||
import {
|
||||
createMultiListenerSubscription,
|
||||
parseEventPayload,
|
||||
removeFromStore,
|
||||
setupHmrCleanup,
|
||||
} from "./listener-utils";
|
||||
|
||||
export type FriendCursorPosition = {
|
||||
userId: string;
|
||||
position: CursorPositions;
|
||||
};
|
||||
|
||||
type FriendCursorData = {
|
||||
position: CursorPositions;
|
||||
lastUpdated: number;
|
||||
};
|
||||
|
||||
export const friendsCursorPositions = writable<Record<string, CursorPositions>>(
|
||||
{},
|
||||
);
|
||||
export const friendsActiveDolls = writable<Record<string, DollDto | null>>({});
|
||||
|
||||
const subscription = createMultiListenerSubscription();
|
||||
|
||||
let friendCursorState: Record<string, FriendCursorData> = {};
|
||||
|
||||
/**
|
||||
* Starts listening for friend cursor position and active doll changes.
|
||||
* Also handles friend disconnection events.
|
||||
*/
|
||||
export async function startFriendCursorTracking() {
|
||||
if (subscription.isListening()) return;
|
||||
|
||||
try {
|
||||
// TODO: Add initial sync for existing friends' cursors and dolls if needed
|
||||
|
||||
const unlistenFriendCursor = await listen<FriendCursorPosition>(
|
||||
AppEvents.FriendCursorPosition,
|
||||
(event) => {
|
||||
const data = event.payload;
|
||||
|
||||
friendCursorState[data.userId] = {
|
||||
position: data.position,
|
||||
lastUpdated: Date.now(),
|
||||
};
|
||||
|
||||
friendsCursorPositions.update((current) => {
|
||||
return {
|
||||
...current,
|
||||
[data.userId]: data.position,
|
||||
};
|
||||
});
|
||||
},
|
||||
);
|
||||
subscription.addUnlisten(unlistenFriendCursor);
|
||||
|
||||
const unlistenFriendDisconnected = await listen<
|
||||
[{ userId: string }] | { userId: string } | string
|
||||
>(AppEvents.FriendDisconnected, (event) => {
|
||||
const payload = parseEventPayload<
|
||||
[{ userId: string }] | { userId: string }
|
||||
>(event.payload, AppEvents.FriendDisconnected);
|
||||
if (!payload) return;
|
||||
|
||||
const data = Array.isArray(payload) ? payload[0] : payload;
|
||||
|
||||
if (friendCursorState[data.userId]) {
|
||||
delete friendCursorState[data.userId];
|
||||
}
|
||||
|
||||
friendsCursorPositions.update((current) =>
|
||||
removeFromStore(current, data.userId),
|
||||
);
|
||||
});
|
||||
subscription.addUnlisten(unlistenFriendDisconnected);
|
||||
|
||||
const unlistenFriendActiveDollChanged = await listen<
|
||||
| string
|
||||
| {
|
||||
friendId: string;
|
||||
doll: DollDto | null;
|
||||
}
|
||||
>(AppEvents.FriendActiveDollChanged, (event) => {
|
||||
const data = parseEventPayload<{
|
||||
friendId: string;
|
||||
doll: DollDto | null;
|
||||
}>(event.payload, AppEvents.FriendActiveDollChanged);
|
||||
if (!data) return;
|
||||
|
||||
const payload = data as { friendId: string; doll: DollDto | null };
|
||||
|
||||
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!,
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
subscription.addUnlisten(unlistenFriendActiveDollChanged);
|
||||
|
||||
subscription.setListening(true);
|
||||
} catch (err) {
|
||||
console.error("Failed to initialize friend cursor tracking:", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
export function stopFriendCursorTracking() {
|
||||
subscription.stop();
|
||||
}
|
||||
|
||||
setupHmrCleanup(stopFriendCursorTracking);
|
||||
@@ -1,5 +1,5 @@
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { addInteraction } from "$lib/stores/interaction-store";
|
||||
import { writable } from "svelte/store";
|
||||
import type { InteractionPayloadDto } from "../types/bindings/InteractionPayloadDto";
|
||||
import type { InteractionDeliveryFailedDto } from "../types/bindings/InteractionDeliveryFailedDto";
|
||||
import { AppEvents } from "../types/bindings/AppEventsConstants";
|
||||
@@ -8,35 +8,62 @@ import {
|
||||
setupHmrCleanup,
|
||||
} from "./listener-utils";
|
||||
|
||||
const subscription = createMultiListenerSubscription();
|
||||
export const receivedInteractions = writable<Map<string, InteractionPayloadDto>>(
|
||||
new Map(),
|
||||
);
|
||||
|
||||
export async function initInteractionListeners() {
|
||||
if (subscription.isListening()) return;
|
||||
|
||||
const unlistenReceived = await listen<InteractionPayloadDto>(
|
||||
AppEvents.InteractionReceived,
|
||||
(event) => {
|
||||
addInteraction(event.payload);
|
||||
},
|
||||
);
|
||||
subscription.addUnlisten(unlistenReceived);
|
||||
|
||||
const unlistenFailed = await listen<InteractionDeliveryFailedDto>(
|
||||
AppEvents.InteractionDeliveryFailed,
|
||||
(event) => {
|
||||
console.error("Interaction delivery failed:", event.payload);
|
||||
// You might want to show a toast or alert here
|
||||
alert(
|
||||
`Failed to send message to user ${event.payload.recipientUserId}: ${event.payload.reason}`,
|
||||
);
|
||||
},
|
||||
);
|
||||
subscription.addUnlisten(unlistenFailed);
|
||||
subscription.setListening(true);
|
||||
export function addInteraction(interaction: InteractionPayloadDto) {
|
||||
receivedInteractions.update((map) => {
|
||||
const newMap = new Map(map);
|
||||
newMap.set(interaction.senderUserId, interaction);
|
||||
return newMap;
|
||||
});
|
||||
}
|
||||
|
||||
export function stopInteractionListeners() {
|
||||
export function clearInteraction(userId: string) {
|
||||
receivedInteractions.update((map) => {
|
||||
const newMap = new Map(map);
|
||||
newMap.delete(userId);
|
||||
return newMap;
|
||||
});
|
||||
}
|
||||
|
||||
const subscription = createMultiListenerSubscription();
|
||||
|
||||
/**
|
||||
* Starts listening for interaction events (received and delivery failed).
|
||||
*/
|
||||
export async function startInteraction() {
|
||||
if (subscription.isListening()) return;
|
||||
|
||||
try {
|
||||
const unlistenReceived = await listen<InteractionPayloadDto>(
|
||||
AppEvents.InteractionReceived,
|
||||
(event) => {
|
||||
addInteraction(event.payload);
|
||||
},
|
||||
);
|
||||
subscription.addUnlisten(unlistenReceived);
|
||||
|
||||
const unlistenFailed = await listen<InteractionDeliveryFailedDto>(
|
||||
AppEvents.InteractionDeliveryFailed,
|
||||
(event) => {
|
||||
console.error("Interaction delivery failed:", event.payload);
|
||||
alert(
|
||||
`Failed to send message to user ${event.payload.recipientUserId}: ${event.payload.reason}`,
|
||||
);
|
||||
},
|
||||
);
|
||||
subscription.addUnlisten(unlistenFailed);
|
||||
subscription.setListening(true);
|
||||
} catch (err) {
|
||||
console.error("Failed to initialize interaction listeners:", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
export function stopInteraction() {
|
||||
subscription.stop();
|
||||
}
|
||||
|
||||
setupHmrCleanup(stopInteractionListeners);
|
||||
setupHmrCleanup(stopInteraction);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { writable } from "svelte/store";
|
||||
import { AppEvents } from "../types/bindings/AppEventsConstants";
|
||||
import { createListenerSubscription, setupHmrCleanup } from "./listener-utils";
|
||||
@@ -7,12 +8,15 @@ export const sceneInteractive = writable<boolean>(false);
|
||||
|
||||
const subscription = createListenerSubscription();
|
||||
|
||||
export async function initSceneInteractiveListener() {
|
||||
/**
|
||||
* Starts listening for scene interactive state changes.
|
||||
* Initializes the scene interactive state from the backend.
|
||||
*/
|
||||
export async function startSceneInteractive() {
|
||||
if (subscription.isListening()) return;
|
||||
|
||||
try {
|
||||
// ensure initial default matches backend default
|
||||
sceneInteractive.set(false);
|
||||
sceneInteractive.set(await invoke("get_scene_interactive"));
|
||||
const unlisten = await listen<boolean>(
|
||||
AppEvents.SceneInteractive,
|
||||
(event) => {
|
||||
@@ -27,8 +31,8 @@ export async function initSceneInteractiveListener() {
|
||||
}
|
||||
}
|
||||
|
||||
export function stopSceneInteractiveListener() {
|
||||
export function stopSceneInteractive() {
|
||||
subscription.stop();
|
||||
}
|
||||
|
||||
setupHmrCleanup(stopSceneInteractiveListener);
|
||||
setupHmrCleanup(stopSceneInteractive);
|
||||
|
||||
@@ -9,17 +9,20 @@ import {
|
||||
setupHmrCleanup,
|
||||
} from "./listener-utils";
|
||||
|
||||
export type UserStatus = {
|
||||
export type PresenceState = {
|
||||
presenceStatus: PresenceStatus;
|
||||
state: "idle" | "resting";
|
||||
};
|
||||
|
||||
export const friendsUserStatuses = writable<Record<string, UserStatus>>({});
|
||||
export const currentUserStatus = writable<UserStatus | null>(null);
|
||||
export const friendsPresenceStates = writable<Record<string, PresenceState>>({});
|
||||
export const currentPresenceState = writable<PresenceState | null>(null);
|
||||
|
||||
const subscription = createMultiListenerSubscription();
|
||||
|
||||
export async function initUserStatusListeners() {
|
||||
/**
|
||||
* Starts listening for user status changes and friend status updates.
|
||||
*/
|
||||
export async function startUserStatus() {
|
||||
if (subscription.isListening()) return;
|
||||
|
||||
try {
|
||||
@@ -28,7 +31,7 @@ export async function initUserStatusListeners() {
|
||||
(event) => {
|
||||
const payload = parseEventPayload<{
|
||||
userId?: string;
|
||||
status?: UserStatus;
|
||||
status?: PresenceState;
|
||||
}>(event.payload, AppEvents.FriendUserStatus);
|
||||
if (!payload) return;
|
||||
|
||||
@@ -48,7 +51,7 @@ export async function initUserStatusListeners() {
|
||||
|
||||
if (status.state !== "idle" && status.state !== "resting") return;
|
||||
|
||||
friendsUserStatuses.update((current) => ({
|
||||
friendsPresenceStates.update((current) => ({
|
||||
...current,
|
||||
[userId]: {
|
||||
presenceStatus: status.presenceStatus,
|
||||
@@ -59,10 +62,10 @@ export async function initUserStatusListeners() {
|
||||
);
|
||||
subscription.addUnlisten(unlistenStatus);
|
||||
|
||||
const unlistenUserStatusChanged = await listen<UserStatus>(
|
||||
const unlistenUserStatusChanged = await listen<PresenceState>(
|
||||
AppEvents.UserStatusChanged,
|
||||
(event) => {
|
||||
currentUserStatus.set(event.payload);
|
||||
currentPresenceState.set(event.payload);
|
||||
},
|
||||
);
|
||||
subscription.addUnlisten(unlistenUserStatusChanged);
|
||||
@@ -79,7 +82,7 @@ export async function initUserStatusListeners() {
|
||||
const userId = data?.userId as string | undefined;
|
||||
if (!userId) return;
|
||||
|
||||
friendsUserStatuses.update((current) => removeFromStore(current, userId));
|
||||
friendsPresenceStates.update((current) => removeFromStore(current, userId));
|
||||
});
|
||||
subscription.addUnlisten(unlistenFriendDisconnected);
|
||||
|
||||
@@ -90,8 +93,8 @@ export async function initUserStatusListeners() {
|
||||
}
|
||||
}
|
||||
|
||||
export function stopUserStatusListeners() {
|
||||
export function stopUserStatus() {
|
||||
subscription.stop();
|
||||
}
|
||||
|
||||
setupHmrCleanup(stopUserStatusListeners);
|
||||
setupHmrCleanup(stopUserStatus);
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import { writable } from "svelte/store";
|
||||
import type { InteractionPayloadDto } from "../../types/bindings/InteractionPayloadDto";
|
||||
|
||||
// Map senderUserId -> InteractionPayloadDto
|
||||
export const receivedInteractions = writable<Map<string, InteractionPayloadDto>>(new Map());
|
||||
|
||||
export function addInteraction(interaction: InteractionPayloadDto) {
|
||||
receivedInteractions.update((map) => {
|
||||
// For now, we only store the latest message per user.
|
||||
// In the future, we could store an array if we want a history.
|
||||
const newMap = new Map(map);
|
||||
newMap.set(interaction.senderUserId, interaction);
|
||||
return newMap;
|
||||
});
|
||||
}
|
||||
|
||||
export function clearInteraction(userId: string) {
|
||||
receivedInteractions.update((map) => {
|
||||
const newMap = new Map(map);
|
||||
newMap.delete(userId);
|
||||
return newMap;
|
||||
});
|
||||
}
|
||||
@@ -1,24 +1,29 @@
|
||||
<script>
|
||||
import { browser } from "$app/environment";
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
import { initCursorTracking, stopCursorTracking } from "../events/cursor";
|
||||
import { initAppDataListener } from "../events/app-data";
|
||||
import { initInteractionListeners, stopInteractionListeners } from "../events/interaction";
|
||||
import { startCursorTracking, stopCursorTracking } from "../events/cursor";
|
||||
import {
|
||||
initSceneInteractiveListener,
|
||||
stopSceneInteractiveListener,
|
||||
startFriendCursorTracking,
|
||||
stopFriendCursorTracking,
|
||||
} from "../events/friend-cursor";
|
||||
import { startAppData } from "../events/app-data";
|
||||
import { startInteraction, stopInteraction } from "../events/interaction";
|
||||
import {
|
||||
startSceneInteractive,
|
||||
stopSceneInteractive,
|
||||
} from "../events/scene-interactive";
|
||||
import { initUserStatusListeners, stopUserStatusListeners } from "../events/user-status";
|
||||
import { startUserStatus, stopUserStatus } from "../events/user-status";
|
||||
|
||||
let { children } = $props();
|
||||
if (browser) {
|
||||
onMount(async () => {
|
||||
try {
|
||||
await initCursorTracking();
|
||||
await initAppDataListener();
|
||||
await initSceneInteractiveListener();
|
||||
await initInteractionListeners();
|
||||
await initUserStatusListeners();
|
||||
await startAppData();
|
||||
await startCursorTracking();
|
||||
await startFriendCursorTracking();
|
||||
await startSceneInteractive();
|
||||
await startInteraction();
|
||||
await startUserStatus();
|
||||
} catch (err) {
|
||||
console.error("Failed to initialize event listeners:", err);
|
||||
}
|
||||
@@ -26,9 +31,10 @@
|
||||
|
||||
onDestroy(() => {
|
||||
stopCursorTracking();
|
||||
stopSceneInteractiveListener();
|
||||
stopInteractionListeners();
|
||||
stopUserStatusListeners();
|
||||
stopFriendCursorTracking();
|
||||
stopSceneInteractive();
|
||||
stopInteraction();
|
||||
stopUserStatus();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<script lang="ts">
|
||||
import {
|
||||
cursorPositionOnScreen,
|
||||
friendsCursorPositions,
|
||||
} from "../../events/cursor";
|
||||
import { cursorPositionOnScreen } from "../../events/cursor";
|
||||
import { friendsCursorPositions } from "../../events/friend-cursor";
|
||||
import { appData } from "../../events/app-data";
|
||||
import { sceneInteractive } from "../../events/scene-interactive";
|
||||
import {
|
||||
friendsUserStatuses,
|
||||
currentUserStatus,
|
||||
friendsPresenceStates,
|
||||
currentPresenceState,
|
||||
} from "../../events/user-status";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import DebugBar from "./components/debug-bar.svelte";
|
||||
@@ -28,10 +26,10 @@
|
||||
<DebugBar
|
||||
isInteractive={$sceneInteractive}
|
||||
cursorPosition={$cursorPositionOnScreen}
|
||||
presenceStatus={$currentUserStatus?.presenceStatus ?? null}
|
||||
presenceStatus={$currentPresenceState?.presenceStatus ?? null}
|
||||
friendsCursorPositions={$friendsCursorPositions}
|
||||
friends={$appData?.friends ?? []}
|
||||
friendsUserStatuses={$friendsUserStatuses}
|
||||
friendsPresenceStates={$friendsPresenceStates}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import type { PresenceStatus } from "../../../types/bindings/PresenceStatus";
|
||||
import type { UserStatus } from "../../../events/user-status";
|
||||
import type { PresenceState } from "../../../events/user-status";
|
||||
|
||||
interface Friend {
|
||||
friend?: {
|
||||
@@ -15,7 +15,7 @@
|
||||
presenceStatus: PresenceStatus | null;
|
||||
friendsCursorPositions: Record<string, { mapped: { x: number; y: number } }>;
|
||||
friends: Friend[];
|
||||
friendsUserStatuses: Record<string, UserStatus>;
|
||||
friendsPresenceStates: Record<string, PresenceState>;
|
||||
}
|
||||
|
||||
let {
|
||||
@@ -24,7 +24,7 @@
|
||||
presenceStatus,
|
||||
friendsCursorPositions,
|
||||
friends,
|
||||
friendsUserStatuses,
|
||||
friendsPresenceStates,
|
||||
}: Props = $props();
|
||||
|
||||
function getFriendById(userId: string) {
|
||||
@@ -33,7 +33,7 @@
|
||||
}
|
||||
|
||||
function getFriendStatus(userId: string) {
|
||||
return friendsUserStatuses[userId];
|
||||
return friendsPresenceStates[userId];
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user