display peer active app info on pet & in pet menu

This commit is contained in:
2026-02-05 00:13:33 +08:00
parent 4152491ca4
commit 4e2e19c60a
3 changed files with 39 additions and 6 deletions

View File

@@ -138,6 +138,7 @@
targetX={position.mapped.x * innerWidth} targetX={position.mapped.x * innerWidth}
targetY={position.mapped.y * innerHeight} targetY={position.mapped.y * innerHeight}
user={getFriendById(userId)} user={getFriendById(userId)}
userStatus={getFriendStatus(userId)}
{doll} {doll}
{isInteractive} {isInteractive}
/> />

View File

@@ -12,11 +12,14 @@
import PetMenu from "./PetMenu.svelte"; import PetMenu from "./PetMenu.svelte";
import type { DollDto } from "../../../types/bindings/DollDto"; import type { DollDto } from "../../../types/bindings/DollDto";
import type { UserBasicDto } from "../../../types/bindings/UserBasicDto"; import type { UserBasicDto } from "../../../types/bindings/UserBasicDto";
import type { AppMetadata } from "../../../types/bindings/AppMetadata";
import type { FriendUserStatus } from "../../../events/user-status";
export let id = ""; export let id = "";
export let targetX = 0; export let targetX = 0;
export let targetY = 0; export let targetY = 0;
export let user: UserBasicDto; export let user: UserBasicDto;
export let userStatus: FriendUserStatus | undefined = undefined;
export let doll: DollDto | undefined = undefined; export let doll: DollDto | undefined = undefined;
export let isInteractive = false; export let isInteractive = false;
@@ -37,10 +40,12 @@
$: { $: {
const interaction = $receivedInteractions.get(user.id); const interaction = $receivedInteractions.get(user.id);
if (interaction && interaction.content !== receivedMessage) { if (interaction && interaction.content !== receivedMessage) {
console.log(`Received interaction for ${user.id}: ${interaction.content}`); console.log(
`Received interaction for ${user.id}: ${interaction.content}`,
);
receivedMessage = interaction.content; receivedMessage = interaction.content;
isPetMenuOpen = true; isPetMenuOpen = true;
// Make scene interactive so user can see it // Make scene interactive so user can see it
invoke("set_scene_interactive", { invoke("set_scene_interactive", {
interactive: true, interactive: true,
@@ -79,9 +84,9 @@
// When we force it via invoke("set_scene_interactive", { interactive: true }), it might not reflect back into `isInteractive` prop immediately or correctly depending on how the parent passes it. // When we force it via invoke("set_scene_interactive", { interactive: true }), it might not reflect back into `isInteractive` prop immediately or correctly depending on how the parent passes it.
// Actually, `isInteractive` is a prop passed from +page.svelte probably based on hover state. // Actually, `isInteractive` is a prop passed from +page.svelte probably based on hover state.
// If we want the menu to stay open during the message, we should probably ignore this auto-close behavior if a message is present. // If we want the menu to stay open during the message, we should probably ignore this auto-close behavior if a message is present.
$: if (!receivedMessage && !isInteractive) { $: if (!receivedMessage && !isInteractive) {
isPetMenuOpen = false; isPetMenuOpen = false;
} }
$: { $: {
@@ -143,13 +148,24 @@
> >
{#if isPetMenuOpen} {#if isPetMenuOpen}
<div <div
class="absolute -translate-y-24 w-50 h-22 *:size-full shadow-md rounded" class="z-10 absolute -translate-y-30 w-50 h-28 *:size-full shadow-md rounded"
role="menu" role="menu"
tabindex="0" tabindex="0"
aria-label="Pet Menu" aria-label="Pet Menu"
> >
{#if doll} {#if doll}
<PetMenu {doll} {user} {receivedMessage} /> <PetMenu {doll} {user} {userStatus} {receivedMessage} />
{/if}
</div>
{/if}
{#if userStatus}
<div class="absolute -top-5 left-0 right-0 w-max mx-auto">
{#if userStatus.appMetadata.appIconB64}
<img
src={`data:image/png;base64,${userStatus.appMetadata.appIconB64}`}
alt="Friend's active app icon"
class="size-4"
/>
{/if} {/if}
</div> </div>
{/if} {/if}

View File

@@ -3,9 +3,11 @@
import { type DollDto } from "../../../types/bindings/DollDto"; import { type DollDto } from "../../../types/bindings/DollDto";
import type { UserBasicDto } from "../../../types/bindings/UserBasicDto"; import type { UserBasicDto } from "../../../types/bindings/UserBasicDto";
import type { SendInteractionDto } from "../../../types/bindings/SendInteractionDto"; import type { SendInteractionDto } from "../../../types/bindings/SendInteractionDto";
import type { FriendUserStatus } from "../../../events/user-status";
export let doll: DollDto; export let doll: DollDto;
export let user: UserBasicDto; export let user: UserBasicDto;
export let userStatus: FriendUserStatus | undefined = undefined;
export let receivedMessage: string | undefined = undefined; export let receivedMessage: string | undefined = undefined;
let showMessageInput = false; let showMessageInput = false;
@@ -45,6 +47,20 @@
<p class="text-sm font-semibold">{doll.name}</p> <p class="text-sm font-semibold">{doll.name}</p>
<p class="text-[0.6rem] opacity-50">From {user.name}</p> <p class="text-[0.6rem] opacity-50">From {user.name}</p>
</div> </div>
{#if userStatus}
<div class="card bg-base-200 px-2 py-1 flex flex-row gap-2 items-center">
{#if userStatus.appMetadata.appIconB64}
<img
src={`data:image/png;base64,${userStatus.appMetadata.appIconB64}`}
alt="Friend's active app icon"
class="size-3"
/>
{/if}
<p class="text-[0.6rem] font-mono text-ellipsis line-clamp-1">
{userStatus.appMetadata.localized}
</p>
</div>
{/if}
{#if receivedMessage} {#if receivedMessage}
<div class=""> <div class="">