diff --git a/extras/speaker-recognition/nginx.conf.template b/extras/speaker-recognition/nginx.conf.template index 91626e23..38a8604a 100644 --- a/extras/speaker-recognition/nginx.conf.template +++ b/extras/speaker-recognition/nginx.conf.template @@ -46,7 +46,7 @@ http { } upstream web_ui { - server web-ui:5175; + server web-ui:WEB_UI_PORT_PLACEHOLDER; } # HTTPS Server diff --git a/extras/speaker-recognition/setup.sh b/extras/speaker-recognition/setup.sh index ce633036..b2ef9eff 100755 --- a/extras/speaker-recognition/setup.sh +++ b/extras/speaker-recognition/setup.sh @@ -141,6 +141,20 @@ if [ -n "$DEEPGRAM_API_KEY" ]; then echo "✅ Deepgram API key configured from command line" fi +# Determine WEB_UI_PORT and HTTPS setting +if [ "$HTTPS_MODE" = "https" ]; then + WEB_UI_PORT=5175 + REACT_UI_HTTPS=true +else + WEB_UI_PORT=5174 + REACT_UI_HTTPS=false +fi + +# Update .env file +sed -i "s|REACT_UI_HTTPS=.*|REACT_UI_HTTPS=$REACT_UI_HTTPS|" .env +sed -i "s|REACT_UI_PORT=.*|REACT_UI_PORT=$WEB_UI_PORT|" .env + +# Generate SSL certificates (only for HTTPS mode) if [ "$HTTPS_MODE" = "https" ]; then # Get SERVER_IP if not already set (from command line) if [ -z "$SERVER_IP" ]; then @@ -152,11 +166,6 @@ if [ "$HTTPS_MODE" = "https" ]; then SERVER_IP=${SERVER_IP:-localhost} fi - # Update .env for HTTPS mode - sed -i "s|REACT_UI_HTTPS=.*|REACT_UI_HTTPS=true|" .env - sed -i "s|REACT_UI_PORT=.*|REACT_UI_PORT=5175|" .env - - # Generate SSL certificates echo "" echo "📄 Generating SSL certificates..." if [ -f "ssl/generate-ssl.sh" ]; then @@ -165,16 +174,20 @@ if [ "$HTTPS_MODE" = "https" ]; then else echo "⚠️ ssl/generate-ssl.sh not found, SSL setup skipped" fi - - # Create nginx.conf from template - echo "📄 Creating nginx configuration..." - if [ -f "nginx.conf.template" ]; then - sed "s/TAILSCALE_IP/$SERVER_IP/g" nginx.conf.template > nginx.conf - echo "✅ nginx.conf created for: $SERVER_IP" - else - echo "⚠️ nginx.conf.template not found, nginx config skipped" - fi - +fi + +# Create nginx.conf from template +echo "📄 Creating nginx configuration..." +if [ -f "nginx.conf.template" ]; then + # Use SERVER_IP if set, otherwise default to localhost for nginx.conf generation + NGINX_SERVER_IP=${SERVER_IP:-localhost} + sed "s/TAILSCALE_IP/$NGINX_SERVER_IP/g" nginx.conf.template | sed "s/WEB_UI_PORT_PLACEHOLDER/$WEB_UI_PORT/g" > nginx.conf + echo "✅ nginx.conf created for: $NGINX_SERVER_IP" +else + echo "⚠️ nginx.conf.template not found, nginx config skipped" +fi + +if [ "$HTTPS_MODE" = "https" ]; then echo "" echo "✅ Speaker Recognition configured (HTTPS mode)!" echo "📁 Configuration saved to .env" @@ -186,16 +199,12 @@ if [ "$HTTPS_MODE" = "https" ]; then echo "📱 Service API: https://localhost:8444/api/" echo "💡 Accept SSL certificate in browser" else - # HTTP Configuration - sed -i "s|REACT_UI_HTTPS=.*|REACT_UI_HTTPS=false|" .env - sed -i "s|REACT_UI_PORT=.*|REACT_UI_PORT=5174|" .env - echo "" echo "✅ Speaker Recognition configured (HTTP mode)!" echo "📁 Configuration saved to .env" echo "" echo "🚀 To start: docker compose up --build -d speaker-service web-ui" echo "📱 Service API: http://localhost:8085" - echo "📱 Web Interface: http://localhost:5174" + echo "📱 Web Interface: http://localhost:$WEB_UI_PORT" echo "⚠️ Note: Microphone access may not work over HTTP on remote connections" fi \ No newline at end of file diff --git a/extras/speaker-recognition/webui/src/App.tsx b/extras/speaker-recognition/webui/src/App.tsx index 9d4650b5..1bfd1f60 100644 --- a/extras/speaker-recognition/webui/src/App.tsx +++ b/extras/speaker-recognition/webui/src/App.tsx @@ -9,24 +9,27 @@ import Inference from './pages/Inference' import InferLive from './pages/InferLive' import InferLiveSimplified from './pages/InferLiveSimplified' import './App.css' +import { ThemeProvider } from './contexts/ThemeContext' function App() { return ( - - - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - - - + + + + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + ) } diff --git a/extras/speaker-recognition/webui/src/components/AudioRecordingControls.tsx b/extras/speaker-recognition/webui/src/components/AudioRecordingControls.tsx index 2e2e1022..4130f62d 100644 --- a/extras/speaker-recognition/webui/src/components/AudioRecordingControls.tsx +++ b/extras/speaker-recognition/webui/src/components/AudioRecordingControls.tsx @@ -129,14 +129,14 @@ export const AudioRecordingControls: React.FC = ({ return (
-

