feat: Add user settings for voice and persona

Introduces a new `UserSettings` interface and default settings. This allows users to customize voice preferences (name, style, gender) and persona characteristics within the application. This enhances personalization and user experience by tailoring interactions to individual needs and preferences.
This commit is contained in:
John Remillard committed 2025-12-17 12:14:29 -05:00
1 parent c78604de02
commit a7a8c661b7
9 files changed
+670 -360

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
import React, { useEffect, useRef } from 'react';
import { MessageSquare, X, User, Bot } from 'lucide-react';
interface TranscriptPanelProps {
messages: { role: 'user' | 'model'; text: string; id: string }[];
onClose: () => void;
}
const TranscriptPanel: React.FC<TranscriptPanelProps> = ({ messages, onClose }) => {
const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}
}, [messages]);
return (
<div className="absolute top-0 right-0 w-full sm:w-80 h-full bg-slate-900/95 backdrop-blur-2xl border-l border-white/10 z-50 flex flex-col shadow-2xl animate-in slide-in-from-right duration-500">
<div className="p-5 border-b border-white/10 flex justify-between items-center bg-black/20">
<div className="flex items-center gap-2 text-teal-400">
<MessageSquare size={16} />
<h3 className="text-[10px] font-black uppercase tracking-widest text-white">Live Conversation</h3>
</div>
<button onClick={onClose} className="text-white/40 hover:text-white transition-colors p-1 hover:bg-white/5 rounded-lg">
<X size={18} />
</button>
</div>
<div
ref={scrollRef}
className="flex-grow overflow-y-auto p-6 space-y-5 scrollbar-hide"
>
{messages.length === 0 ? (
<div className="h-full flex flex-col items-center justify-center text-center opacity-20 px-8">
<div className="w-12 h-12 rounded-full border border-white/20 flex items-center justify-center mb-4">
<MessageSquare size={24} className="text-white" />
</div>
<p className="text-[9px] text-white uppercase font-bold tracking-widest leading-loose">
Listening for conversation...<br/>Transcript will appear here
</p>
</div>
) : (
messages.map((m) => (
<div key={m.id} className={`flex flex-col gap-1.5 ${m.role === 'user' ? 'items-end' : 'items-start'} animate-in fade-in slide-in-from-bottom-2 duration-300`}>
<div className="flex items-center gap-1.5 opacity-40 mb-0.5 px-1">
{m.role === 'user' ? (
<>
<span className="text-[8px] font-black text-white uppercase tracking-tighter">You</span>
<User size={8} className="text-teal-400" />
</>
) : (
<>
<Bot size={8} className="text-blue-400" />
<span className="text-[8px] font-black text-white uppercase tracking-tighter">AI Partner</span>
</>
)}
</div>
<div className={`px-4 py-3 rounded-2xl text-[11px] leading-relaxed max-w-[95%] shadow-lg ${
m.role === 'user'
? 'bg-teal-600 text-white rounded-tr-none shadow-teal-900/20'
: 'bg-white/10 text-slate-100 rounded-tl-none border border-white/5 shadow-black/20'
}`}>
{m.text}
</div>
</div>
))
)}
</div>
<div className="p-4 bg-black/40 text-center border-t border-white/5">
<div className="flex items-center justify-center gap-2">
<div className="w-1 h-1 bg-teal-400 rounded-full animate-pulse"></div>
<p className="text-[8px] text-white/30 uppercase font-black tracking-[0.3em]">
Real-time Analysis
</p>
</div>
</div>
</div>
);
};
export default React.memo(TranscriptPanel);