Skip to content

Commit

Permalink
Merge pull request #29 from Orenoid/main
Browse files Browse the repository at this point in the history
Merge main branch
  • Loading branch information
Orenoid authored Dec 17, 2024
2 parents 9bfa3bf + 758ca08 commit 7e40b18
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 34 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ docker run -d --name babel-duck --env-file .env -p 9000:9000 orenoid/babel-duck:

- [ ] 对话模板
- [ ] 复述练习模式
- [ ] 移动端适配
- [ ] 语音回放
- [ ] 支持多模态语音
- [ ] 接入更多 LLM/TTS/STT 服务
Expand Down
37 changes: 33 additions & 4 deletions src/app/chat/components/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export function Chat({ chatID, chatTitle, loadChatByID, className = "" }: {
throw new Error(`Chat intelligence with type ${type} not found`)
}
}
const inputHandlers = chatSettings !== undefined ?
const visibleInputHandlers = chatSettings !== undefined ?
chatSettings.inputHandlers
.filter((handler) => handler.display)
.map((handler) => handler.handler)
Expand Down Expand Up @@ -251,11 +251,40 @@ export function Chat({ chatID, chatTitle, loadChatByID, className = "" }: {
</div>
{/* input */}
<MessageInput addInputHandler={(handler) => {
updateInputHandlerInLocalStorage(chatID, inputHandlers?.length ?? 0, handler)
}} className="w-4/5"
if (chatSettings === undefined) return
updateInputHandlerInLocalStorage(chatID, visibleInputHandlers?.length ?? 0, handler)
const originalInputHandlers = chatSettings.inputHandlers
dispatch(setCurrentChatSettings({
chatID,
chatSettings: {
...chatSettings,
inputHandlers: [
...originalInputHandlers.map((handler) => ({ handler: handler.handler.serialize(), display: handler.display })),
{ handler: handler.serialize(), display: true }
],
}
}))
}}
updateInputHandler={(index, handler) => {
if (chatSettings === undefined) return
updateInputHandlerInLocalStorage(chatID, index, handler)
const originalInputHandlers = chatSettings.inputHandlers
dispatch(setCurrentChatSettings({
chatID,
chatSettings: {
...chatSettings,
inputHandlers: originalInputHandlers.map((h, i) =>
i === index
? { handler: handler.serialize(), display: h.display }
: { handler: h.handler.serialize(), display: h.display }
),
}
}))
}}
className="w-4/5"
chatID={chatID}
msgListSwitchSignal={msgListSwitchSignal}
inputHandlers={inputHandlers}
inputHandlers={visibleInputHandlers}
addMesssage={addMesssage} messageList={currentMessageList}
// Temporarily forbid nested multi-level discussions, the component has already supported,
// it's just the AI might be unable to handle too many levels
Expand Down
58 changes: 31 additions & 27 deletions src/app/chat/components/input.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
"use client";

