Twilioapp/src/screens/CallScreen.web.tsx

300 lines
7.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;