Skip to content

Commit 92e6450

Browse files
t3dotggclaude
andauthored
fix(web,mobile): queued messages get a simpler Send now row, no reordering (#25846)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 4cb29a5 commit 92e6450

11 files changed

Lines changed: 140 additions & 591 deletions

File tree

‎apps/mobile/src/features/threads/ThreadQueueControl.tsx‎

Lines changed: 99 additions & 333 deletions
Large diffs are not rendered by default.

‎apps/mobile/src/features/threads/floating-working-control.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ export function FloatingWorkingControl(props: {
243243
<Pressable
244244
accessibilityRole="button"
245245
accessibilityLabel={`Open queue, ${props.queuedCount} messages`}
246-
accessibilityHint="Opens queued messages for reordering, steering, or removal"
246+
accessibilityHint="Opens queued messages to send now, edit, or remove"
247247
onPress={props.onOpenQueue}
248248
onLayout={(event) => setQueueWidth(settleWidth(event.nativeEvent.layout.width))}
249249
style={{ maxWidth: Math.min(overlayWidth, windowWidth) * 0.45 }}
Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import { formatAssistantCitationHref } from "@t3tools/shared/assistantCitations";
22
import { describe, expect, it } from "vite-plus/test";
33

4-
import {
5-
resolveThreadQueueRowControls,
6-
resolveQueueDropBeforeRunId,
7-
} from "./threadQueueControlPresentation";
4+
import { resolveThreadQueueRowControls } from "./threadQueueControlPresentation";
85

96
describe("threadQueueControlPresentation", () => {
107
it.each([
@@ -19,9 +16,6 @@ describe("threadQueueControlPresentation", () => {
1916
isEditing,
2017
canPromoteToSteer: false,
2118
canSendNow: true,
22-
canReorder: false,
23-
index: 0,
24-
queuedCount: 1,
2519
text: "Queued message",
2620
});
2721

@@ -45,9 +39,6 @@ describe("threadQueueControlPresentation", () => {
4539
busy: false,
4640
canPromoteToSteer: true,
4741
canSendNow: false,
48-
canReorder: true,
49-
index: 0,
50-
queuedCount: 1,
5142
text: `[Assistant quote](${href}) Can we add a backoff here?`,
5243
});
5344

@@ -61,17 +52,13 @@ describe("threadQueueControlPresentation", () => {
6152
busy: false,
6253
canPromoteToSteer: true,
6354
canSendNow: false,
64-
canReorder: true,
65-
index: 1,
6655
isEditing: true,
67-
queuedCount: 3,
6856
text: "Being edited",
6957
});
7058

7159
expect(editing.isEditing).toBe(true);
7260
expect(editing.canEdit).toBe(false);
7361
expect(editing.canSend).toBe(false);
74-
expect(editing.canMoveUp).toBe(true);
7562
expect(editing.canDismiss).toBe(true);
7663
});
7764

@@ -80,35 +67,11 @@ describe("threadQueueControlPresentation", () => {
8067
busy: false,
8168
canPromoteToSteer: true,
8269
canSendNow: false,
83-
canReorder: true,
84-
index: 0,
8570
isGuestMessage: true,
86-
queuedCount: 1,
8771
text: "Why?",
8872
});
8973

9074
expect(guest.canEdit).toBe(false);
9175
expect(guest.canDismiss).toBe(true);
9276
});
9377
});
94-
95-
describe("queue drag insertion", () => {
96-
const rows = [
97-
{ id: "first" as never, y: 0, height: 80 },
98-
{ id: "second" as never, y: 80, height: 140 },
99-
{ id: "third" as never, y: 220, height: 80 },
100-
];
101-
102-
it("moves between variable-height rows and to either end", () => {
103-
expect(resolveQueueDropBeforeRunId(rows, rows[0]!.id, 140)).toBe("third");
104-
expect(resolveQueueDropBeforeRunId(rows, rows[0]!.id, 300)).toBeNull();
105-
expect(resolveQueueDropBeforeRunId(rows, rows[2]!.id, -300)).toBe("first");
106-
});
107-
108-
it("does not send a reorder for an unchanged or unmeasured drop", () => {
109-
expect(resolveQueueDropBeforeRunId(rows, rows[1]!.id, 0)).toBeUndefined();
110-
expect(resolveQueueDropBeforeRunId(rows, rows[2]!.id, 20)).toBeUndefined();
111-
expect(resolveQueueDropBeforeRunId([{ id: rows[0]!.id }], rows[0]!.id, 10)).toBeUndefined();
112-
expect(resolveQueueDropBeforeRunId(rows, "missing" as never, 100)).toBeUndefined();
113-
});
114-
});

‎apps/mobile/src/features/threads/threadQueueControlPresentation.ts‎

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ export const REMOVE_QUEUED_MESSAGE_ACCESSIBILITY_LABEL = "Remove queued message"
66
export interface ThreadQueueRowControls {
77
readonly canDismiss: boolean;
88
readonly canEdit: boolean;
9-
readonly canMoveDown: boolean;
10-
readonly canMoveUp: boolean;
119
readonly canSend: boolean;
1210
readonly dismissAccessibilityLabel: string;
1311
readonly displayText: string;
@@ -18,14 +16,11 @@ export function resolveThreadQueueRowControls(input: {
1816
readonly busy: boolean;
1917
readonly canPromoteToSteer: boolean;
2018
readonly canSendNow: boolean;
21-
readonly canReorder: boolean;
2219
/** Something else holds the composer, such as an open question. */
2320
readonly editBlocked?: boolean;
24-
readonly index: number;
2521
readonly isEditing?: boolean;
2622
/** A guest's message keeps the guest's words; the owner can cancel it, not rewrite it. */
2723
readonly isGuestMessage?: boolean;
28-
readonly queuedCount: number;
2924
readonly text: string;
3025
}): ThreadQueueRowControls {
3126
const mutationEnabled = !input.busy;
@@ -37,8 +32,6 @@ export function resolveThreadQueueRowControls(input: {
3732
// away whatever has been typed since.
3833
canEdit:
3934
mutationEnabled && !isEditing && input.isGuestMessage !== true && input.editBlocked !== true,
40-
canMoveDown: mutationEnabled && input.canReorder && input.index < input.queuedCount - 1,
41-
canMoveUp: mutationEnabled && input.canReorder && input.index > 0,
4235
canSend: mutationEnabled && (input.canPromoteToSteer || input.canSendNow) && !isEditing,
4336
dismissAccessibilityLabel: REMOVE_QUEUED_MESSAGE_ACCESSIBILITY_LABEL,
4437
// Editing and sending keep the original text so quoted citations stay linked.
@@ -66,27 +59,3 @@ export function buildCancelQueuedRunCommand(input: {
6659
},
6760
};
6861
}
69-
70-
export function resolveQueueDragBeforeRunId(
71-
rows: ReadonlyArray<{ id: RunId; y?: number; height?: number }>,
72-
runId: RunId,
73-
translationY: number,
74-
): RunId | null | undefined {
75-
const sourceIndex = rows.findIndex((row) => row.id === runId);
76-
const source = rows[sourceIndex];
77-
if (!source || rows.some((row) => row.y === undefined || row.height === undefined)) return;
78-
const center = source.y! + source.height! / 2 + translationY;
79-
const remaining = rows.filter((row) => row.id !== runId);
80-
return remaining.find((row) => center < row.y! + row.height! / 2)?.id ?? null;
81-
}
82-
83-
export function resolveQueueDropBeforeRunId(
84-
rows: ReadonlyArray<{ id: RunId; y?: number; height?: number }>,
85-
runId: RunId,
86-
translationY: number,
87-
): RunId | null | undefined {
88-
const before = resolveQueueDragBeforeRunId(rows, runId, translationY);
89-
if (before === undefined) return;
90-
const sourceIndex = rows.findIndex((row) => row.id === runId);
91-
return before === (rows[sourceIndex + 1]?.id ?? null) ? undefined : before;
92-
}

‎apps/web/src/components/chat/QueuedRunsControl.browser.test.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ it("previews assistant quotes as readable text and preserves the citation when e
7171
state.workflow = {
7272
activeRun: { id: "run:active" },
7373
canPromoteToSteer: true,
74-
canReorder: true,
7574
queuedRuns: [
7675
{
7776
run: { id: "run:quote-only", userMessageId: "message:quote-only" },

0 commit comments

Comments
 (0)