fix: resolve ReferenceError issues and improve disconnect functionality
- Add missing sessionTimeLeft state variable to fix ReferenceError in handleDisconnect - Fix ReferenceError in handleCreateAnswer by correcting variable scope (e.target.value -> answerInput) - Add type checking for answerData.trim() to prevent TypeError in shouldPreserveAnswerData - Standardize data types by replacing null assignments with empty strings for offerData/answerData - Improve handleDisconnect function with proper error handling and comprehensive state cleanup - Add try-catch wrapper around disconnect operations for better error handling - Ensure complete metadata removal and connection termination on disconnect - Fix Bluetooth transfer modal opening with proper role-based event dispatching
This commit is contained in:
240
dist/app.js
vendored
240
dist/app.js
vendored
@@ -709,25 +709,30 @@ var EnhancedConnectionSetup = ({
|
|||||||
className: "fas fa-qrcode mr-2"
|
className: "fas fa-qrcode mr-2"
|
||||||
}),
|
}),
|
||||||
"Scan QR Code"
|
"Scan QR Code"
|
||||||
|
]),
|
||||||
|
React.createElement("button", {
|
||||||
|
key: "bluetooth-btn",
|
||||||
|
onClick: () => {
|
||||||
|
try {
|
||||||
|
document.dispatchEvent(new CustomEvent("open-bluetooth-transfer", { detail: { role: "responder" } }));
|
||||||
|
} catch {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
className: "px-4 py-2 bg-blue-500/10 hover:bg-blue-500/20 text-blue-400 border border-blue-500/20 rounded text-sm font-medium transition-all duration-200"
|
||||||
|
}, [
|
||||||
|
React.createElement("i", {
|
||||||
|
key: "icon",
|
||||||
|
className: "fas fa-bluetooth mr-2"
|
||||||
|
}),
|
||||||
|
"Bluetooth"
|
||||||
])
|
])
|
||||||
// React.createElement('button', {
|
|
||||||
// key: 'bluetooth-btn',
|
|
||||||
// onClick: () => { try { document.dispatchEvent(new CustomEvent('open-bluetooth-transfer', { detail: { role: 'responder' } })); } catch {} },
|
|
||||||
// className: "px-4 py-2 bg-blue-500/10 hover:bg-blue-500/20 text-blue-400 border border-blue-500/20 rounded text-sm font-medium transition-all duration-200"
|
|
||||||
// }, [
|
|
||||||
// React.createElement('i', {
|
|
||||||
// key: 'icon',
|
|
||||||
// className: 'fas fa-bluetooth mr-2'
|
|
||||||
// }),
|
|
||||||
// 'Bluetooth'
|
|
||||||
// ])
|
|
||||||
]),
|
]),
|
||||||
React.createElement("textarea", {
|
React.createElement("textarea", {
|
||||||
key: "input",
|
key: "input",
|
||||||
value: answerInput,
|
value: answerInput,
|
||||||
onChange: (e2) => {
|
onChange: (e) => {
|
||||||
setAnswerInput(e2.target.value);
|
setAnswerInput(e.target.value);
|
||||||
if (e2.target.value.trim().length > 0) {
|
if (e.target.value.trim().length > 0) {
|
||||||
if (typeof markAnswerCreated === "function") {
|
if (typeof markAnswerCreated === "function") {
|
||||||
markAnswerCreated();
|
markAnswerCreated();
|
||||||
}
|
}
|
||||||
@@ -803,9 +808,9 @@ var EnhancedConnectionSetup = ({
|
|||||||
React.createElement("textarea", {
|
React.createElement("textarea", {
|
||||||
key: "input",
|
key: "input",
|
||||||
value: offerInput,
|
value: offerInput,
|
||||||
onChange: (e2) => {
|
onChange: (e) => {
|
||||||
setOfferInput(e2.target.value);
|
setOfferInput(e.target.value);
|
||||||
if (e2.target.value.trim().length > 0) {
|
if (e.target.value.trim().length > 0) {
|
||||||
if (typeof markAnswerCreated === "function") {
|
if (typeof markAnswerCreated === "function") {
|
||||||
markAnswerCreated();
|
markAnswerCreated();
|
||||||
}
|
}
|
||||||
@@ -830,17 +835,22 @@ var EnhancedConnectionSetup = ({
|
|||||||
}),
|
}),
|
||||||
"Scan QR Code"
|
"Scan QR Code"
|
||||||
]),
|
]),
|
||||||
// React.createElement('button', {
|
React.createElement("button", {
|
||||||
// key: 'bluetooth-btn',
|
key: "bluetooth-btn",
|
||||||
// onClick: () => { try { document.dispatchEvent(new CustomEvent('open-bluetooth-transfer', { detail: { role: 'initiator' } })); } catch {} },
|
onClick: () => {
|
||||||
// className: "px-4 py-2 bg-blue-500/10 hover:bg-blue-500/20 text-blue-400 border border-blue-500/20 rounded text-sm font-medium transition-all duration-200"
|
try {
|
||||||
// }, [
|
document.dispatchEvent(new CustomEvent("open-bluetooth-transfer", { detail: { role: "initiator" } }));
|
||||||
// React.createElement('i', {
|
} catch {
|
||||||
// key: 'icon',
|
}
|
||||||
// className: 'fas fa-bluetooth mr-2'
|
},
|
||||||
// }),
|
className: "px-4 py-2 bg-blue-500/10 hover:bg-blue-500/20 text-blue-400 border border-blue-500/20 rounded text-sm font-medium transition-all duration-200"
|
||||||
// 'Bluetooth'
|
}, [
|
||||||
// ]),
|
React.createElement("i", {
|
||||||
|
key: "icon",
|
||||||
|
className: "fas fa-bluetooth mr-2"
|
||||||
|
}),
|
||||||
|
"Bluetooth"
|
||||||
|
]),
|
||||||
React.createElement("button", {
|
React.createElement("button", {
|
||||||
key: "process-btn",
|
key: "process-btn",
|
||||||
onClick: onCreateAnswer,
|
onClick: onCreateAnswer,
|
||||||
@@ -1107,9 +1117,9 @@ var EnhancedChatInterface = ({
|
|||||||
setShowScrollButton(false);
|
setShowScrollButton(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const handleKeyPress = (e2) => {
|
const handleKeyPress = (e) => {
|
||||||
if (e2.key === "Enter" && !e2.shiftKey) {
|
if (e.key === "Enter" && !e.shiftKey) {
|
||||||
e2.preventDefault();
|
e.preventDefault();
|
||||||
onSendMessage();
|
onSendMessage();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1294,7 +1304,7 @@ var EnhancedChatInterface = ({
|
|||||||
[
|
[
|
||||||
React.createElement("textarea", {
|
React.createElement("textarea", {
|
||||||
value: messageInput,
|
value: messageInput,
|
||||||
onChange: (e2) => setMessageInput(e2.target.value),
|
onChange: (e) => setMessageInput(e.target.value),
|
||||||
onKeyDown: handleKeyPress,
|
onKeyDown: handleKeyPress,
|
||||||
placeholder: "Enter message to encrypt...",
|
placeholder: "Enter message to encrypt...",
|
||||||
rows: 2,
|
rows: 2,
|
||||||
@@ -1357,9 +1367,9 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
const [showBluetoothTransfer, setShowBluetoothTransfer] = React.useState(false);
|
const [showBluetoothTransfer, setShowBluetoothTransfer] = React.useState(false);
|
||||||
const [bluetoothAutoRole, setBluetoothAutoRole] = React.useState(null);
|
const [bluetoothAutoRole, setBluetoothAutoRole] = React.useState(null);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const openBt = (e2) => {
|
const openBt = (e) => {
|
||||||
try {
|
try {
|
||||||
const role = e2?.detail?.role || null;
|
const role = e?.detail?.role || null;
|
||||||
setBluetoothAutoRole(role);
|
setBluetoothAutoRole(role);
|
||||||
setShowBluetoothTransfer(true);
|
setShowBluetoothTransfer(true);
|
||||||
} catch {
|
} catch {
|
||||||
@@ -1371,6 +1381,7 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
const [bluetoothManager, setBluetoothManager] = React.useState(null);
|
const [bluetoothManager, setBluetoothManager] = React.useState(null);
|
||||||
const [isVerified, setIsVerified] = React.useState(false);
|
const [isVerified, setIsVerified] = React.useState(false);
|
||||||
const [securityLevel, setSecurityLevel] = React.useState(null);
|
const [securityLevel, setSecurityLevel] = React.useState(null);
|
||||||
|
const [sessionTimeLeft, setSessionTimeLeft] = React.useState(0);
|
||||||
const [localVerificationConfirmed, setLocalVerificationConfirmed] = React.useState(false);
|
const [localVerificationConfirmed, setLocalVerificationConfirmed] = React.useState(false);
|
||||||
const [remoteVerificationConfirmed, setRemoteVerificationConfirmed] = React.useState(false);
|
const [remoteVerificationConfirmed, setRemoteVerificationConfirmed] = React.useState(false);
|
||||||
const [bothVerificationsConfirmed, setBothVerificationsConfirmed] = React.useState(false);
|
const [bothVerificationsConfirmed, setBothVerificationsConfirmed] = React.useState(false);
|
||||||
@@ -1395,7 +1406,7 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const answerAge = now - (connectionState.answerCreatedAt || 0);
|
const answerAge = now - (connectionState.answerCreatedAt || 0);
|
||||||
const maxPreserveTime = 3e5;
|
const maxPreserveTime = 3e5;
|
||||||
const hasAnswerData = answerData && answerData.trim().length > 0 || answerInput && answerInput.trim().length > 0;
|
const hasAnswerData = answerData && typeof answerData === "string" && answerData.trim().length > 0 || answerInput && answerInput.trim().length > 0;
|
||||||
const hasAnswerQR = qrCodeUrl && qrCodeUrl.trim().length > 0;
|
const hasAnswerQR = qrCodeUrl && qrCodeUrl.trim().length > 0;
|
||||||
const shouldPreserve = connectionState.hasActiveAnswer && answerAge < maxPreserveTime && !connectionState.isUserInitiatedDisconnect || hasAnswerData && answerAge < maxPreserveTime && !connectionState.isUserInitiatedDisconnect || hasAnswerQR && answerAge < maxPreserveTime && !connectionState.isUserInitiatedDisconnect;
|
const shouldPreserve = connectionState.hasActiveAnswer && answerAge < maxPreserveTime && !connectionState.isUserInitiatedDisconnect || hasAnswerData && answerAge < maxPreserveTime && !connectionState.isUserInitiatedDisconnect || hasAnswerQR && answerAge < maxPreserveTime && !connectionState.isUserInitiatedDisconnect;
|
||||||
return shouldPreserve;
|
return shouldPreserve;
|
||||||
@@ -1584,8 +1595,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
setLocalVerificationConfirmed(false);
|
setLocalVerificationConfirmed(false);
|
||||||
setRemoteVerificationConfirmed(false);
|
setRemoteVerificationConfirmed(false);
|
||||||
setBothVerificationsConfirmed(false);
|
setBothVerificationsConfirmed(false);
|
||||||
setOfferData(null);
|
setOfferData("");
|
||||||
setAnswerData(null);
|
setAnswerData("");
|
||||||
setOfferInput("");
|
setOfferInput("");
|
||||||
setAnswerInput("");
|
setAnswerInput("");
|
||||||
setShowOfferStep(false);
|
setShowOfferStep(false);
|
||||||
@@ -1596,8 +1607,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setConnectionStatus("disconnected");
|
setConnectionStatus("disconnected");
|
||||||
setShowVerification(false);
|
setShowVerification(false);
|
||||||
setOfferData(null);
|
setOfferData("");
|
||||||
setAnswerData(null);
|
setAnswerData("");
|
||||||
setOfferInput("");
|
setOfferInput("");
|
||||||
setAnswerInput("");
|
setAnswerInput("");
|
||||||
setShowOfferStep(false);
|
setShowOfferStep(false);
|
||||||
@@ -1617,8 +1628,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
setLocalVerificationConfirmed(false);
|
setLocalVerificationConfirmed(false);
|
||||||
setRemoteVerificationConfirmed(false);
|
setRemoteVerificationConfirmed(false);
|
||||||
setBothVerificationsConfirmed(false);
|
setBothVerificationsConfirmed(false);
|
||||||
setOfferData(null);
|
setOfferData("");
|
||||||
setAnswerData(null);
|
setAnswerData("");
|
||||||
setOfferInput("");
|
setOfferInput("");
|
||||||
setAnswerInput("");
|
setAnswerInput("");
|
||||||
setShowOfferStep(false);
|
setShowOfferStep(false);
|
||||||
@@ -1749,9 +1760,9 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
a.download = fileData.fileName;
|
a.download = fileData.fileName;
|
||||||
a.click();
|
a.click();
|
||||||
setTimeout(() => fileData.revokeObjectURL(url), 15e3);
|
setTimeout(() => fileData.revokeObjectURL(url), 15e3);
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.error("Download failed:", e2);
|
console.error("Download failed:", e);
|
||||||
addMessageWithAutoScroll(` File upload error: ${String(e2?.message || e2)}`, "system");
|
addMessageWithAutoScroll(` File upload error: ${String(e?.message || e)}`, "system");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, "Download")
|
}, "Download")
|
||||||
@@ -1867,8 +1878,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
const QR_SIZE = isDesktop ? 720 : 512;
|
const QR_SIZE = isDesktop ? 720 : 512;
|
||||||
const url = await (window.generateQRCode ? window.generateQRCode(current, { errorCorrectionLevel: "M", margin: 2, size: QR_SIZE }) : Promise.resolve(""));
|
const url = await (window.generateQRCode ? window.generateQRCode(current, { errorCorrectionLevel: "M", margin: 2, size: QR_SIZE }) : Promise.resolve(""));
|
||||||
if (url) setQrCodeUrl(url);
|
if (url) setQrCodeUrl(url);
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("Animated QR render error (current):", e2);
|
console.warn("Animated QR render error (current):", e);
|
||||||
}
|
}
|
||||||
setQrFrameIndex((qrAnimationRef.current?.idx || 0) % (qrAnimationRef.current?.chunks?.length || 1) + 1);
|
setQrFrameIndex((qrAnimationRef.current?.idx || 0) % (qrAnimationRef.current?.chunks?.length || 1) + 1);
|
||||||
};
|
};
|
||||||
@@ -1974,8 +1985,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
setQrFrameIndex(1);
|
setQrFrameIndex(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("Binary QR generation failed, falling back to compressed:", e2?.message || e2);
|
console.warn("Binary QR generation failed, falling back to compressed:", e?.message || e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (typeof window.generateCompressedQRCode === "function") {
|
if (typeof window.generateCompressedQRCode === "function") {
|
||||||
@@ -1998,8 +2009,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
setQrFrameIndex(1);
|
setQrFrameIndex(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("Compressed QR generation failed, falling back to plain:", e2?.message || e2);
|
console.warn("Compressed QR generation failed, falling back to plain:", e?.message || e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const payload = typeof data === "string" ? data : JSON.stringify(data);
|
const payload = typeof data === "string" ? data : JSON.stringify(data);
|
||||||
@@ -2193,8 +2204,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
qrChunksBufferRef.current = { id: null, total: 0, seen: /* @__PURE__ */ new Set(), items: [] };
|
qrChunksBufferRef.current = { id: null, total: 0, seen: /* @__PURE__ */ new Set(), items: [] };
|
||||||
setShowQRScannerModal(false);
|
setShowQRScannerModal(false);
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("Binary chunks reconstruction failed:", e2);
|
console.warn("Binary chunks reconstruction failed:", e);
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2252,8 +2263,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
qrChunksBufferRef.current = { id: null, total: 0, seen: /* @__PURE__ */ new Set(), items: [] };
|
qrChunksBufferRef.current = { id: null, total: 0, seen: /* @__PURE__ */ new Set(), items: [] };
|
||||||
setShowQRScannerModal(false);
|
setShowQRScannerModal(false);
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("Binary chunks reconstruction failed:", e2);
|
console.warn("Binary chunks reconstruction failed:", e);
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2312,8 +2323,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
qrChunksBufferRef.current = { id: null, total: 0, seen: /* @__PURE__ */ new Set(), items: [] };
|
qrChunksBufferRef.current = { id: null, total: 0, seen: /* @__PURE__ */ new Set(), items: [] };
|
||||||
setShowQRScannerModal(false);
|
setShowQRScannerModal(false);
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("RAW multi-frame reconstruction failed:", e2);
|
console.warn("RAW multi-frame reconstruction failed:", e);
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
} else if (hdr.rt === "bin") {
|
} else if (hdr.rt === "bin") {
|
||||||
@@ -2340,8 +2351,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
qrChunksBufferRef.current = { id: null, total: 0, seen: /* @__PURE__ */ new Set(), items: [] };
|
qrChunksBufferRef.current = { id: null, total: 0, seen: /* @__PURE__ */ new Set(), items: [] };
|
||||||
setShowQRScannerModal(false);
|
setShowQRScannerModal(false);
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("BIN multi-frame reconstruction failed:", e2);
|
console.warn("BIN multi-frame reconstruction failed:", e);
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
} else if (window.receiveAndProcess) {
|
} else if (window.receiveAndProcess) {
|
||||||
@@ -2363,8 +2374,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
setShowQRScannerModal(false);
|
setShowQRScannerModal(false);
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("COSE multi-chunk processing failed:", e2);
|
console.warn("COSE multi-chunk processing failed:", e);
|
||||||
}
|
}
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
} else {
|
} else {
|
||||||
@@ -2626,8 +2637,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("Offer QR generation failed:", e2);
|
console.warn("Offer QR generation failed:", e);
|
||||||
}
|
}
|
||||||
const existingMessages = messages.filter(
|
const existingMessages = messages.filter(
|
||||||
(m) => m.type === "system" && (m.message.includes("Secure invitation created") || m.message.includes("Send the encrypted code"))
|
(m) => m.type === "system" && (m.message.includes("Secure invitation created") || m.message.includes("Send the encrypted code"))
|
||||||
@@ -2749,10 +2760,10 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e2) {
|
} catch (e) {
|
||||||
console.warn("Answer QR generation failed:", e2);
|
console.warn("Answer QR generation failed:", e);
|
||||||
}
|
}
|
||||||
if (e.target.value.trim().length > 0) {
|
if (answerInput.trim().length > 0) {
|
||||||
if (typeof markAnswerCreated === "function") {
|
if (typeof markAnswerCreated === "function") {
|
||||||
markAnswerCreated();
|
markAnswerCreated();
|
||||||
}
|
}
|
||||||
@@ -2936,8 +2947,8 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
setShowVerification(false);
|
setShowVerification(false);
|
||||||
setVerificationCode("");
|
setVerificationCode("");
|
||||||
setConnectionStatus("disconnected");
|
setConnectionStatus("disconnected");
|
||||||
setOfferData(null);
|
setOfferData("");
|
||||||
setAnswerData(null);
|
setAnswerData("");
|
||||||
setOfferInput("");
|
setOfferInput("");
|
||||||
setAnswerInput("");
|
setAnswerInput("");
|
||||||
setShowOfferStep(false);
|
setShowOfferStep(false);
|
||||||
@@ -3008,53 +3019,56 @@ var EnhancedSecureP2PChat = () => {
|
|||||||
document.dispatchEvent(new CustomEvent("peer-disconnect"));
|
document.dispatchEvent(new CustomEvent("peer-disconnect"));
|
||||||
};
|
};
|
||||||
const handleDisconnect = () => {
|
const handleDisconnect = () => {
|
||||||
setSessionTimeLeft(0);
|
try {
|
||||||
updateConnectionState({
|
|
||||||
status: "disconnected",
|
|
||||||
isUserInitiatedDisconnect: true
|
|
||||||
});
|
|
||||||
if (webrtcManagerRef.current) {
|
|
||||||
webrtcManagerRef.current.disconnect();
|
|
||||||
}
|
|
||||||
setKeyFingerprint("");
|
|
||||||
setVerificationCode("");
|
|
||||||
setSecurityLevel(null);
|
|
||||||
setIsVerified(false);
|
|
||||||
setShowVerification(false);
|
|
||||||
setConnectionStatus("disconnected");
|
|
||||||
setLocalVerificationConfirmed(false);
|
|
||||||
setRemoteVerificationConfirmed(false);
|
|
||||||
setBothVerificationsConfirmed(false);
|
|
||||||
setConnectionStatus("disconnected");
|
|
||||||
setShowVerification(false);
|
|
||||||
setOfferData(null);
|
|
||||||
setAnswerData(null);
|
|
||||||
setOfferInput("");
|
|
||||||
setAnswerInput("");
|
|
||||||
setShowOfferStep(false);
|
|
||||||
setShowAnswerStep(false);
|
|
||||||
setKeyFingerprint("");
|
|
||||||
setVerificationCode("");
|
|
||||||
setSecurityLevel(null);
|
|
||||||
setIsVerified(false);
|
|
||||||
setMessages([]);
|
|
||||||
if (typeof console.clear === "function") {
|
|
||||||
console.clear();
|
|
||||||
}
|
|
||||||
document.dispatchEvent(new CustomEvent("peer-disconnect"));
|
|
||||||
document.dispatchEvent(new CustomEvent("disconnected"));
|
|
||||||
document.dispatchEvent(new CustomEvent("session-cleanup", {
|
|
||||||
detail: {
|
|
||||||
timestamp: Date.now(),
|
|
||||||
reason: "manual_disconnect"
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
setTimeout(() => {
|
|
||||||
setSessionTimeLeft(0);
|
setSessionTimeLeft(0);
|
||||||
}, 500);
|
updateConnectionState({
|
||||||
handleClearData();
|
status: "disconnected",
|
||||||
setTimeout(() => {
|
isUserInitiatedDisconnect: true
|
||||||
}, 1e3);
|
});
|
||||||
|
if (webrtcManagerRef.current) {
|
||||||
|
webrtcManagerRef.current.disconnect();
|
||||||
|
}
|
||||||
|
setKeyFingerprint("");
|
||||||
|
setVerificationCode("");
|
||||||
|
setSecurityLevel(null);
|
||||||
|
setIsVerified(false);
|
||||||
|
setShowVerification(false);
|
||||||
|
setConnectionStatus("disconnected");
|
||||||
|
setLocalVerificationConfirmed(false);
|
||||||
|
setRemoteVerificationConfirmed(false);
|
||||||
|
setBothVerificationsConfirmed(false);
|
||||||
|
setOfferData("");
|
||||||
|
setAnswerData("");
|
||||||
|
setOfferInput("");
|
||||||
|
setAnswerInput("");
|
||||||
|
setShowOfferStep(false);
|
||||||
|
setShowAnswerStep(false);
|
||||||
|
setShowQRCode(false);
|
||||||
|
setQrCodeUrl("");
|
||||||
|
setShowQRScanner(false);
|
||||||
|
setShowQRScannerModal(false);
|
||||||
|
setShowBluetoothTransfer(false);
|
||||||
|
setBluetoothAutoRole(null);
|
||||||
|
setMessages([]);
|
||||||
|
if (typeof console.clear === "function") {
|
||||||
|
console.clear();
|
||||||
|
}
|
||||||
|
document.dispatchEvent(new CustomEvent("peer-disconnect"));
|
||||||
|
document.dispatchEvent(new CustomEvent("disconnected"));
|
||||||
|
document.dispatchEvent(new CustomEvent("session-cleanup", {
|
||||||
|
detail: {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
reason: "manual_disconnect"
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
handleClearData();
|
||||||
|
setTimeout(() => {
|
||||||
|
setSessionTimeLeft(0);
|
||||||
|
}, 500);
|
||||||
|
console.log("Disconnect completed successfully");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error during disconnect:", error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const handleSessionActivated = (session) => {
|
const handleSessionActivated = (session) => {
|
||||||
let message;
|
let message;
|
||||||
|
|||||||
6
dist/app.js.map
vendored
6
dist/app.js.map
vendored
File diff suppressed because one or more lines are too long
193
src/app.jsx
193
src/app.jsx
@@ -746,17 +746,17 @@
|
|||||||
}),
|
}),
|
||||||
'Scan QR Code'
|
'Scan QR Code'
|
||||||
]),
|
]),
|
||||||
// React.createElement('button', {
|
React.createElement('button', {
|
||||||
// key: 'bluetooth-btn',
|
key: 'bluetooth-btn',
|
||||||
// onClick: () => { try { document.dispatchEvent(new CustomEvent('open-bluetooth-transfer', { detail: { role: 'responder' } })); } catch {} },
|
onClick: () => { try { document.dispatchEvent(new CustomEvent('open-bluetooth-transfer', { detail: { role: 'responder' } })); } catch {} },
|
||||||
// className: "px-4 py-2 bg-blue-500/10 hover:bg-blue-500/20 text-blue-400 border border-blue-500/20 rounded text-sm font-medium transition-all duration-200"
|
className: "px-4 py-2 bg-blue-500/10 hover:bg-blue-500/20 text-blue-400 border border-blue-500/20 rounded text-sm font-medium transition-all duration-200"
|
||||||
// }, [
|
}, [
|
||||||
// React.createElement('i', {
|
React.createElement('i', {
|
||||||
// key: 'icon',
|
key: 'icon',
|
||||||
// className: 'fas fa-bluetooth mr-2'
|
className: 'fas fa-bluetooth mr-2'
|
||||||
// }),
|
}),
|
||||||
// 'Bluetooth'
|
'Bluetooth'
|
||||||
// ])
|
])
|
||||||
]),
|
]),
|
||||||
React.createElement('textarea', {
|
React.createElement('textarea', {
|
||||||
key: 'input',
|
key: 'input',
|
||||||
@@ -870,17 +870,17 @@
|
|||||||
}),
|
}),
|
||||||
'Scan QR Code'
|
'Scan QR Code'
|
||||||
]),
|
]),
|
||||||
// React.createElement('button', {
|
React.createElement('button', {
|
||||||
// key: 'bluetooth-btn',
|
key: 'bluetooth-btn',
|
||||||
// onClick: () => { try { document.dispatchEvent(new CustomEvent('open-bluetooth-transfer', { detail: { role: 'initiator' } })); } catch {} },
|
onClick: () => { try { document.dispatchEvent(new CustomEvent('open-bluetooth-transfer', { detail: { role: 'initiator' } })); } catch {} },
|
||||||
// className: "px-4 py-2 bg-blue-500/10 hover:bg-blue-500/20 text-blue-400 border border-blue-500/20 rounded text-sm font-medium transition-all duration-200"
|
className: "px-4 py-2 bg-blue-500/10 hover:bg-blue-500/20 text-blue-400 border border-blue-500/20 rounded text-sm font-medium transition-all duration-200"
|
||||||
// }, [
|
}, [
|
||||||
// React.createElement('i', {
|
React.createElement('i', {
|
||||||
// key: 'icon',
|
key: 'icon',
|
||||||
// className: 'fas fa-bluetooth mr-2'
|
className: 'fas fa-bluetooth mr-2'
|
||||||
// }),
|
}),
|
||||||
// 'Bluetooth'
|
'Bluetooth'
|
||||||
// ]),
|
]),
|
||||||
React.createElement('button', {
|
React.createElement('button', {
|
||||||
key: 'process-btn',
|
key: 'process-btn',
|
||||||
onClick: onCreateAnswer,
|
onClick: onCreateAnswer,
|
||||||
@@ -1451,6 +1451,7 @@
|
|||||||
const [bluetoothManager, setBluetoothManager] = React.useState(null);
|
const [bluetoothManager, setBluetoothManager] = React.useState(null);
|
||||||
const [isVerified, setIsVerified] = React.useState(false);
|
const [isVerified, setIsVerified] = React.useState(false);
|
||||||
const [securityLevel, setSecurityLevel] = React.useState(null);
|
const [securityLevel, setSecurityLevel] = React.useState(null);
|
||||||
|
const [sessionTimeLeft, setSessionTimeLeft] = React.useState(0);
|
||||||
|
|
||||||
// Mutual verification states
|
// Mutual verification states
|
||||||
const [localVerificationConfirmed, setLocalVerificationConfirmed] = React.useState(false);
|
const [localVerificationConfirmed, setLocalVerificationConfirmed] = React.useState(false);
|
||||||
@@ -1497,7 +1498,7 @@
|
|||||||
const maxPreserveTime = 300000;
|
const maxPreserveTime = 300000;
|
||||||
|
|
||||||
|
|
||||||
const hasAnswerData = (answerData && answerData.trim().length > 0) ||
|
const hasAnswerData = (answerData && typeof answerData === 'string' && answerData.trim().length > 0) ||
|
||||||
(answerInput && answerInput.trim().length > 0);
|
(answerInput && answerInput.trim().length > 0);
|
||||||
|
|
||||||
const hasAnswerQR = qrCodeUrl && qrCodeUrl.trim().length > 0;
|
const hasAnswerQR = qrCodeUrl && qrCodeUrl.trim().length > 0;
|
||||||
@@ -1751,8 +1752,8 @@
|
|||||||
setBothVerificationsConfirmed(false);
|
setBothVerificationsConfirmed(false);
|
||||||
|
|
||||||
// Clear connection data
|
// Clear connection data
|
||||||
setOfferData(null);
|
setOfferData('');
|
||||||
setAnswerData(null);
|
setAnswerData('');
|
||||||
setOfferInput('');
|
setOfferInput('');
|
||||||
setAnswerInput('');
|
setAnswerInput('');
|
||||||
setShowOfferStep(false);
|
setShowOfferStep(false);
|
||||||
@@ -1767,8 +1768,8 @@
|
|||||||
setConnectionStatus('disconnected');
|
setConnectionStatus('disconnected');
|
||||||
setShowVerification(false);
|
setShowVerification(false);
|
||||||
|
|
||||||
setOfferData(null);
|
setOfferData('');
|
||||||
setAnswerData(null);
|
setAnswerData('');
|
||||||
setOfferInput('');
|
setOfferInput('');
|
||||||
setAnswerInput('');
|
setAnswerInput('');
|
||||||
setShowOfferStep(false);
|
setShowOfferStep(false);
|
||||||
@@ -1796,8 +1797,8 @@
|
|||||||
setBothVerificationsConfirmed(false);
|
setBothVerificationsConfirmed(false);
|
||||||
|
|
||||||
// Clear connection data
|
// Clear connection data
|
||||||
setOfferData(null);
|
setOfferData('');
|
||||||
setAnswerData(null);
|
setAnswerData('');
|
||||||
setOfferInput('');
|
setOfferInput('');
|
||||||
setAnswerInput('');
|
setAnswerInput('');
|
||||||
setShowOfferStep(false);
|
setShowOfferStep(false);
|
||||||
@@ -3117,11 +3118,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mark answer as created for state management
|
// Mark answer as created for state management
|
||||||
if (e.target.value.trim().length > 0) {
|
if (answerInput.trim().length > 0) {
|
||||||
if (typeof markAnswerCreated === 'function') {
|
if (typeof markAnswerCreated === 'function') {
|
||||||
markAnswerCreated();
|
markAnswerCreated();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const existingResponseMessages = messages.filter(m =>
|
const existingResponseMessages = messages.filter(m =>
|
||||||
@@ -3338,8 +3339,8 @@
|
|||||||
|
|
||||||
// Reset UI to initial state
|
// Reset UI to initial state
|
||||||
setConnectionStatus('disconnected');
|
setConnectionStatus('disconnected');
|
||||||
setOfferData(null);
|
setOfferData('');
|
||||||
setAnswerData(null);
|
setAnswerData('');
|
||||||
setOfferInput('');
|
setOfferInput('');
|
||||||
setAnswerInput('');
|
setAnswerInput('');
|
||||||
setShowOfferStep(false);
|
setShowOfferStep(false);
|
||||||
@@ -3438,70 +3439,78 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDisconnect = () => {
|
const handleDisconnect = () => {
|
||||||
|
try {
|
||||||
setSessionTimeLeft(0);
|
setSessionTimeLeft(0);
|
||||||
|
|
||||||
// Mark as user-initiated disconnect
|
// Mark as user-initiated disconnect
|
||||||
updateConnectionState({
|
updateConnectionState({
|
||||||
status: 'disconnected',
|
status: 'disconnected',
|
||||||
isUserInitiatedDisconnect: true
|
isUserInitiatedDisconnect: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cleanup session state
|
// Cleanup WebRTC connection
|
||||||
if (webrtcManagerRef.current) {
|
if (webrtcManagerRef.current) {
|
||||||
webrtcManagerRef.current.disconnect();
|
webrtcManagerRef.current.disconnect();
|
||||||
}
|
|
||||||
|
|
||||||
setKeyFingerprint('');
|
|
||||||
setVerificationCode('');
|
|
||||||
setSecurityLevel(null);
|
|
||||||
setIsVerified(false);
|
|
||||||
setShowVerification(false);
|
|
||||||
setConnectionStatus('disconnected');
|
|
||||||
|
|
||||||
// Clear verification states
|
|
||||||
setLocalVerificationConfirmed(false);
|
|
||||||
setRemoteVerificationConfirmed(false);
|
|
||||||
setBothVerificationsConfirmed(false);
|
|
||||||
|
|
||||||
// Reset UI to initial state (user-initiated disconnect always clears data)
|
|
||||||
setConnectionStatus('disconnected');
|
|
||||||
setShowVerification(false);
|
|
||||||
setOfferData(null);
|
|
||||||
setAnswerData(null);
|
|
||||||
setOfferInput('');
|
|
||||||
setAnswerInput('');
|
|
||||||
setShowOfferStep(false);
|
|
||||||
setShowAnswerStep(false);
|
|
||||||
setKeyFingerprint('');
|
|
||||||
setVerificationCode('');
|
|
||||||
setSecurityLevel(null);
|
|
||||||
setIsVerified(false);
|
|
||||||
|
|
||||||
setMessages([]);
|
|
||||||
|
|
||||||
if (typeof console.clear === 'function') {
|
|
||||||
console.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
document.dispatchEvent(new CustomEvent('peer-disconnect'));
|
|
||||||
document.dispatchEvent(new CustomEvent('disconnected'));
|
|
||||||
|
|
||||||
document.dispatchEvent(new CustomEvent('session-cleanup', {
|
|
||||||
detail: {
|
|
||||||
timestamp: Date.now(),
|
|
||||||
reason: 'manual_disconnect'
|
|
||||||
}
|
}
|
||||||
}));
|
|
||||||
|
|
||||||
setTimeout(() => {
|
// Clear all connection-related states
|
||||||
|
setKeyFingerprint('');
|
||||||
|
setVerificationCode('');
|
||||||
|
setSecurityLevel(null);
|
||||||
|
setIsVerified(false);
|
||||||
|
setShowVerification(false);
|
||||||
|
setConnectionStatus('disconnected');
|
||||||
|
|
||||||
|
// Clear verification states
|
||||||
|
setLocalVerificationConfirmed(false);
|
||||||
|
setRemoteVerificationConfirmed(false);
|
||||||
|
setBothVerificationsConfirmed(false);
|
||||||
|
|
||||||
|
// Reset UI to initial state
|
||||||
|
setOfferData('');
|
||||||
|
setAnswerData('');
|
||||||
|
setOfferInput('');
|
||||||
|
setAnswerInput('');
|
||||||
|
setShowOfferStep(false);
|
||||||
|
setShowAnswerStep(false);
|
||||||
|
setShowQRCode(false);
|
||||||
|
setQrCodeUrl('');
|
||||||
|
setShowQRScanner(false);
|
||||||
|
setShowQRScannerModal(false);
|
||||||
|
setShowBluetoothTransfer(false);
|
||||||
|
setBluetoothAutoRole(null);
|
||||||
|
|
||||||
|
// Clear messages
|
||||||
|
setMessages([]);
|
||||||
|
|
||||||
|
// Clear console
|
||||||
|
if (typeof console.clear === 'function') {
|
||||||
|
console.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dispatch disconnect events
|
||||||
|
document.dispatchEvent(new CustomEvent('peer-disconnect'));
|
||||||
|
document.dispatchEvent(new CustomEvent('disconnected'));
|
||||||
|
|
||||||
|
// Dispatch session cleanup event
|
||||||
|
document.dispatchEvent(new CustomEvent('session-cleanup', {
|
||||||
|
detail: {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
reason: 'manual_disconnect'
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Clear data and reset session timer
|
||||||
|
handleClearData();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
setSessionTimeLeft(0);
|
setSessionTimeLeft(0);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
handleClearData();
|
console.log('Disconnect completed successfully');
|
||||||
|
} catch (error) {
|
||||||
setTimeout(() => {
|
console.error('Error during disconnect:', error);
|
||||||
// Session manager removed - all features enabled by default
|
}
|
||||||
}, 1000);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSessionActivated = (session) => {
|
const handleSessionActivated = (session) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user