import { useEffect, useRef, useState } from 'react'; import type { InstanceContext } from '../app-shell.js'; export interface SmsMessage { readonly id: string; readonly direction: string; readonly phoneNumber: string; readonly content: string; readonly timestamp: string; readonly status: string; } export interface MessagesSnapshot { readonly messages: readonly SmsMessage[]; } export interface SendMessageInput { readonly phoneNumber: string; readonly content: string; } export interface MessagesDataSource { load(instanceId: string, signal: AbortSignal): Promise; send(instanceId: string, input: SendMessageInput): Promise; } export interface MessagesModuleProps { readonly instance: InstanceContext; readonly dataSource?: MessagesDataSource; readonly refreshSignal?: unknown; } const directionLabel = (value: string): string => value === 'incoming' || value === 'received' ? '收到' : value === 'outgoing' || value === 'sent' ? '发送' : '未知'; export function MessagesModule({ instance, dataSource, refreshSignal }: MessagesModuleProps) { const owner = useRef(0); const [messages, setMessages] = useState(); const [loadError, setLoadError] = useState(false); const [retry, setRetry] = useState(0); const [phoneNumber, setPhoneNumber] = useState(''); const [content, setContent] = useState(''); const [pendingSend, setPendingSend] = useState(); const [sending, setSending] = useState(false); const [sendState, setSendState] = useState<'success' | 'error'>(); useEffect(() => { const request = ++owner.current; const controller = new AbortController(); setMessages(undefined); setLoadError(false); if (!dataSource) return () => controller.abort(); void dataSource.load(instance.id, controller.signal).then( (snapshot) => { if (request === owner.current && !controller.signal.aborted) setMessages(snapshot.messages); }, () => { if (request === owner.current && !controller.signal.aborted) setLoadError(true); }, ); return () => controller.abort(); }, [dataSource, instance.id, refreshSignal, retry]); async function send(input: SendMessageInput): Promise { if (!dataSource || sending) return; setSending(true); setSendState(undefined); try { await dataSource.send(instance.id, input); setContent(''); setPendingSend(undefined); setSendState('success'); setRetry((value) => value + 1); } catch { setSendState('error'); } finally { setSending(false); } } if (!dataSource) return (
短信功能暂不可用。
); return (

发送短信

发送会立即提交到当前设备,不会自动重试。请确认号码和内容。

{ event.preventDefault(); setPendingSend({ phoneNumber: phoneNumber.trim(), content: content.trim() }); }} >