θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@
"tailwindcss": "^3.3.1",
"vite": "^4.3.0"
}
}
}
5 changes: 2 additions & 3 deletions frontend/src/components/ChatBubble/index.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import Jazzicon from "../UserIcon";
import UserIcon from "../UserIcon";
import { userFromStorage } from "@/utils/request";
import { AI_BACKGROUND_COLOR, USER_BACKGROUND_COLOR } from "@/utils/constants";

Expand All @@ -11,8 +11,7 @@ export default function ChatBubble({ message, type, popMsg }) {
<div className={`flex justify-center items-end w-full ${backgroundColor}`}>
<div className={`py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}>
<div className="flex gap-x-5">
<Jazzicon
size={36}
<UserIcon
user={{ uid: isUser ? userFromStorage()?.username : "system" }}
role={type}
/>
Expand Down
23 changes: 10 additions & 13 deletions frontend/src/components/DefaultChat/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { isMobile } from "react-device-detect";
import { SidebarMobileHeader } from "../Sidebar";
import ChatBubble from "../ChatBubble";
import System from "@/models/system";
import Jazzicon from "../UserIcon";
import UserIcon from "../UserIcon";
import { userFromStorage } from "@/utils/request";
import { AI_BACKGROUND_COLOR, USER_BACKGROUND_COLOR } from "@/utils/constants";
import useUser from "@/hooks/useUser";
Expand Down Expand Up @@ -46,7 +46,7 @@ export default function DefaultChatContainer() {
className={`pt-10 pb-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
>
<div className="flex gap-x-5">
<Jazzicon size={36} user={{ uid: "system" }} role={"assistant"} />
<UserIcon user={{ uid: "system" }} role={"assistant"} />

<span
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
Expand All @@ -70,7 +70,7 @@ export default function DefaultChatContainer() {
className={`pb-4 pt-2 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
>
<div className="flex gap-x-5">
<Jazzicon size={36} user={{ uid: "system" }} role={"assistant"} />
<UserIcon user={{ uid: "system" }} role={"assistant"} />

<span
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
Expand All @@ -93,7 +93,7 @@ export default function DefaultChatContainer() {
className={`pt-2 pb-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
>
<div className="flex gap-x-5">
<Jazzicon size={36} user={{ uid: "system" }} role={"assistant"} />
<UserIcon user={{ uid: "system" }} role={"assistant"} />
<div>
<span
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
Expand Down Expand Up @@ -127,8 +127,7 @@ export default function DefaultChatContainer() {
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
>
<div className="flex gap-x-5">
<Jazzicon
size={36}
<UserIcon
user={{ uid: userFromStorage()?.username }}
role={"user"}
/>
Expand All @@ -151,7 +150,7 @@ export default function DefaultChatContainer() {
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
>
<div className="flex gap-x-5">
<Jazzicon size={36} user={{ uid: "system" }} role={"assistant"} />
<UserIcon user={{ uid: "system" }} role={"assistant"} />
<div>
<span
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
Expand Down Expand Up @@ -188,8 +187,7 @@ export default function DefaultChatContainer() {
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
>
<div className="flex gap-x-5">
<Jazzicon
size={36}
<UserIcon
user={{ uid: userFromStorage()?.username }}
role={"user"}
/>
Expand All @@ -213,7 +211,7 @@ export default function DefaultChatContainer() {
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
>
<div className="flex gap-x-5">
<Jazzicon size={36} user={{ uid: "system" }} role={"assistant"} />
<UserIcon user={{ uid: "system" }} role={"assistant"} />

<span
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
Expand Down Expand Up @@ -251,8 +249,7 @@ export default function DefaultChatContainer() {
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
>
<div className="flex gap-x-5">
<Jazzicon
size={36}
<UserIcon
user={{ uid: userFromStorage()?.username }}
role={"user"}
/>
Expand All @@ -275,7 +272,7 @@ export default function DefaultChatContainer() {
className={`py-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col`}
>
<div className="flex gap-x-5">
<Jazzicon size={36} user={{ uid: "system" }} role={"assistant"} />
<UserIcon user={{ uid: "system" }} role={"assistant"} />
<div>
<span
className={`whitespace-pre-line text-white font-normal text-sm md:text-sm flex flex-col gap-y-1 mt-2`}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/UserIcon/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useRef, useEffect } from "react";
import JAZZ from "@metamask/jazzicon";
import usePfp from "../../hooks/usePfp";

export default function Jazzicon({ size = 10, user, role }) {
export default function UserIcon({ size = 36, user, role }) {
const { pfp } = usePfp();
const divRef = useRef(null);
const seed = user?.uid
Expand Down
Binary file added frontend/src/components/UserIcon/workspace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { AI_BACKGROUND_COLOR, USER_BACKGROUND_COLOR } from "@/utils/constants";
import { Pencil } from "@phosphor-icons/react";
import { useState, useEffect, useRef } from "react";
import { Tooltip } from "react-tooltip";
const EDIT_EVENT = "toggle-message-edit";

export function useEditMessage({ chatId, role }) {
const [isEditing, setIsEditing] = useState(false);

function onEditEvent(e) {
if (e.detail.chatId !== chatId || e.detail.role !== role) {
setIsEditing(false);
return false;
}
setIsEditing((prev) => !prev);
}

useEffect(() => {
function listenForEdits() {
if (!chatId || !role) return;
window.addEventListener(EDIT_EVENT, onEditEvent);
}
listenForEdits();
return () => {
window.removeEventListener(EDIT_EVENT, onEditEvent);
};
}, [chatId, role]);

return { isEditing, setIsEditing };
}

export function EditMessageAction({ chatId = null, role, isEditing }) {
function handleEditClick() {
window.dispatchEvent(
new CustomEvent(EDIT_EVENT, { detail: { chatId, role } })
);
}

if (!chatId || isEditing) return null;
return (
<div
className={`mt-3 relative ${
role === "user" && !isEditing ? "opacity-0" : ""
} group-hover:opacity-100 transition-all duration-300`}
>
<button
onClick={handleEditClick}
data-tooltip-id="edit-input-text"
data-tooltip-content={`Edit ${
role === "user" ? "Prompt" : "Response"
} `}
className="border-none text-zinc-300"
aria-label={`Edit ${role === "user" ? "Prompt" : "Response"}`}
>
<Pencil size={18} className="mb-1" />
</button>
<Tooltip
id="edit-input-text"
place="bottom"
delayShow={300}
className="tooltip !text-xs"
/>
</div>
);
}

export function EditMessageForm({
role,
chatId,
message,
adjustTextArea,
saveChanges,
}) {
const formRef = useRef(null);
function handleSaveMessage(e) {
e.preventDefault();
const form = new FormData(e.target);
const editedMessage = form.get("editedMessage");
saveChanges({ editedMessage, chatId, role });
window.dispatchEvent(
new CustomEvent(EDIT_EVENT, { detail: { chatId, role } })
);
}

function cancelEdits() {
window.dispatchEvent(
new CustomEvent(EDIT_EVENT, { detail: { chatId, role } })
);
return false;
}

useEffect(() => {
if (!formRef || !formRef.current) return;
formRef.current.focus();
adjustTextArea({ target: formRef.current });
}, [formRef]);

return (
<form onSubmit={handleSaveMessage} className="flex flex-col w-full">
<textarea
ref={formRef}
name="editedMessage"
className={`w-full rounded ${
role === "user" ? USER_BACKGROUND_COLOR : AI_BACKGROUND_COLOR
} border border-white/20 active:outline-none focus:outline-none focus:ring-0 pr-16 pl-1.5 pt-1.5 resize-y`}
defaultValue={message}
onChange={adjustTextArea}
/>
<div className="mt-3 flex justify-center">
<button
type="submit"
className="px-2 py-1 bg-gray-200 text-gray-700 font-medium rounded-md mr-2 hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
>
Save & Submit
</button>
<button
type="button"
className="px-2 py-1 bg-historical-msg-system text-white font-medium rounded-md hover:bg-historical-msg-user/90 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2"
onClick={cancelEdits}
>
Cancel
</button>
</div>
</form>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import React, { memo, useState } from "react";
import useCopyText from "@/hooks/useCopyText";
import {
Check,
ClipboardText,
ThumbsUp,
ThumbsDown,
ArrowsClockwise,
Copy,
} from "@phosphor-icons/react";
import { Tooltip } from "react-tooltip";
import Workspace from "@/models/workspace";
import TTSMessage from "./TTSButton";
import { EditMessageAction } from "./EditMessage";

const Actions = ({
message,
Expand All @@ -18,9 +19,10 @@ const Actions = ({
slug,
isLastMessage,
regenerateMessage,
isEditing,
role,
}) => {
const [selectedFeedback, setSelectedFeedback] = useState(feedbackScore);

const handleFeedback = async (newFeedback) => {
const updatedFeedback =
selectedFeedback === newFeedback ? null : newFeedback;
Expand All @@ -32,14 +34,15 @@ const Actions = ({
<div className="flex w-full justify-between items-center">
<div className="flex justify-start items-center gap-x-4">
<CopyMessage message={message} />
{isLastMessage && (
<EditMessageAction chatId={chatId} role={role} isEditing={isEditing} />
{isLastMessage && !isEditing && (
<RegenerateMessage
regenerateMessage={regenerateMessage}
slug={slug}
chatId={chatId}
/>
)}
{chatId && (
{chatId && role !== "user" && !isEditing && (
<>
<FeedbackButton
isSelected={selectedFeedback === true}
Expand Down Expand Up @@ -111,7 +114,7 @@ function CopyMessage({ message }) {
{copied ? (
<Check size={18} className="mb-1" />
) : (
<ClipboardText size={18} className="mb-1" />
<Copy size={18} className="mb-1" />
)}
</button>
<Tooltip
Expand Down
Loading