feat: add dark mode support for meeting join and start processes
Build & Push Docker Image / build (push) Successful in 4m14s

This commit is contained in:
2026-06-11 09:27:34 +02:00
parent fbbcd79719
commit 4621010bd7
6 changed files with 33 additions and 10 deletions
+4 -2
View File
@@ -2,6 +2,7 @@ import { Users, Play, Trash2, Radio, Loader2, Share2, Copy, Link } from 'lucide-
import { useNavigate } from 'react-router-dom';
import { useState, useEffect, useRef } from 'react';
import api from '../services/api';
import { isCurrentThemeDark } from '../themes';
import { useLanguage } from '../contexts/LanguageContext';
import toast from 'react-hot-toast';
@@ -107,11 +108,12 @@ export default function RoomCard({ room, onDelete }) {
setStarting(true);
try {
if (status.running) {
const data = room.access_code ? { access_code: prompt(t('room.enterAccessCode')) } : {};
const data = { dark_mode: isCurrentThemeDark() };
if (room.access_code) data.access_code = prompt(t('room.enterAccessCode'));
const res = await api.post(`/rooms/${room.uid}/join`, data);
if (res.data.joinUrl) window.open(res.data.joinUrl, '_blank');
} else {
const res = await api.post(`/rooms/${room.uid}/start`);
const res = await api.post(`/rooms/${room.uid}/start`, { dark_mode: isCurrentThemeDark() });
if (res.data.joinUrl) window.open(res.data.joinUrl, '_blank');
toast.success(t('room.meetingStarted'));
setTimeout(() => {
+2
View File
@@ -3,6 +3,7 @@ import { useParams, Link, useSearchParams, useNavigate } from 'react-router-dom'
import { Video, User, Lock, Shield, ArrowRight, Loader2, Users, Radio, AlertCircle, FileText, Clock, X } from 'lucide-react';
import BrandLogo from '../components/BrandLogo';
import api from '../services/api';
import { isCurrentThemeDark } from '../themes';
import toast from 'react-hot-toast';
import { useLanguage } from '../contexts/LanguageContext';
import { useAuth } from '../contexts/AuthContext';
@@ -35,6 +36,7 @@ export default function GuestJoin() {
name: name.trim(),
access_code: accessCode || undefined,
moderator_code: moderatorCode || undefined,
dark_mode: isCurrentThemeDark(),
};
// If logged in, send avatar data
if (isLoggedIn && user) {
+5 -3
View File
@@ -8,6 +8,7 @@ import {
} from 'lucide-react';
import Modal from '../components/Modal';
import api from '../services/api';
import { isCurrentThemeDark } from '../themes';
import { useAuth } from '../contexts/AuthContext';
import { useLanguage } from '../contexts/LanguageContext';
import RecordingList from '../components/RecordingList';
@@ -124,7 +125,7 @@ export default function RoomDetail() {
toast.success(t('room.meetingStarted'));
setWaitingToJoin(false);
setActionLoading('join');
api.post(`/rooms/${uid}/join`, {})
api.post(`/rooms/${uid}/join`, { dark_mode: isCurrentThemeDark() })
.then(res => { if (res.data.joinUrl) window.open(res.data.joinUrl, '_blank'); })
.catch(err => toast.error(err.response?.data?.error || t('room.joinFailed')))
.finally(() => setActionLoading(null));
@@ -135,7 +136,7 @@ export default function RoomDetail() {
const handleStart = async () => {
setActionLoading('start');
try {
const res = await api.post(`/rooms/${uid}/start`);
const res = await api.post(`/rooms/${uid}/start`, { dark_mode: isCurrentThemeDark() });
if (res.data.joinUrl) {
window.open(res.data.joinUrl, '_blank');
}
@@ -157,7 +158,8 @@ export default function RoomDetail() {
setWaitingToJoin(false);
setActionLoading('join');
try {
const data = room.access_code ? { access_code: prompt(t('room.enterAccessCode')) } : {};
const data = { dark_mode: isCurrentThemeDark() };
if (room.access_code) data.access_code = prompt(t('room.enterAccessCode'));
const res = await api.post(`/rooms/${uid}/join`, data);
if (res.data.joinUrl) {
window.open(res.data.joinUrl, '_blank');
+12
View File
@@ -173,6 +173,18 @@ export function getThemeById(id) {
return themes.find(t => t.id === id) || themes[1]; // default to dark
}
// Whether the currently applied theme is a dark one. Reads the resolved theme
// from the <html data-theme> attribute (set by ThemeContext) with a localStorage
// fallback, so it works without React context — handy for one-off API payloads
// such as the BBB join call that forwards dark mode to the meeting.
export function isCurrentThemeDark() {
const id = (typeof document !== 'undefined'
&& document.documentElement.getAttribute('data-theme'))
|| (typeof localStorage !== 'undefined' && localStorage.getItem('theme'))
|| 'dark';
return getThemeById(id).type === 'dark';
}
export function getThemeGroups() {
const groups = {};
themes.forEach(theme => {