feat:The sender side has also added the exit room function

This commit is contained in:
david_bai
2025-08-13 23:41:35 +08:00
parent 7038e79726
commit abe3220d0f
4 changed files with 69 additions and 44 deletions
+4 -2
View File
@@ -116,7 +116,8 @@ const ClipboardApp = () => {
processRoomIdInput,
joinRoom,
generateShareLinkAndBroadcast,
handleLeaveRoom,
handleLeaveReceiverRoom,
handleLeaveSenderRoom,
} = useRoomManager({
messages,
putMessageInMs,
@@ -269,6 +270,7 @@ const ClipboardApp = () => {
sender={sender}
shareMessage={shareMessage}
currentValidatedShareRoomId={shareRoomId}
handleLeaveSenderRoom={handleLeaveSenderRoom}
/>
) : (
<RetrieveTabPanel
@@ -293,7 +295,7 @@ const ClipboardApp = () => {
getReceiverSaveType={getReceiverSaveType}
retrieveMessage={retrieveMessage}
senderDisconnected={senderDisconnected}
handleLeaveRoom={handleLeaveRoom}
handleLeaveRoom={handleLeaveReceiverRoom}
/>
)}
</CardContent>
@@ -137,9 +137,9 @@ export function RetrieveTabPanel({
className="flex-grow min-w-0"
/>
</div>
<div className="mb-3">
<div className="flex gap-2 mb-3">
<Button
className="w-full"
className="flex-1"
onClick={() => joinRoom(false, retrieveRoomIdInput)}
ref={retrieveJoinRoomBtnRef}
disabled={
@@ -148,18 +148,14 @@ export function RetrieveTabPanel({
>
{messages.text.ClipboardApp.html.joinRoom_dis}
</Button>
<Button
variant="outline"
onClick={handleLeaveRoom}
disabled={!receiver || !receiver.isInRoom || isAnyFileTransferring}
>
Leave Room
</Button>
</div>
{senderDisconnected && (
<div className="mb-3">
<Button
className="w-full"
variant="destructive"
onClick={handleLeaveRoom}
>
{messages.text.ClipboardApp.html.leaveRoom_dis || "Leave Room"}
</Button>
</div>
)}
{retrievedContent && (
<div className="my-3 p-2 border rounded bg-gray-50">
<RichTextEditor
@@ -47,6 +47,7 @@ interface SendTabPanelProps {
// Pass the validated/initial shareRoomId from useRoomManager for display/initialization
// Also, initShareRoomId can be useful if we want to reset the input to it.
currentValidatedShareRoomId: string;
handleLeaveSenderRoom: () => void; // New prop for leaving room
// initShareRoomId: string; // If needed for reset logic
}
@@ -67,6 +68,7 @@ export function SendTabPanel({
sender,
shareMessage,
currentValidatedShareRoomId,
handleLeaveSenderRoom,
}: // initShareRoomId,
SendTabPanelProps) {
// Local state for immediate response in the input field
@@ -145,20 +147,28 @@ SendTabPanelProps) {
{messages.text.ClipboardApp.html.joinRoom_dis}
</Button>
</div>
<div className="flex">
<div className="flex gap-2">
<AnimatedButton
className="w-full"
className="flex-1"
onClick={generateShareLinkAndBroadcast}
loadingText={messages.text.ClipboardApp.html.SyncSending_loadingText}
disabled={
!sender ||
!sender.isInRoom ||
(sendFiles.length === 0 && shareContent.trim() === "") ||
!currentValidatedShareRoomId.trim()
!currentValidatedShareRoomId.trim() ||
isAnyFileTransferring
} // Ensure there is a validated room ID before allowing sharing
>
{messages.text.ClipboardApp.html.SyncSending_dis}
</AnimatedButton>
<Button
variant="outline"
onClick={handleLeaveSenderRoom}
disabled={!sender || !sender.isInRoom || isAnyFileTransferring}
>
Leave Room
</Button>
</div>
{shareMessage && (
<p className="mt-3 text-sm text-blue-600">{shareMessage}</p>
+43 -26
View File
@@ -43,9 +43,9 @@ export function useRoomManager({
const [shareLink, setShareLink] = useState("");
const [shareRoomStatusText, setShareRoomStatusText] = useState("");
const [retrieveRoomStatusText, setRetrieveRoomStatusText] = useState("");
const autoLeaveTimer = useRef<NodeJS.Timeout | null>(null);
const handleLeaveRoom = useCallback(async () => {
// Receiver leave room function (renamed and simplified)
const handleLeaveReceiverRoom = useCallback(async () => {
if (!receiver || !receiver.roomId || !receiver.peerId) return;
try {
await leaveRoom(receiver.roomId, receiver.peerId);
@@ -56,13 +56,47 @@ export function useRoomManager({
} finally {
// Reset application state
resetApp();
if (autoLeaveTimer.current) {
clearTimeout(autoLeaveTimer.current);
autoLeaveTimer.current = null;
}
}
}, [receiver, putMessageInMs, resetApp]);
// Sender leave room function (new)
const handleLeaveSenderRoom = useCallback(async () => {
if (!sender || !sender.roomId || !sender.peerId) return;
try {
await leaveRoom(sender.roomId, sender.peerId);
putMessageInMs("You have left the room.", true);
} catch (error) {
console.error("Error leaving room:", error);
putMessageInMs("Failed to leave the room.", true);
} finally {
// Reset sender state and get new room ID
await resetSenderApp();
}
}, [sender, putMessageInMs]);
// Reset sender app state (preserve send content, get new room ID)
const resetSenderApp = useCallback(async () => {
try {
// 1. Clean up WebRTC connections
if (sender) {
await sender.leaveRoomAndCleanup();
}
// 2. Clear share link
setShareLink("");
// 3. Get new room ID from backend
const newRoomId = await fetchRoom();
setShareRoomId(newRoomId || "");
setInitShareRoomId(newRoomId || "");
console.log("Sender application state reset successfully, new room ID:", newRoomId);
} catch (error) {
console.error("Error during sender state reset:", error);
putMessageInMs("Error resetting sender state.", true);
}
}, [sender, putMessageInMs]);
// Initialize shareRoomId on mount
useEffect(() => {
if (
@@ -304,25 +338,7 @@ export function useRoomManager({
senderDisconnected,
]);
useEffect(() => {
if (activeTab === "retrieve" && senderDisconnected) {
setRetrieveRoomStatusText(
messages?.text.ClipboardApp.roomStatus.senderDisconnected_dis ||
"The sender has disconnected. The room will close in 15 minutes."
);
// Set a timer to automatically leave the room
autoLeaveTimer.current = setTimeout(() => {
handleLeaveRoom();
}, 900000); // 15 minutes
}
return () => {
// Cleanup timer if the component unmounts or dependencies change
if (autoLeaveTimer.current) {
clearTimeout(autoLeaveTimer.current);
}
};
}, [senderDisconnected, activeTab, messages, handleLeaveRoom]);
return {
shareRoomId, // This is the validated or initial room ID
@@ -333,6 +349,7 @@ export function useRoomManager({
processRoomIdInput, // New input processing function
joinRoom,
generateShareLinkAndBroadcast,
handleLeaveRoom,
handleLeaveReceiverRoom, // Renamed function
handleLeaveSenderRoom, // New function
};
}