feat(auth): проверка устройств на входе — запрос доступа и превью камеры
Отключаемый модуль (instance_settings.device_check, дефолт выключен): запрос доступа к камере/микрофону на LoginPage и в карточке "Как вас зовут?" (JoinPage), живое зеркальное превью и кнопки вкл/выкл камеры и микрофона там же. На JoinPage кнопки определяют, с чем гость войдёт в конференцию (RoomPage.LiveKitRoom audio/video вместо жёстких false) — на LoginPage только пре-авторизуют разрешение, без UI (карточка ведёт в лобби, применить выбор некуда). Вход в комнату по умолчанию, как и раньше, с выключенными микрофоном/камерой. Публичный GET /api/v1/public/settings отдаёт флаг модуля обеим страницам до аутентификации.
This commit is contained in:
75
frontend/src/styles/device-check.css
Normal file
75
frontend/src/styles/device-check.css
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* VidConf — превью камеры на входе (сессия 33, `JoinPage`; LoginPage
|
||||
* превью не показывает — см. `DeviceCheckCard` не используется там).
|
||||
* Свой файл: компонент самодостаточный, стили ему не нужны нигде за
|
||||
* пределами компонента.
|
||||
*/
|
||||
|
||||
.device-check { margin: 0 auto var(--space-5); }
|
||||
|
||||
/* Окошко превью и кнопки под ним — одна композиция шириной в половину
|
||||
карточки (`.flow-card`, куда компонент вложен): проценты сами масштабируются
|
||||
от фактической ширины родителя без хардкода пикселей. */
|
||||
.device-check-inner { width: 50%; margin: 0 auto; }
|
||||
|
||||
.device-check-frame {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
aspect-ratio: 4 / 3;
|
||||
border-radius: var(--radius-lg);
|
||||
overflow: hidden;
|
||||
background: var(--color-bg-alt);
|
||||
border: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.device-check-video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
/* Своё видео принято показывать зеркально — так человек видит себя
|
||||
привычно, как в зеркале, а не «как его видят другие». */
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
.device-check-placeholder {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-ink-400);
|
||||
}
|
||||
.device-check-placeholder .lucide { width: 26px; height: 26px; }
|
||||
|
||||
/* Кнопки без подписи, только пиктограммы — их совместная ширина равна
|
||||
ширине окошка превью (тот же `.device-check-inner`), за края не выступают. */
|
||||
.device-check-toggles {
|
||||
display: flex;
|
||||
gap: var(--space-2);
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
|
||||
.device-check-toggle {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 8px 0;
|
||||
border-radius: var(--radius-lg);
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-bg-alt);
|
||||
color: var(--color-ink-500);
|
||||
cursor: pointer;
|
||||
}
|
||||
.device-check-toggle .lucide { width: 18px; height: 18px; }
|
||||
.device-check-toggle.is-on {
|
||||
background: var(--color-accent);
|
||||
border-color: transparent;
|
||||
color: var(--color-accent-text);
|
||||
}
|
||||
.device-check-toggle:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
.device-check-hint {
|
||||
text-align: center;
|
||||
margin-top: var(--space-3);
|
||||
}
|
||||
Reference in New Issue
Block a user