diff --git a/src/renderer/components/communication/ChannelSidebar.tsx b/src/renderer/components/communication/ChannelSidebar.tsx index 05c7e7e0..c39effd8 100644 --- a/src/renderer/components/communication/ChannelSidebar.tsx +++ b/src/renderer/components/communication/ChannelSidebar.tsx @@ -5,7 +5,7 @@ import type { AgentRecord, MessageChannel } from "@shared/types" import { AgentAvatar } from "./MessageItem" import type { ChannelDescriptor, TaskDiscussionDescriptor } from "./ChannelHeader" import { useT } from "../../i18n" -import { Eyebrow } from "../ui" +import { Eyebrow, Select } from "../ui" type ChannelConfig = { labelKey: string; icon: React.ElementType } @@ -68,10 +68,7 @@ function ChannelItem({ {hasUrgent ? ( ) : unreadCount > 0 ? ( - + {unreadCount > 99 ? "99+" : unreadCount} ) : null} @@ -204,8 +201,7 @@ export function FilterBar({ onChange={(e) => onChangeFilters({ ...filters, search: e.target.value })} onKeyDown={onSearchKeyDown} placeholder={t("comm.searchMessages")} - className="w-full rounded-lg border border-border bg-card py-1.5 pl-8 pr-3 text-[11px] text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-1" - style={{ focusRingColor: "var(--primary)" } as React.CSSProperties} + className="w-full rounded-lg border border-border bg-card py-1.5 pl-8 pr-3 text-[11px] text-foreground placeholder:text-muted-foreground focus:border-[color:var(--primary)] focus:outline-none focus:ring-1 focus:ring-[color:var(--primary)]" /> {scopeToggle} @@ -214,14 +210,9 @@ export function FilterBar({ onClick={() => setExpanded(!expanded)} className={`flex items-center gap-1.5 rounded-lg border px-2.5 py-1.5 text-[11px] font-medium transition ${ expanded || filters.channelType !== "all" || filters.priority !== "all" || filters.unreadOnly - ? "border-transparent text-primary-foreground" + ? "border-transparent bg-primary text-primary-foreground" : "border-border text-muted-foreground hover:border-border" }`} - style={ - expanded || filters.channelType !== "all" || filters.priority !== "all" || filters.unreadOnly - ? { backgroundColor: "var(--primary)" } - : undefined - } > {t("comm.filters")} @@ -236,35 +227,36 @@ export function FilterBar({ exit={{ opacity: 0, height: 0 }} className="flex flex-wrap items-center gap-2 overflow-hidden" > - - onChangeFilters({ ...filters, priority: e.target.value })} - className="rounded-lg border border-border bg-card px-2 py-1 text-[11px] font-medium text-foreground" - > - - - - - + onChange={(v) => onChangeFilters({ ...filters, priority: v })} + options={[ + { value: "all", label: t("comm.allPriorities") }, + { value: "urgent", label: t("comm.urgent") }, + { value: "normal", label: t("comm.normal") }, + { value: "low", label: t("comm.low") }, + ]} + /> diff --git a/src/renderer/components/communication/MessageComposer.tsx b/src/renderer/components/communication/MessageComposer.tsx index 55652da4..9362879e 100644 --- a/src/renderer/components/communication/MessageComposer.tsx +++ b/src/renderer/components/communication/MessageComposer.tsx @@ -119,7 +119,7 @@ export function MessageComposer({ placeholder={t("composer.typeMessage")} sending={sending} error={sendError} - shortcutHint={`Press ${cmdOrCtrlLabel()}+Enter to send`} + shortcutHint={t("comm.sendShortcut").replace("{0}", cmdOrCtrlLabel())} sendLabel={t("composer.sendMessage")} sendDisabled={!body.trim() || (channel === "direct" && !directRecipientId)} leading={ diff --git a/src/renderer/components/communication/ThreadPanel.tsx b/src/renderer/components/communication/ThreadPanel.tsx index a6d0d69d..7afa75e2 100644 --- a/src/renderer/components/communication/ThreadPanel.tsx +++ b/src/renderer/components/communication/ThreadPanel.tsx @@ -12,6 +12,7 @@ import { motion } from "framer-motion" import type { AgentRecord, ConversationEventRecord, ThreadWaitStateRecord, ConversationThreadRecord, DocumentRecord } from "@shared/types" import WaitStateIndicator, { type WaitStateInfo } from "./WaitStateIndicator" import { MessageComposer } from "./MessageComposer" +import { formatMessageTime } from "../../lib/formatters" import { useT, type TranslationFn } from "../../i18n" interface ThreadPanelProps { @@ -28,7 +29,7 @@ function EventItem({ event, agents, t }: { event: ConversationEventRecord; agent ? t("thread.actor.you") : agents.find((a) => a.id === event.actorId)?.name ?? event.actorId - const time = new Date(event.createdAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) + const time = formatMessageTime(event.createdAt) const iconClass = event.eventType === "status_change" ? "text-primary"