From b8fda4322f81adc004d35b66dfaeee5ba12f0832 Mon Sep 17 00:00:00 2001 From: loveuer Date: Mon, 28 Apr 2025 17:59:07 +0800 Subject: [PATCH] init: 0.0.7 next: upload --- frontend/src/component/message/u-message.tsx | 84 ++++++++++++++++++++ frontend/src/page/component/panel-left.tsx | 2 +- 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 frontend/src/component/message/u-message.tsx diff --git a/frontend/src/component/message/u-message.tsx b/frontend/src/component/message/u-message.tsx new file mode 100644 index 0000000..8a5de2a --- /dev/null +++ b/frontend/src/component/message/u-message.tsx @@ -0,0 +1,84 @@ +// MessageContext.tsx +import React, { createContext, useContext, useState, useCallback, useRef } from 'react'; +import ReactDOM from 'react-dom'; +import './Message.css'; + +export interface Message { + id: number; + content: string; + type: 'info' | 'success' | 'warning' | 'error'; +} + +export type MessageType = Message['type']; + +const MessageContext = createContext<{ + addMessage: (content: string, type?: MessageType, duration?: number) => void; + removeMessage: (id: number) => void; +}>({ + addMessage: () => {}, + removeMessage: () => {}, +}); + +export const MessageProvider: React.FC = ({ children }) => { + const [messages, setMessages] = useState([]); + const timerRef = useRef>({}); + + const addMessage = useCallback((content: string, type: MessageType = 'info', duration: number = 3000) => { + const id = Date.now(); + setMessages(prev => [...prev, { id, content, type }]); + + timerRef.current[id] = setTimeout(() => { + removeMessage(id); + }, duration); + }, []); + + const removeMessage = useCallback((id: number) => { + setMessages(prev => prev.filter(msg => msg.id !== id)); + clearTimeout(timerRef.current[id]); + delete timerRef.current[id]; + }, []); + + return ( + + {children} + {ReactDOM.createPortal( +
+ {messages.map(({ id, content, type }) => ( + removeMessage(id)} + /> + ))} +
, + document.body + )} +
+ ); +}; + +interface MessageItemProps { + id: number; + content: string; + type: MessageType; + onClose: () => void; +} + +const MessageItem: React.FC = ({ id, content, type, onClose }) => { + return ( +
+ {content} + +
+ ); +}; + +export const useMessage = (): ReturnType => { + const context = useContext(MessageContext); + if (!context) { + throw new Error('useMessage must be used within a MessageProvider'); + } + return context; +}; \ No newline at end of file diff --git a/frontend/src/page/component/panel-left.tsx b/frontend/src/page/component/panel-left.tsx index 9c97832..74c89ed 100644 --- a/frontend/src/page/component/panel-left.tsx +++ b/frontend/src/page/component/panel-left.tsx @@ -54,7 +54,7 @@ export const PanelLeft = () => { } function onFileUpload() { - console.log('[D] onFileUpload: upload file =', file) + console.log(`[D] onFileUpload: upload file = ${file?.name}, size = ${file?.size}`, file) } function onFileClean() {