MCPcopy Create free account
hub / github.com/agegr/pi-web / UserMessageView

Function UserMessageView

components/MessageView.tsx:139–337  ·  view source on GitHub ↗
({ message, cwd, onOpenFile, entryId, onFork, forking, onNavigate, prevAssistantEntryId, onEditContent }: {
  message: UserMessage;
  cwd?: string;
  onOpenFile?: (filePath: string) => void;
  entryId?: string;
  onFork?: (entryId: string) => void;
  forking?: boolean;
  onNavigate?: (entryId: string) => void;
  prevAssistantEntryId?: string;
  onEditContent?: (content: string) => void;
})

Source from the content-addressed store, hash-verified

137});
138
139function UserMessageView({ message, cwd, onOpenFile, entryId, onFork, forking, onNavigate, prevAssistantEntryId, onEditContent }: {
140 message: UserMessage;
141 cwd?: string;
142 onOpenFile?: (filePath: string) => void;
143 entryId?: string;
144 onFork?: (entryId: string) => void;
145 forking?: boolean;
146 onNavigate?: (entryId: string) => void;
147 prevAssistantEntryId?: string;
148 onEditContent?: (content: string) => void;
149}) {
150 const [hovered, setHovered] = useState(false);
151 const [copied, setCopied] = useState(false);
152
153 const content =
154 typeof message.content === "string"
155 ? message.content
156 : message.content
157 .filter((b): b is TextContent => b.type === "text")
158 .map((b) => b.text)
159 .join("\n");
160
161 const imageBlocks: ImageContent[] =
162 typeof message.content === "string"
163 ? []
164 : message.content.filter((b): b is ImageContent => b.type === "image");
165
166 const time = formatTime(message.timestamp);
167 const canFork = !!entryId && !!onFork;
168 const canNavigate = !!prevAssistantEntryId && !!onNavigate;
169
170 const copyContent = () => {
171 copyText(content).then(() => {
172 setCopied(true);
173 setTimeout(() => setCopied(false), 1500);
174 });
175 };
176
177 return (
178 <div
179 style={{ marginBottom: 16, display: "flex", flexDirection: "column", alignItems: "flex-end" }}
180 onMouseEnter={() => setHovered(true)}
181 onMouseLeave={() => setHovered(false)}
182 >
183 <div style={{ display: "flex", alignItems: "flex-end", gap: 6, maxWidth: "85%" }}>
184 <div
185 style={{
186 flex: 1,
187 minWidth: 0,
188 background: "var(--user-bg)",
189 border: "1px solid rgba(59,130,246,0.2)",
190 borderRadius: 12,
191 padding: "8px 12px",
192 fontSize: 14,
193 lineHeight: 1.6,
194 color: "var(--text)",
195 wordBreak: "break-word",
196 }}

Callers

nothing calls this directly

Calls 1

formatTimeFunction · 0.85

Tested by

no test coverage detected