update model when a message is added

This commit is contained in:
Red Adaya 2024-10-21 10:13:24 +08:00
parent 6868d1f39f
commit 4c72acdd4d
3 changed files with 35 additions and 16 deletions

View File

@ -10,7 +10,9 @@ import { Palette, PaletteButton, PaletteContent } from "./palette";
import "./emojiPalette.less"; import "./emojiPalette.less";
const emojiList = [ type EmojiItem = { emoji: string; name: string };
const emojiList: EmojiItem[] = [
// Smileys & Emotion // Smileys & Emotion
{ emoji: "😀", name: "grinning face" }, { emoji: "😀", name: "grinning face" },
{ emoji: "😁", name: "beaming face with smiling eyes" }, { emoji: "😁", name: "beaming face with smiling eyes" },
@ -214,15 +216,20 @@ const emojiList = [
interface EmojiPaletteProps { interface EmojiPaletteProps {
className?: string; className?: string;
placement?: Placement; placement?: Placement;
onSelect?: (_: EmojiItem) => void;
} }
const EmojiPalette = memo(({ className, placement }: EmojiPaletteProps) => { const EmojiPalette = memo(({ className, placement, onSelect }: EmojiPaletteProps) => {
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState("");
const handleSearchChange = (val: string) => { const handleSearchChange = (val: string) => {
setSearchTerm(val.toLowerCase()); setSearchTerm(val.toLowerCase());
}; };
const handleSelect = (item: { name: string; emoji: string }) => {
onSelect?.(item);
};
const filteredEmojis = emojiList.filter((item) => item.name.includes(searchTerm)); const filteredEmojis = emojiList.filter((item) => item.name.includes(searchTerm));
return ( return (
@ -241,13 +248,7 @@ const EmojiPalette = memo(({ className, placement }: EmojiPaletteProps) => {
<div className="emoji-grid"> <div className="emoji-grid">
{filteredEmojis.length > 0 ? ( {filteredEmojis.length > 0 ? (
filteredEmojis.map((item, index) => ( filteredEmojis.map((item, index) => (
<Button <Button key={index} className="ghost emoji-button" onClick={() => handleSelect(item)}>
key={index}
className="ghost emoji-button"
onClick={() => {
console.log(`Emoji selected: ${item.emoji}`);
}}
>
{item.emoji} {item.emoji}
</Button> </Button>
)) ))
@ -264,3 +265,4 @@ const EmojiPalette = memo(({ className, placement }: EmojiPaletteProps) => {
EmojiPalette.displayName = "EmojiPalette"; EmojiPalette.displayName = "EmojiPalette";
export { EmojiPalette }; export { EmojiPalette };
export type { EmojiItem };

View File

@ -3,6 +3,7 @@
import { ChatMessage, ChatMessages } from "@/app/view/chat/chatmessages"; import { ChatMessage, ChatMessages } from "@/app/view/chat/chatmessages";
import { UserStatus } from "@/app/view/chat/userlist"; import { UserStatus } from "@/app/view/chat/userlist";
import * as jotai from "jotai";
import { Channels } from "./channels"; import { Channels } from "./channels";
import { ChatBox } from "./chatbox"; import { ChatBox } from "./chatbox";
import { channels, messages, users } from "./data"; import { channels, messages, users } from "./data";
@ -14,19 +15,23 @@ class ChatModel {
viewType: string; viewType: string;
channels: MenuItem[]; channels: MenuItem[];
users: UserStatus[]; users: UserStatus[];
messages: ChatMessage[]; messagesAtom: jotai.PrimitiveAtom<ChatMessage[]>;
constructor(blockId: string) { constructor(blockId: string) {
this.viewType = "chat"; this.viewType = "chat";
this.channels = channels; this.channels = channels;
this.messages = messages;
this.users = users; this.users = users;
this.messagesAtom = jotai.atom(messages);
} }
addMessageAtom = jotai.atom(null, (get, set, newMessage: ChatMessage) => {
const currentMessages = get(this.messagesAtom);
set(this.messagesAtom, [...currentMessages, newMessage]);
});
} }
function makeChatModel(blockId: string): ChatModel { function makeChatModel(blockId: string): ChatModel {
const cpuPlotViewModel = new ChatModel(blockId); return new ChatModel(blockId);
return cpuPlotViewModel;
} }
interface ChatProps { interface ChatProps {
@ -34,7 +39,19 @@ interface ChatProps {
} }
const Chat = ({ model }: ChatProps) => { const Chat = ({ model }: ChatProps) => {
const { channels, users, messages } = model; const { channels, users } = model;
const messages = jotai.useAtomValue(model.messagesAtom);
const [, appendMessage] = jotai.useAtom(model.addMessageAtom);
const handleSendMessage = (message: string) => {
const newMessage: ChatMessage = {
id: `${Date.now()}`,
username: "currentUser",
message: message,
};
appendMessage(newMessage);
};
return ( return (
<div className="chat-view"> <div className="chat-view">
<Channels channels={channels}></Channels> <Channels channels={channels}></Channels>
@ -42,7 +59,7 @@ const Chat = ({ model }: ChatProps) => {
<div className="message-wrapper"> <div className="message-wrapper">
<ChatMessages messages={messages}></ChatMessages> <ChatMessages messages={messages}></ChatMessages>
</div> </div>
<ChatBox onSendMessage={(message: string) => console.log("message: ", message)} /> <ChatBox onSendMessage={(message: string) => handleSendMessage(message)} />
</div> </div>
<UserList users={users}></UserList> <UserList users={users}></UserList>
</div> </div>

View File

@ -30,7 +30,7 @@ const ChatMessages = memo(({ messages, className }: ChatMessagesProps) => {
}; };
useEffect(() => { useEffect(() => {
scrollToBottom(); // scrollToBottom();
}, [messages]); }, [messages]);
return ( return (