🎤 Record Audio

+

🎤 Record Audio

{/* Recording Status */}
{/* Status Indicator */}
{getStatusIcon()} - {getStatusText()} + {getStatusText()}
{/* Recording Controls */} @@ -171,7 +171,7 @@ export const AudioRecordingControls: React.FC = ({
{/* Browser Compatibility Info */} -
+

Record audio for speaker identification

{location.protocol !== 'https:' && location.hostname !== 'localhost' @@ -200,11 +200,11 @@ export const AudioRecordingControls: React.FC = ({

-
Duration
+
Duration
{formatDuration(processedAudio.buffer.duration * 1000)}
-
Sample Rate
+
Sample Rate
{(processedAudio.buffer.sampleRate / 1000).toFixed(1)} kHz
diff --git a/extras/speaker-recognition/webui/src/components/ConnectionStatus.tsx b/extras/speaker-recognition/webui/src/components/ConnectionStatus.tsx index 7960e664..8242f5dc 100644 --- a/extras/speaker-recognition/webui/src/components/ConnectionStatus.tsx +++ b/extras/speaker-recognition/webui/src/components/ConnectionStatus.tsx @@ -102,7 +102,7 @@ export default function ConnectionStatus() { onClick={() => checkBackendConnection()} > - {getStatusText()} + {getStatusText()}
) } diff --git a/extras/speaker-recognition/webui/src/components/FileUploader.tsx b/extras/speaker-recognition/webui/src/components/FileUploader.tsx index 26299ba0..f236c147 100644 --- a/extras/speaker-recognition/webui/src/components/FileUploader.tsx +++ b/extras/speaker-recognition/webui/src/components/FileUploader.tsx @@ -127,14 +127,14 @@ export default function FileUploader({
-

+

{isDragOver ? 'Drop files here' : (title || 'Upload Audio Files')}

-

+

Drag and drop or click to select files

{accept.includes('audio') && ( -

+

Supported: WAV, FLAC, MP3, M4A, OGG

)} @@ -149,7 +149,7 @@ export default function FileUploader({ {/* Selected Files List */} {selectedFiles.length > 0 && (
-

Selected Files:

+

Selected Files:

{selectedFiles.map((file, index) => (
-

{file.name}

-

{formatFileSize(file.size)}

+

{file.name}

+

{formatFileSize(file.size)}

; +} \ No newline at end of file diff --git a/extras/speaker-recognition/webui/src/components/UserSelector.tsx b/extras/speaker-recognition/webui/src/components/UserSelector.tsx index ece819bb..52727a9d 100644 --- a/extras/speaker-recognition/webui/src/components/UserSelector.tsx +++ b/extras/speaker-recognition/webui/src/components/UserSelector.tsx @@ -37,7 +37,7 @@ export default function UserSelector() { if (isLoading) { return ( -
+
Loading...
@@ -49,42 +49,42 @@ export default function UserSelector() { {/* Current User Display / Dropdown Trigger */} {/* Dropdown Menu */} {isDropdownOpen && ( -
+
{/* Existing Users */} {users.length > 0 && ( <> -
+
Select User
{users.map((u) => ( ))} -
+
)} @@ -92,7 +92,7 @@ export default function UserSelector() { {!isCreating ? ( @@ -123,7 +123,7 @@ export default function UserSelector() { setIsCreating(false) setNewUsername('') }} - className="flex-1 px-2 py-1 text-xs bg-gray-300 text-gray-700 rounded hover:bg-gray-400" + className="btn-secondary" disabled={isSubmitting} > Cancel diff --git a/extras/speaker-recognition/webui/src/components/layout/Layout.tsx b/extras/speaker-recognition/webui/src/components/layout/Layout.tsx index 29c8d681..93eb4578 100644 --- a/extras/speaker-recognition/webui/src/components/layout/Layout.tsx +++ b/extras/speaker-recognition/webui/src/components/layout/Layout.tsx @@ -3,6 +3,7 @@ import { Link, useLocation } from 'react-router-dom' import { Mic, Music, FileText, Users, Brain, User, Radio, Wifi } from 'lucide-react' import UserSelector from '../UserSelector' import ConnectionStatus from '../ConnectionStatus' +import { ThemeSwitcher } from '../ThemeSwitcher' interface LayoutProps { children: React.ReactNode @@ -22,20 +23,22 @@ export default function Layout({ children }: LayoutProps) { ] return ( -
+
{/* Header */} -
+
- -

+ +

Speaker Recognition System

-
+
+ +
@@ -54,8 +57,8 @@ export default function Layout({ children }: LayoutProps) { to={path} className={`flex items-center space-x-3 px-3 py-2 rounded-md text-sm font-medium transition-colors ${ location.pathname === path - ? 'bg-blue-100 text-blue-900' - : 'text-gray-700 hover:bg-gray-100' + ? 'bg-blue-100 text-blue-900 dark:bg-blue-900 dark:text-blue-100' + : 'input-label hover-bg' }`} > @@ -77,9 +80,9 @@ export default function Layout({ children }: LayoutProps) {
{/* Footer */} -