diff --git a/app/locales/ar.json b/app/locales/ar.json index a23c48d..de977c5 100644 --- a/app/locales/ar.json +++ b/app/locales/ar.json @@ -6,6 +6,8 @@ "title": "تسجيل الدخول", "username": "أدخل اسم المستخدم", "button": "تسجيل الدخول", + "camera": "الكاميرا", + "microphone": "الميكروفون", "enterUsername": "يرجى إدخال اسم المستخدم" }, "room": { diff --git a/app/locales/de.json b/app/locales/de.json index e00db42..01ce47f 100644 --- a/app/locales/de.json +++ b/app/locales/de.json @@ -6,6 +6,8 @@ "title": "Anmelden", "username": "Benutzernamen eingeben", "button": "Anmelden", + "camera": "Kamera", + "microphone": "Mikrofon", "enterUsername": "Bitte geben Sie Ihren Benutzernamen ein" }, "room": { diff --git a/app/locales/en.json b/app/locales/en.json index a529014..1225362 100644 --- a/app/locales/en.json +++ b/app/locales/en.json @@ -6,6 +6,8 @@ "title": "Sign In", "username": "Enter username", "button": "Sign In", + "camera": "Camera", + "microphone": "Microphone", "enterUsername": "Please enter your username" }, "room": { diff --git a/app/locales/es.json b/app/locales/es.json index 416b9ff..f872ee5 100644 --- a/app/locales/es.json +++ b/app/locales/es.json @@ -6,6 +6,8 @@ "title": "Iniciar Sesión", "username": "Ingrese nombre de usuario", "button": "Iniciar Sesión", + "camera": "Cámara", + "microphone": "Micrófono", "enterUsername": "Por favor ingrese su nombre de usuario" }, "room": { diff --git a/app/locales/fr.json b/app/locales/fr.json index 5fc6d67..573f818 100644 --- a/app/locales/fr.json +++ b/app/locales/fr.json @@ -6,6 +6,8 @@ "title": "Se Connecter", "username": "Entrez le nom d'utilisateur", "button": "Se Connecter", + "camera": "Caméra", + "microphone": "Microphone", "enterUsername": "Veuillez entrer votre nom d'utilisateur" }, "room": { diff --git a/app/locales/hi.json b/app/locales/hi.json index 1e25e91..3f5d6e3 100644 --- a/app/locales/hi.json +++ b/app/locales/hi.json @@ -6,6 +6,8 @@ "title": "साइन इन", "username": "उपयोगकर्ता नाम दर्ज करें", "button": "साइन इन", + "camera": "कैमरा", + "microphone": "माइक्रोफ़ोन", "enterUsername": "कृपया अपना उपयोगकर्ता नाम दर्ज करें" }, "room": { diff --git a/app/locales/hr.json b/app/locales/hr.json index ff9d1f5..e156a0e 100644 --- a/app/locales/hr.json +++ b/app/locales/hr.json @@ -6,6 +6,8 @@ "title": "Prijava", "username": "Unesite korisničko ime", "button": "Prijavi se", + "camera": "Kamera", + "microphone": "Mikrofon", "enterUsername": "Molimo unesite svoje korisničko ime" }, "room": { diff --git a/app/locales/it.json b/app/locales/it.json index 69f75bf..e509c90 100644 --- a/app/locales/it.json +++ b/app/locales/it.json @@ -6,6 +6,8 @@ "title": "Accedi", "username": "Inserisci nome utente", "button": "Accedi", + "camera": "Fotocamera", + "microphone": "Microfono", "enterUsername": "Inserisci il tuo nome utente" }, "room": { diff --git a/app/locales/ja.json b/app/locales/ja.json index 7b5ffbd..3d591ca 100644 --- a/app/locales/ja.json +++ b/app/locales/ja.json @@ -6,6 +6,8 @@ "title": "サインイン", "username": "ユーザー名を入力", "button": "サインイン", + "camera": "カメラ", + "microphone": "マイク", "enterUsername": "ユーザー名を入力してください" }, "room": { diff --git a/app/locales/pt.json b/app/locales/pt.json index 7ae9efe..c51914c 100644 --- a/app/locales/pt.json +++ b/app/locales/pt.json @@ -6,6 +6,8 @@ "title": "Entrar", "username": "Digite o nome de usuário", "button": "Entrar", + "camera": "Câmera", + "microphone": "Microfone", "enterUsername": "Por favor, digite seu nome de usuário" }, "room": { diff --git a/app/locales/ru.json b/app/locales/ru.json index 10b1602..f8265e1 100644 --- a/app/locales/ru.json +++ b/app/locales/ru.json @@ -6,6 +6,8 @@ "title": "Войти", "username": "Введите имя пользователя", "button": "Войти", + "camera": "Камера", + "microphone": "Микрофон", "enterUsername": "Пожалуйста, введите имя пользователя" }, "room": { diff --git a/app/locales/sr.json b/app/locales/sr.json index 1058dd4..fbbee44 100644 --- a/app/locales/sr.json +++ b/app/locales/sr.json @@ -6,6 +6,8 @@ "title": "Prijava", "username": "Unesite korisničko ime", "button": "Prijavi se", + "camera": "Камера", + "microphone": "Микрофон", "enterUsername": "Molimo unesite svoje korisničko ime" }, "room": { diff --git a/app/locales/zh.json b/app/locales/zh.json index 45b3eb0..b6213bc 100644 --- a/app/locales/zh.json +++ b/app/locales/zh.json @@ -6,6 +6,8 @@ "title": "登录", "username": "请输入用户名", "button": "登录", + "camera": "摄像头", + "microphone": "麦克风", "enterUsername": "请输入您的用户名" }, "room": { diff --git a/package-lock.json b/package-lock.json index 69751f6..c35e523 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "call-me", - "version": "1.3.02", + "version": "1.3.03", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "call-me", - "version": "1.3.02", + "version": "1.3.03", "license": "AGPLv3", "dependencies": { "@ngrok/ngrok": "1.7.0", diff --git a/package.json b/package.json index 09b2dc0..f1874a8 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "call-me", - "version": "1.3.02", + "version": "1.3.03", "description": "Your Go-To for Instant Video Calls", "author": "Miroslav Pejic - miroslav.pejic.85@gmail.com", "license": "AGPLv3", diff --git a/public/client.js b/public/client.js index 338d9da..62e0af0 100755 --- a/public/client.js +++ b/public/client.js @@ -19,6 +19,8 @@ const githubDiv = document.getElementById('githubDiv'); const signInPage = document.getElementById('signInPage'); const usernameIn = document.getElementById('usernameIn'); const signInBtn = document.getElementById('signInBtn'); +const joinVideoToggle = document.getElementById('joinVideoToggle'); +const joinAudioToggle = document.getElementById('joinAudioToggle'); const roomPage = document.getElementById('roomPage'); const exitSidebarBtn = document.getElementById('exitSidebarBtn'); const userSidebar = document.getElementById('userSidebar'); @@ -1271,6 +1273,22 @@ async function handleSignIn(data) { await initializeDeviceSettings(); handleVideoMirror(localVideo, myStream); + // Apply initial media toggles from sign-in card + if (!joinVideoToggle.checked) { + const vt = stream.getVideoTracks()[0]; + if (vt) { + vt.stop(); + vt.enabled = false; + } + videoBtn.classList.add('btn-danger'); + showCameraOffOverlay('local', true); + } + if (!joinAudioToggle.checked) { + const at = stream.getAudioTracks()[0]; + if (at) at.enabled = false; + audioBtn.classList.add('btn-danger'); + } + // Update UI based on available devices updateUIForAvailableDevices(); diff --git a/public/index.html b/public/index.html index 2a06498..9b284b0 100755 --- a/public/index.html +++ b/public/index.html @@ -78,6 +78,29 @@ required /> + +
+ + +
diff --git a/public/style.css b/public/style.css index ce03a28..a301b01 100644 --- a/public/style.css +++ b/public/style.css @@ -270,6 +270,124 @@ button { text-align: center !important; } +/* Media toggle switches on sign-in card */ +.media-toggles { + display: flex; + flex-direction: column; + gap: var(--spacing-sm); + max-width: 320px; + margin: 0 auto; +} + +.media-toggle-item { + display: flex; + align-items: center; + gap: var(--spacing-md); + padding: var(--spacing-sm) var(--spacing-md); + border-radius: var(--border-radius-sm); + background: rgba(255, 255, 255, 0.04); + border: 1px solid var(--glass-border); + cursor: pointer; + transition: all var(--transition-base); + user-select: none; +} + +.media-toggle-item:hover { + background: rgba(255, 255, 255, 0.08); + border-color: var(--glass-border-hover); +} + +.media-toggle-item:has(input:not(:checked)) { + opacity: 0.6; +} + +.media-toggle-item:has(input:not(:checked)):hover { + opacity: 0.8; +} + +.media-toggle-icon { + display: flex; + align-items: center; + justify-content: center; + width: 34px; + height: 34px; + border-radius: var(--border-radius-sm); + background: rgba(59, 130, 246, 0.15); + color: var(--primary-light); + font-size: var(--font-size-base); + flex-shrink: 0; + transition: all var(--transition-base); +} + +.media-toggle-item:has(input:not(:checked)) .media-toggle-icon { + background: rgba(239, 68, 68, 0.15); + color: var(--danger-color); +} + +.media-toggle-label { + flex: 1; + text-align: left; + color: var(--text-secondary); + font-size: var(--font-size-sm); + font-weight: var(--font-weight-medium); + transition: color var(--transition-base); +} + +.media-toggle-item:has(input:checked) .media-toggle-label { + color: var(--text-color); +} + +/* Toggle switch */ +.switch { + position: relative; + display: inline-block; + width: 44px; + height: 24px; + flex-shrink: 0; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.switch .slider { + position: absolute; + cursor: pointer; + inset: 0; + background: var(--bg-tertiary); + border: 1px solid var(--glass-border); + border-radius: 24px; + transition: var(--transition-base); +} + +.switch .slider::before { + content: ''; + position: absolute; + height: 18px; + width: 18px; + left: 2px; + bottom: 2px; + background: var(--text-muted); + border-radius: 50%; + transition: var(--transition-base); +} + +.switch input:checked + .slider { + background: var(--primary-color); + border-color: var(--primary-color); +} + +.switch input:checked + .slider::before { + transform: translateX(20px); + background: #fff; +} + +.switch input:focus + .slider { + box-shadow: 0 0 4px var(--primary-color); +} + /* Video Styles */ video { width: 100%;