300 lines
7.8 KiB
TypeScript
300 lines
7.8 KiB
TypeScript
import { FC, useState } from 'react';
|
||
|
||
const CallScreen: FC = () => {
|
||
const [callStatus, setCallStatus] = useState<'idle' | 'calling' | 'connected'>('idle');
|
||
const [selectedLanguage, setSelectedLanguage] = useState('zh-en');
|
||
|
||
const handleStartCall = () => {
|
||
setCallStatus('calling');
|
||
// 模拟连接过程
|
||
setTimeout(() => {
|
||
setCallStatus('connected');
|
||
}, 2000);
|
||
};
|
||
|
||
const handleEndCall = () => {
|
||
setCallStatus('idle');
|
||
};
|
||
|
||
const languageOptions = [
|
||
{ value: 'zh-en', label: '中文 ⇄ 英文' },
|
||
{ value: 'zh-es', label: '中文 ⇄ 西班牙文' },
|
||
{ value: 'zh-fr', label: '中文 ⇄ 法文' },
|
||
{ value: 'zh-ja', label: '中文 ⇄ 日文' },
|
||
{ value: 'zh-ko', label: '中文 ⇄ 韩文' },
|
||
];
|
||
|
||
return (
|
||
<div style={styles.container}>
|
||
<div style={styles.content}>
|
||
{/* 语言选择 */}
|
||
<div style={styles.section}>
|
||
<h3 style={styles.sectionTitle}>选择翻译语言</h3>
|
||
<select
|
||
value={selectedLanguage}
|
||
onChange={(e) => setSelectedLanguage(e.target.value)}
|
||
style={styles.languageSelect}
|
||
>
|
||
{languageOptions.map((option) => (
|
||
<option key={option.value} value={option.value}>
|
||
{option.label}
|
||
</option>
|
||
))}
|
||
</select>
|
||
</div>
|
||
|
||
{/* 通话状态 */}
|
||
<div style={styles.callContainer}>
|
||
{callStatus === 'idle' && (
|
||
<div style={styles.idleState}>
|
||
<div style={styles.callIcon}>📞</div>
|
||
<h2 style={styles.statusText}>准备开始通话</h2>
|
||
<p style={styles.statusSubtext}>点击下方按钮开始翻译通话</p>
|
||
<button style={styles.startButton} onClick={handleStartCall}>
|
||
开始通话
|
||
</button>
|
||
</div>
|
||
)}
|
||
|
||
{callStatus === 'calling' && (
|
||
<div style={styles.callingState}>
|
||
<div style={styles.pulsingIcon}>📞</div>
|
||
<h2 style={styles.statusText}>正在连接...</h2>
|
||
<p style={styles.statusSubtext}>请稍候,正在为您连接译员</p>
|
||
<div style={styles.loadingDots}>
|
||
<span>●</span>
|
||
<span>●</span>
|
||
<span>●</span>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{callStatus === 'connected' && (
|
||
<div style={styles.connectedState}>
|
||
<div style={styles.connectedIcon}>✅</div>
|
||
<h2 style={styles.statusText}>通话中</h2>
|
||
<p style={styles.statusSubtext}>译员已连接,可以开始对话</p>
|
||
|
||
{/* 通话控制 */}
|
||
<div style={styles.callControls}>
|
||
<button style={styles.muteButton}>🔇</button>
|
||
<button style={styles.endButton} onClick={handleEndCall}>
|
||
结束通话
|
||
</button>
|
||
<button style={styles.speakerButton}>🔊</button>
|
||
</div>
|
||
|
||
{/* 通话信息 */}
|
||
<div style={styles.callInfo}>
|
||
<div style={styles.infoItem}>
|
||
<span style={styles.infoLabel}>通话时长</span>
|
||
<span style={styles.infoValue}>00:45</span>
|
||
</div>
|
||
<div style={styles.infoItem}>
|
||
<span style={styles.infoLabel}>译员</span>
|
||
<span style={styles.infoValue}>张译员</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* 快速操作 */}
|
||
<div style={styles.section}>
|
||
<h3 style={styles.sectionTitle}>快速操作</h3>
|
||
<div style={styles.quickActions}>
|
||
<button style={styles.actionButton}>
|
||
<span style={styles.actionIcon}>📝</span>
|
||
<span style={styles.actionLabel}>记录笔记</span>
|
||
</button>
|
||
<button style={styles.actionButton}>
|
||
<span style={styles.actionIcon}>📧</span>
|
||
<span style={styles.actionLabel}>发送邮件</span>
|
||
</button>
|
||
<button style={styles.actionButton}>
|
||
<span style={styles.actionIcon}>📋</span>
|
||
<span style={styles.actionLabel}>复制内容</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
const styles = {
|
||
container: {
|
||
display: 'flex',
|
||
flexDirection: 'column' as const,
|
||
height: '100%',
|
||
backgroundColor: '#f5f5f5',
|
||
},
|
||
content: {
|
||
flex: 1,
|
||
padding: '16px',
|
||
paddingBottom: '100px',
|
||
},
|
||
section: {
|
||
marginBottom: '24px',
|
||
},
|
||
sectionTitle: {
|
||
fontSize: '18px',
|
||
fontWeight: 'bold',
|
||
color: '#333',
|
||
margin: '0 0 16px 0',
|
||
},
|
||
languageSelect: {
|
||
width: '100%',
|
||
padding: '12px',
|
||
fontSize: '16px',
|
||
border: '1px solid #d9d9d9',
|
||
borderRadius: '8px',
|
||
backgroundColor: '#fff',
|
||
},
|
||
callContainer: {
|
||
display: 'flex',
|
||
flexDirection: 'column' as const,
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
minHeight: '300px',
|
||
backgroundColor: '#fff',
|
||
borderRadius: '16px',
|
||
padding: '32px',
|
||
marginBottom: '24px',
|
||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)',
|
||
},
|
||
idleState: {
|
||
textAlign: 'center' as const,
|
||
},
|
||
callingState: {
|
||
textAlign: 'center' as const,
|
||
},
|
||
connectedState: {
|
||
textAlign: 'center' as const,
|
||
width: '100%',
|
||
},
|
||
callIcon: {
|
||
fontSize: '64px',
|
||
marginBottom: '16px',
|
||
},
|
||
pulsingIcon: {
|
||
fontSize: '64px',
|
||
marginBottom: '16px',
|
||
animation: 'pulse 1.5s ease-in-out infinite alternate',
|
||
},
|
||
connectedIcon: {
|
||
fontSize: '64px',
|
||
marginBottom: '16px',
|
||
},
|
||
statusText: {
|
||
fontSize: '24px',
|
||
fontWeight: 'bold',
|
||
color: '#333',
|
||
margin: '0 0 8px 0',
|
||
},
|
||
statusSubtext: {
|
||
fontSize: '16px',
|
||
color: '#666',
|
||
margin: '0 0 24px 0',
|
||
},
|
||
startButton: {
|
||
backgroundColor: '#52c41a',
|
||
color: '#fff',
|
||
border: 'none',
|
||
borderRadius: '50px',
|
||
padding: '16px 32px',
|
||
fontSize: '18px',
|
||
fontWeight: 'bold',
|
||
cursor: 'pointer',
|
||
transition: 'background-color 0.3s ease',
|
||
},
|
||
loadingDots: {
|
||
display: 'flex',
|
||
gap: '8px',
|
||
justifyContent: 'center',
|
||
},
|
||
callControls: {
|
||
display: 'flex',
|
||
gap: '16px',
|
||
justifyContent: 'center',
|
||
margin: '24px 0',
|
||
},
|
||
muteButton: {
|
||
backgroundColor: '#1890ff',
|
||
color: '#fff',
|
||
border: 'none',
|
||
borderRadius: '50%',
|
||
width: '56px',
|
||
height: '56px',
|
||
fontSize: '20px',
|
||
cursor: 'pointer',
|
||
},
|
||
endButton: {
|
||
backgroundColor: '#ff4d4f',
|
||
color: '#fff',
|
||
border: 'none',
|
||
borderRadius: '50px',
|
||
padding: '16px 24px',
|
||
fontSize: '16px',
|
||
fontWeight: 'bold',
|
||
cursor: 'pointer',
|
||
},
|
||
speakerButton: {
|
||
backgroundColor: '#1890ff',
|
||
color: '#fff',
|
||
border: 'none',
|
||
borderRadius: '50%',
|
||
width: '56px',
|
||
height: '56px',
|
||
fontSize: '20px',
|
||
cursor: 'pointer',
|
||
},
|
||
callInfo: {
|
||
display: 'flex',
|
||
justifyContent: 'space-around',
|
||
width: '100%',
|
||
marginTop: '24px',
|
||
},
|
||
infoItem: {
|
||
display: 'flex',
|
||
flexDirection: 'column' as const,
|
||
alignItems: 'center',
|
||
},
|
||
infoLabel: {
|
||
fontSize: '14px',
|
||
color: '#666',
|
||
marginBottom: '4px',
|
||
},
|
||
infoValue: {
|
||
fontSize: '16px',
|
||
fontWeight: 'bold',
|
||
color: '#333',
|
||
},
|
||
quickActions: {
|
||
display: 'grid',
|
||
gridTemplateColumns: 'repeat(3, 1fr)',
|
||
gap: '12px',
|
||
},
|
||
actionButton: {
|
||
display: 'flex',
|
||
flexDirection: 'column' as const,
|
||
alignItems: 'center',
|
||
padding: '16px 8px',
|
||
backgroundColor: '#fff',
|
||
border: 'none',
|
||
borderRadius: '12px',
|
||
cursor: 'pointer',
|
||
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
|
||
},
|
||
actionIcon: {
|
||
fontSize: '24px',
|
||
marginBottom: '8px',
|
||
},
|
||
actionLabel: {
|
||
fontSize: '12px',
|
||
color: '#666',
|
||
textAlign: 'center' as const,
|
||
},
|
||
};
|
||
|
||
export default CallScreen;
|