Skip to content

Commit ceb322e

Browse files
committed
feat: add message scheduling via right-click on Send button
- Added dropdown menu to Send button with scheduling option - Right-click or dropdown opens menu with 'Send message' and 'Schedule for after task completion' options - Updated QueuedMessages component to show scheduled messages with clock icon - Added translations for new scheduling feature - Messages can be scheduled to send automatically after current task completes Fixes #7738
1 parent e8deedd commit ceb322e

File tree

3 files changed

+75
-23
lines changed

3 files changed

+75
-23
lines changed

webview-ui/src/components/chat/ChatTextArea.tsx

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { forwardRef, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"
22
import { useEvent } from "react-use"
33
import DynamicTextArea from "react-textarea-autosize"
4-
import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX } from "lucide-react"
4+
import { VolumeX, Image, WandSparkles, SendHorizontal, MessageSquareX, Clock } from "lucide-react"
55

66
import { mentionRegex, mentionRegexGlobal, commandRegexGlobal, unescapeSpaces } from "@roo/context-mentions"
77
import { WebviewMessage } from "@roo/WebviewMessage"
@@ -21,7 +21,13 @@ import {
2121
} from "@src/utils/context-mentions"
2222
import { cn } from "@src/lib/utils"
2323
import { convertToMentionPath } from "@src/utils/path-mentions"
24-
import { StandardTooltip } from "@src/components/ui"
24+
import {
25+
StandardTooltip,
26+
DropdownMenu,
27+
DropdownMenuContent,
28+
DropdownMenuItem,
29+
DropdownMenuTrigger,
30+
} from "@src/components/ui"
2531

2632
import Thumbnails from "../common/Thumbnails"
2733
import { ModeSelector } from "./ModeSelector"
@@ -1102,7 +1108,7 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
11021108
</StandardTooltip>
11031109
</div>
11041110

1105-
<div className="absolute bottom-1 right-1 z-30">
1111+
<div className="absolute bottom-1 right-1 z-30 flex items-center gap-1">
11061112
{isEditMode && (
11071113
<StandardTooltip content={t("chat:cancel.title")}>
11081114
<button
@@ -1124,25 +1130,66 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
11241130
</button>
11251131
</StandardTooltip>
11261132
)}
1127-
<StandardTooltip content={t("chat:sendMessage")}>
1128-
<button
1129-
aria-label={t("chat:sendMessage")}
1130-
disabled={false}
1131-
onClick={onSend}
1132-
className={cn(
1133-
"relative inline-flex items-center justify-center",
1134-
"bg-transparent border-none p-1.5",
1135-
"rounded-md min-w-[28px] min-h-[28px]",
1136-
"opacity-60 hover:opacity-100 text-vscode-descriptionForeground hover:text-vscode-foreground",
1137-
"transition-all duration-150",
1138-
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
1139-
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
1140-
"active:bg-[rgba(255,255,255,0.1)]",
1141-
"cursor-pointer",
1142-
)}>
1143-
<SendHorizontal className="w-4 h-4" />
1144-
</button>
1145-
</StandardTooltip>
1133+
<DropdownMenu>
1134+
<DropdownMenuTrigger asChild>
1135+
<button
1136+
aria-label={t("chat:sendMessage")}
1137+
disabled={false}
1138+
onContextMenu={(e) => {
1139+
e.preventDefault()
1140+
// Trigger dropdown on right-click
1141+
const event = new MouseEvent("click", {
1142+
bubbles: true,
1143+
cancelable: true,
1144+
view: window,
1145+
})
1146+
e.currentTarget.dispatchEvent(event)
1147+
}}
1148+
onClick={(e) => {
1149+
// If it's a regular left click, just send the message
1150+
if (e.button === 0 && !e.ctrlKey && !e.metaKey) {
1151+
e.preventDefault()
1152+
e.stopPropagation()
1153+
onSend()
1154+
}
1155+
}}
1156+
className={cn(
1157+
"relative inline-flex items-center justify-center",
1158+
"bg-transparent border-none p-1.5",
1159+
"rounded-md min-w-[28px] min-h-[28px]",
1160+
"opacity-60 hover:opacity-100 text-vscode-descriptionForeground hover:text-vscode-foreground",
1161+
"transition-all duration-150",
1162+
"hover:bg-[rgba(255,255,255,0.03)] hover:border-[rgba(255,255,255,0.15)]",
1163+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-vscode-focusBorder",
1164+
"active:bg-[rgba(255,255,255,0.1)]",
1165+
"cursor-pointer",
1166+
)}>
1167+
<SendHorizontal className="w-4 h-4" />
1168+
</button>
1169+
</DropdownMenuTrigger>
1170+
<DropdownMenuContent align="end" className="w-56">
1171+
<DropdownMenuItem onClick={onSend}>
1172+
<SendHorizontal className="mr-2 h-4 w-4" />
1173+
<span>{t("chat:sendMessage")}</span>
1174+
</DropdownMenuItem>
1175+
<DropdownMenuItem
1176+
onClick={() => {
1177+
// Queue the message for after task completion
1178+
if (inputValue.trim() || selectedImages.length > 0) {
1179+
vscode.postMessage({
1180+
type: "queueMessage",
1181+
text: inputValue,
1182+
images: selectedImages,
1183+
})
1184+
setInputValue("")
1185+
setSelectedImages([])
1186+
}
1187+
}}>
1188+
<Clock className="mr-2 h-4 w-4" />
1189+
<span>{t("chat:scheduleForAfterTask")}</span>
1190+
</DropdownMenuItem>
1191+
</DropdownMenuContent>
1192+
</DropdownMenu>
11461193
</div>
11471194

11481195
{!inputValue && (

webview-ui/src/components/chat/QueuedMessages.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ export const QueuedMessages = ({ queue, onRemove, onUpdate }: QueuedMessagesProp
4141

4242
return (
4343
<div className="px-[15px] py-[10px] pr-[6px]" data-testid="queued-messages">
44-
<div className="text-vscode-descriptionForeground text-md mb-2">{t("queuedMessages.title")}</div>
44+
<div className="text-vscode-descriptionForeground text-md mb-2">
45+
<span className="codicon codicon-clock mr-2" />
46+
{t("queuedMessages.scheduledTitle")}
47+
</div>
4548
<div className="flex flex-col gap-2 max-h-[300px] overflow-y-auto pr-2">
4649
{queue.map((message, index) => {
4750
const editState = getEditState(message.id, message.text)

webview-ui/src/i18n/locales/en/chat.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
"enhancePromptDescription": "The 'Enhance Prompt' button helps improve your prompt by providing additional context, clarification, or rephrasing. Try typing a prompt in here and clicking the button again to see how it works.",
129129
"addImages": "Add images to message",
130130
"sendMessage": "Send message",
131+
"scheduleForAfterTask": "Schedule for after task completion",
131132
"stopTts": "Stop text-to-speech",
132133
"typeMessage": "Type a message...",
133134
"typeTask": "Type your task here...",
@@ -387,6 +388,7 @@
387388
},
388389
"queuedMessages": {
389390
"title": "Queued Messages:",
391+
"scheduledTitle": "Scheduled for after task completion",
390392
"clickToEdit": "Click to edit message"
391393
}
392394
}

0 commit comments

Comments
 (0)