import { useState, useRef, useEffect, useCallback, useContext } from "react";
import { FaBackspace, FaMicrophone } from "react-icons/fa";
import { LuSettings, LuUserCog2 } from "react-icons/lu";
import { Audio, Oval } from "react-loader-spinner";
import { messageAddedCallbackOptions } from "./chat";
import { ChatSettingsContext } from "./chat-settings";
import { SpecialRoles, TextMessage } from "./message";
import { I18nText } from "@/app/i18n/i18n";
import { TmpFilledButton, TmpTransparentButton } from "@/app/ui-utils/components/button";
import { SemiTransparentOverlay } from "@/app/ui-utils/components/overlay";
import { IconCircleWrapper } from "@/app/ui-utils/components/wrapper";
import { diffChars } from "diff";
import { IMediaRecorder } from "extendable-media-recorder";
import { useCallback, useContext, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { FaBackspace, FaMicrophone } from "react-icons/fa";
import { FiPlus } from "react-icons/fi";
import { LiaComments } from "react-icons/lia";
import { LuSettings, LuUserCog2 } from "react-icons/lu";
import { PiKeyReturnBold } from "react-icons/pi";
import { isOpenAILikeMessage, Message, OpenAILikeMessage } from "../lib/message";
import { TbPencil } from "react-icons/tb";
import { Audio, Oval } from "react-loader-spinner";
import Switch from "react-switch";
import { IMediaRecorder } from "extendable-media-recorder";
import { Tooltip } from "react-tooltip";
import { FiPlus } from "react-icons/fi";
import { updateInputHandlerInLocalStorage, updateInputSettingsPayloadInLocalStorage } from "../lib/chat";
import { updateInputSettingsPayloadInLocalStorage } from "../lib/chat";
import { isOpenAILikeMessage, Message, OpenAILikeMessage } from "../lib/message";
import { messageAddedCallbackOptions } from "./chat";
import { ChatSettingsContext } from "./chat-settings";
import {
InputHandler,
CustomInputHandlerCreator
CustomInputHandlerCreator,
InputHandler
} from "./input-handlers";
import { SemiTransparentOverlay } from "@/app/ui-utils/components/overlay";
import { useTranslation } from "react-i18next";
import { I18nText } from "@/app/i18n/i18n";
import { TmpFilledButton, TmpTransparentButton } from "@/app/ui-utils/components/button";
import { TbPencil } from "react-icons/tb";
import { SpecialRoles, TextMessage } from "./message";
import { TutorialDiffView, TutorialInput } from "./tutorial-input";

export async function reviseMessage(
Expand Down Expand Up @@ -220,17 +220,21 @@ export type MsgListSwitchSignal =
| { type: 'backFromFollowUpDiscussion', message: Message, handledMsg: Message, handlerInstruction: string, key: number }

export function MessageInput({
chatID, messageList, inputHandlers, addMesssage, addInputHandler: pAddInputHandler, msgListSwitchSignal, allowFollowUpDiscussion, startFollowUpDiscussion, className = ""
chatID, messageList, inputHandlers, msgListSwitchSignal, allowFollowUpDiscussion, className = "",
addMesssage,
addInputHandler: pAddInputHandler,
startFollowUpDiscussion,
updateInputHandler,
}: {
chatID: string
messageList: Message[];
inputHandlers: InputHandler[]
allowFollowUpDiscussion: boolean;
// callback functions
addMesssage: (message: Message, callbackOpts?: messageAddedCallbackOptions) => void;
// TODO tech-debt: 新增 inputHandler 应该通过更新 chatSettings 来实现
addInputHandler: (handler: InputHandler) => void;
startFollowUpDiscussion: (userInstruction: string, messageToRevise: Message, revisedText: Message) => void;
updateInputHandler: (index: number, handler: InputHandler) => void;
// signals
msgListSwitchSignal: MsgListSwitchSignal,
className?: string;
Expand Down Expand Up @@ -321,17 +325,17 @@ export function MessageInput({
}
pAddInputHandler(handler);
setCompState(compState.previousState);
inputHandlers.push(handler); // TODO need to find out why this would work...
}
function updateInputHandler(handler: InputHandler) {
function _updateInputHandler(handler: InputHandler) {
if (compState.type !== 'settingsPanel') {
return;
}
updateInputHandlerInLocalStorage(chatID, compState.handlerIndex, handler);
inputHandlers[compState.handlerIndex] = handler;
updateInputHandler(compState.handlerIndex, handler);
setCompState(compState.previousState);
}
function updateInputSettingsPayload(payload: object) {
// update the input component settings
// TODO tech-debt: maybe should just achieve this by directly updating the chat settings
function updateInputCompSettings(payload: object) {
updateInputSettingsPayloadInLocalStorage(chatID, payload);
}

Expand Down Expand Up @@ -401,7 +405,7 @@ export function MessageInput({
{compState.type === 'settingsPanel' && compState.handlerIndex === index && configurable &&
<>
<SemiTransparentOverlay onClick={cancelUpdatingInputHandler} />
<SettingsPanel updateHandler={updateInputHandler} />
<SettingsPanel updateHandler={_updateInputHandler} />
</>
}
</div>
Expand Down Expand Up @@ -444,7 +448,7 @@ export function MessageInput({
addMessage={addMesssage} updateMessage={updateMessage}
revisionMessage={isNormal ? [compState.message, compState.fromRevision] : undefined} rejectionSignal={rejectionSignal} />}
{inputComponentType === 'tutorialInput' && <TutorialInput msgListSwitchSignal={msgListSwitchSignal} allowEdit={isNormal}
addMessage={addMesssage} updateMessage={updateMessage} updateInputSettingsPayload={updateInputSettingsPayload}
addMessage={addMesssage} updateMessage={updateMessage} updateInputSettingsPayload={updateInputCompSettings}
revisionMessage={isNormal ? [compState.message, compState.fromRevision] : undefined} rejectionSignal={rejectionSignal} />}
</div>;
}
Expand Down
4 changes: 1 addition & 3 deletions src/app/settings/components/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,7 @@ function CommonChatSettings({ chatSettings, updateChatSettings, className = "" }
if (handler.handler.deletable) {
updateChatSettings({
...chatSettings,
inputHandlers: chatSettings.inputHandlers.filter((h) =>
h.handler.implType !== handler.handler.implType
)
inputHandlers: chatSettings.inputHandlers.filter((_, i) => i !== index)
})
}
}}
Expand Down

0 comments on commit 7e40b18

Please sign in to comment.