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
All checks were successful
Build & Push Docker Image / build (push) Successful in 6m25s
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user