mirror of
https://github.com/block/buzz.git
synced 2026-11-11 20:01:09 +00:00
fix(desktop): show unavailable activity state
Co-authored-by: Rizz <302abe414ca6e3134763d2539bfcf145aea2a63fe5f8455204ed602fd40cf381@buzz.block.builderlab.xyz> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import * as React from "react";
|
||||
import { Hash, LogIn } from "lucide-react";
|
||||
import { Hash, LoaderCircle, LogIn } from "lucide-react";
|
||||
import { AnimatePresence } from "motion/react";
|
||||
import { useAppNavigation } from "@/app/navigation/useAppNavigation";
|
||||
import { useMediaUpload } from "@/features/messages/lib/useMediaUpload";
|
||||
@@ -87,6 +87,7 @@ export const ChannelPane = React.memo(function ChannelPane({
|
||||
isMessageUnreadById,
|
||||
isJoining = false,
|
||||
isSinglePanelView = false,
|
||||
isAgentSessionLoading = false,
|
||||
isSending,
|
||||
isTimelineLoading,
|
||||
entranceMessageId = null,
|
||||
@@ -914,6 +915,30 @@ export const ChannelPane = React.memo(function ChannelPane({
|
||||
);
|
||||
return wrapAux(panel, "agent-session-thread-panel");
|
||||
})()
|
||||
) : isSinglePanelView && openAgentSessionPubkey ? (
|
||||
<div
|
||||
className="flex min-h-0 flex-1 items-center justify-center p-8 text-center"
|
||||
data-testid="agent-session-unavailable"
|
||||
>
|
||||
<div className="max-w-sm space-y-2">
|
||||
{isAgentSessionLoading ? (
|
||||
<LoaderCircle
|
||||
aria-hidden="true"
|
||||
className="mx-auto h-5 w-5 animate-spin text-muted-foreground"
|
||||
/>
|
||||
) : null}
|
||||
<h1 className="text-lg font-semibold">
|
||||
{isAgentSessionLoading
|
||||
? "Loading agent activity…"
|
||||
: "Agent activity unavailable"}
|
||||
</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{isAgentSessionLoading
|
||||
? "Buzz is finding this agent."
|
||||
: "This agent is no longer available in this community. You can close this window and open another activity feed from Buzz."}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
) : profilePanelPubkey ? (
|
||||
(() => {
|
||||
const panel = (
|
||||
|
||||
@@ -54,6 +54,7 @@ export type ChannelPaneProps = {
|
||||
isHuddleTranscript?: boolean;
|
||||
isJoining?: boolean;
|
||||
isSinglePanelView?: boolean;
|
||||
isAgentSessionLoading?: boolean;
|
||||
isSending: boolean;
|
||||
isTimelineLoading: boolean;
|
||||
/** Newly-created message that should receive the one-shot conversation arrival motion. */
|
||||
|
||||
@@ -306,6 +306,10 @@ export function ChannelScreen({
|
||||
welcomeGuideAgent,
|
||||
});
|
||||
const relayAgentsQuery = useRelayAgentsQuery();
|
||||
const agentsLoading =
|
||||
channelMembersQuery.isLoading ||
|
||||
managedAgentsQuery.isLoading ||
|
||||
relayAgentsQuery.isLoading;
|
||||
const relayAgents = relayAgentsQuery.data ?? [];
|
||||
const knownAgentPubkeys = React.useMemo(
|
||||
() =>
|
||||
@@ -568,16 +572,14 @@ export function ChannelScreen({
|
||||
} = useChannelAgentSessions({
|
||||
activeChannel,
|
||||
activeChannelId,
|
||||
agentsLoaded:
|
||||
!channelMembersQuery.isLoading &&
|
||||
!managedAgentsQuery.isLoading &&
|
||||
!relayAgentsQuery.isLoading,
|
||||
agentsLoaded: !agentsLoading,
|
||||
channelMembers,
|
||||
handleOpenThread,
|
||||
managedAgents: agentSessionCandidates,
|
||||
openAgentSessionPubkey,
|
||||
openThreadHeadId: effectiveOpenThreadHeadId,
|
||||
profilePanelPubkey,
|
||||
preserveUnresolvedSession: isDedicatedActivityWindow,
|
||||
setChannelManagementOpen,
|
||||
setExpandedThreadReplyIds,
|
||||
setOpenAgentSessionChannelId,
|
||||
@@ -890,6 +892,7 @@ export function ChannelScreen({
|
||||
isMessageUnreadById={isMessageUnread}
|
||||
isFollowingThread={isNotifiedForEffectiveThread}
|
||||
isSending={sendMessageMutation.isPending}
|
||||
isAgentSessionLoading={agentsLoading}
|
||||
isSinglePanelView={isSinglePanelView}
|
||||
isTimelineLoading={isTimelineLoading}
|
||||
messages={timelineMessages}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import { shouldClearUnresolvedAgentSession } from "./useChannelAgentSessions.ts";
|
||||
|
||||
const unresolvedSession = {
|
||||
agentSessionAgents: [],
|
||||
agentsLoaded: true,
|
||||
openAgentSessionPubkey: "agent-pubkey",
|
||||
profilePanelPubkey: null,
|
||||
};
|
||||
|
||||
test("dedicated activity windows preserve unresolved sessions for an empty state", () => {
|
||||
assert.equal(
|
||||
shouldClearUnresolvedAgentSession({
|
||||
...unresolvedSession,
|
||||
preserveUnresolvedSession: true,
|
||||
}),
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test("the in-app panel still clears stale unresolved sessions", () => {
|
||||
assert.equal(
|
||||
shouldClearUnresolvedAgentSession({
|
||||
...unresolvedSession,
|
||||
preserveUnresolvedSession: false,
|
||||
}),
|
||||
true,
|
||||
);
|
||||
});
|
||||
@@ -39,6 +39,7 @@ type UseChannelAgentSessionsOptions = {
|
||||
openAgentSessionPubkey: string | null;
|
||||
openThreadHeadId: string | null;
|
||||
profilePanelPubkey?: string | null;
|
||||
preserveUnresolvedSession?: boolean;
|
||||
setChannelManagementOpen: (open: boolean) => void;
|
||||
setExpandedThreadReplyIds: (value: Set<string>) => void;
|
||||
setOpenAgentSessionChannelId: PanelValueSetter;
|
||||
@@ -163,6 +164,33 @@ export function getChannelAgentSessionAgents({
|
||||
});
|
||||
}
|
||||
|
||||
export function shouldClearUnresolvedAgentSession({
|
||||
agentSessionAgents,
|
||||
agentsLoaded,
|
||||
openAgentSessionPubkey,
|
||||
preserveUnresolvedSession,
|
||||
profilePanelPubkey,
|
||||
}: {
|
||||
agentSessionAgents: ChannelAgentSessionAgent[];
|
||||
agentsLoaded: boolean;
|
||||
openAgentSessionPubkey: string | null;
|
||||
preserveUnresolvedSession: boolean;
|
||||
profilePanelPubkey: string | null;
|
||||
}): boolean {
|
||||
return Boolean(
|
||||
openAgentSessionPubkey &&
|
||||
!preserveUnresolvedSession &&
|
||||
agentsLoaded &&
|
||||
normalizePubkey(profilePanelPubkey ?? "") !==
|
||||
normalizePubkey(openAgentSessionPubkey) &&
|
||||
!agentSessionAgents.some(
|
||||
(agent) =>
|
||||
normalizePubkey(agent.pubkey) ===
|
||||
normalizePubkey(openAgentSessionPubkey),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export function useChannelAgentSessions({
|
||||
activeChannel,
|
||||
activeChannelId,
|
||||
@@ -173,6 +201,7 @@ export function useChannelAgentSessions({
|
||||
openAgentSessionPubkey,
|
||||
openThreadHeadId,
|
||||
profilePanelPubkey = null,
|
||||
preserveUnresolvedSession = false,
|
||||
setChannelManagementOpen,
|
||||
setExpandedThreadReplyIds,
|
||||
setOpenAgentSessionChannelId,
|
||||
@@ -298,15 +327,13 @@ export function useChannelAgentSessions({
|
||||
// agent queries have settled. Once loaded, a channel that legitimately has
|
||||
// zero agents will still auto-close a stale param.
|
||||
if (
|
||||
openAgentSessionPubkey &&
|
||||
agentsLoaded &&
|
||||
normalizePubkey(profilePanelPubkey ?? "") !==
|
||||
normalizePubkey(openAgentSessionPubkey) &&
|
||||
!agentSessionAgents.some(
|
||||
(agent) =>
|
||||
normalizePubkey(agent.pubkey) ===
|
||||
normalizePubkey(openAgentSessionPubkey),
|
||||
)
|
||||
shouldClearUnresolvedAgentSession({
|
||||
agentSessionAgents,
|
||||
agentsLoaded,
|
||||
openAgentSessionPubkey,
|
||||
preserveUnresolvedSession,
|
||||
profilePanelPubkey,
|
||||
})
|
||||
) {
|
||||
returnTarget.clear();
|
||||
setOpenAgentSessionPubkey(null, { replace: true });
|
||||
@@ -315,6 +342,7 @@ export function useChannelAgentSessions({
|
||||
agentSessionAgents,
|
||||
agentsLoaded,
|
||||
openAgentSessionPubkey,
|
||||
preserveUnresolvedSession,
|
||||
profilePanelPubkey,
|
||||
returnTarget,
|
||||
setOpenAgentSessionPubkey,
|
||||
|
||||
Reference in New Issue
Block a user