feat(room): add copy link functionality with options for room and guest links
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m25s

This commit is contained in:
2026-03-03 14:23:57 +01:00
parent d886725c4f
commit ba096a31a2
2 changed files with 44 additions and 8 deletions

View File

@@ -126,7 +126,7 @@ export default function RoomCard({ room, onDelete }) {
<Copy size={14} />
</button>
{showCopyMenu && (
<div className="absolute bottom-full right-0 mb-1 bg-th-surface border border-th-border rounded-lg shadow-lg z-50 min-w-[150px] py-1">
<div className="absolute bottom-full right-0 mb-2 bg-th-surface border border-th-border rounded-lg shadow-lg z-50 min-w-[150px] py-1">
<button
onClick={(e) => { e.stopPropagation(); copyToClipboard(`${window.location.origin}/rooms/${room.uid}`); }}
className="w-full flex items-center gap-2 px-3 py-2 text-xs text-th-text hover:bg-th-accent/10 transition-colors"

View File

@@ -4,7 +4,7 @@ import {
ArrowLeft, Play, Square, Users, Settings, FileVideo, Radio,
Loader2, Copy, ExternalLink, Lock, Mic, MicOff, UserCheck,
Shield, Save, UserPlus, X, Share2, Globe, Send,
FileText, Upload, Trash2,
FileText, Upload, Trash2, Link,
} from 'lucide-react';
import Modal from '../components/Modal';
import api from '../services/api';
@@ -33,6 +33,18 @@ export default function RoomDetail() {
const [shareSearching, setShareSearching] = useState(false);
const [waitingToJoin, setWaitingToJoin] = useState(false);
const prevRunningRef = useRef(false);
const [showCopyMenu, setShowCopyMenu] = useState(false);
const copyMenuRef = useRef(null);
useEffect(() => {
const handleClickOutside = (e) => {
if (copyMenuRef.current && !copyMenuRef.current.contains(e.target)) {
setShowCopyMenu(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
// Federation invite state
const [showFedInvite, setShowFedInvite] = useState(false);
@@ -182,9 +194,10 @@ export default function RoomDetail() {
}
};
const copyLink = () => {
navigator.clipboard.writeText(`${window.location.origin}/rooms/${uid}`);
const copyToClipboard = (url) => {
navigator.clipboard.writeText(url);
toast.success(t('room.linkCopied'));
setShowCopyMenu(false);
};
// Federation invite handler
@@ -356,10 +369,33 @@ export default function RoomDetail() {
{t('common.protected')}
</span>
)}
<button onClick={copyLink} className="flex items-center gap-1 hover:text-th-accent transition-colors">
<Copy size={14} />
{t('room.copyLink')}
</button>
<div className="relative" ref={copyMenuRef}>
<button
onClick={() => setShowCopyMenu(v => !v)}
className="flex items-center gap-1 hover:text-th-accent transition-colors"
>
<Copy size={14} />
{t('room.copyLink')}
</button>
{showCopyMenu && (
<div className="absolute bottom-full left-0 mb-2 bg-th-surface border border-th-border rounded-lg shadow-lg z-50 min-w-[160px] py-1">
<button
onClick={() => copyToClipboard(`${window.location.origin}/rooms/${uid}`)}
className="w-full flex items-center gap-2 px-3 py-2 text-xs text-th-text hover:bg-th-accent/10 transition-colors"
>
<Link size={12} />
{t('room.copyRoomLink')}
</button>
<button
onClick={() => copyToClipboard(`${window.location.origin}/join/${uid}`)}
className="w-full flex items-center gap-2 px-3 py-2 text-xs text-th-text hover:bg-th-accent/10 transition-colors"
>
<Users size={12} />
{t('room.copyGuestLink')}
</button>
</div>
)}
</div>
</div>
</div>