mirror of
https://github.com/UNITRONIX/BetterDesk.git
synced 2026-09-11 13:49:03 +00:00
feat(web-remote): improve file transfer connection handling
Enhance the file transfer connection logic by adding an `isConnected` method to check the readiness of the file connection. Update the `ensureFileConnection` method to handle connection errors more gracefully and ensure proper disconnection. Modify the file transfer modal to improve user feedback during connection states and streamline the rendering of remote entries. Additionally, refine the file transfer class to better manage connection requirements.
This commit is contained in:
@@ -46,7 +46,8 @@ class RDClient {
|
||||
proto: this.proto,
|
||||
sendMessage: (msg) => this._sendFileTransferMessage(msg),
|
||||
emit: (event, ...args) => this._emit(event, ...args),
|
||||
ensureConnected: () => this.ensureFileConnection()
|
||||
ensureConnected: () => this.ensureFileConnection(),
|
||||
isConnected: () => this.isFileConnectionReady()
|
||||
});
|
||||
|
||||
// State
|
||||
@@ -254,6 +255,10 @@ class RDClient {
|
||||
* Open dedicated FILE_TRANSFER relay (lazy). Reuses desktop session password.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
isFileConnectionReady() {
|
||||
return !!(this._fileConnection && this._fileConnection.state === 'ready');
|
||||
}
|
||||
|
||||
async ensureFileConnection() {
|
||||
if (typeof RDFileConnection !== 'function') {
|
||||
throw new Error('File transfer module not loaded');
|
||||
@@ -272,9 +277,19 @@ class RDClient {
|
||||
this._fileConnection.on('2fa_required', () => this._emit('2fa_required'));
|
||||
this._fileConnection.on('2fa_error', (err) => this._emit('2fa_error', err));
|
||||
this._fileConnection.on('login_error', (err) => this._emit('login_error', err));
|
||||
this._fileConnection.on('disconnected', () => {
|
||||
if (this._fileConnection && this._fileConnection.state !== 'ready') {
|
||||
this._fileConnection = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (this._fileConnection.state === 'ready') return;
|
||||
await this._fileConnection.connect(this._sessionPassword || '');
|
||||
try {
|
||||
await this._fileConnection.connect(this._sessionPassword || '');
|
||||
} catch (err) {
|
||||
this.disconnectFileConnection();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
_sendFileTransferMessage(msgObj) {
|
||||
@@ -1103,6 +1118,9 @@ class RDClient {
|
||||
|
||||
// Enable file transfer
|
||||
this.fileTransfer.enable();
|
||||
this.ensureFileConnection().catch(function (err) {
|
||||
console.warn('[RDClient] File transfer preconnect:', err.message || err);
|
||||
});
|
||||
|
||||
// Initialize video decoder callbacks
|
||||
this.video.onFrame = (frame) => this.renderer.pushFrame(frame);
|
||||
|
||||
@@ -99,6 +99,11 @@ class RDFileConnection {
|
||||
|
||||
async _doConnect(password) {
|
||||
try {
|
||||
if (this.conn) {
|
||||
try { this.conn.close(); } catch (_e) { /* ignore */ }
|
||||
}
|
||||
this.conn = new RDConnection();
|
||||
this.crypto = new RDCrypto();
|
||||
this._setState('connecting');
|
||||
this._emit('log', 'Opening file transfer session…');
|
||||
|
||||
@@ -110,6 +115,9 @@ class RDFileConnection {
|
||||
this._keyExchangePending = false;
|
||||
this._keyExchangeDone = false;
|
||||
this._peerEncryptionConfirmed = false;
|
||||
this._loginChallenge = '';
|
||||
this._loginSalt = '';
|
||||
this._pendingPassword = password;
|
||||
|
||||
const ct = this._connType();
|
||||
await this.conn.connectRendezvous();
|
||||
@@ -230,7 +238,8 @@ class RDFileConnection {
|
||||
if (this._loginReject) {
|
||||
this._loginReject(new Error('Disconnected'));
|
||||
}
|
||||
this.conn.close();
|
||||
this._connectPromise = null;
|
||||
try { this.conn.close(); } catch (_e) { /* ignore */ }
|
||||
this._setState('disconnected');
|
||||
}
|
||||
|
||||
|
||||
@@ -186,6 +186,11 @@
|
||||
t('remote.file_transfer', 'File Transfer') + ' — ' + (session.deviceName || session.deviceId);
|
||||
this._updateLocalHint();
|
||||
this._updateLocalToolbarState();
|
||||
this._renderLocalList();
|
||||
this._remoteEntries = [];
|
||||
this._selectedRemote = null;
|
||||
this._el.querySelector('.ft-remote-path').textContent = '';
|
||||
this._renderRemoteLoading(t('remote.file_connecting', 'Connecting file transfer session…'));
|
||||
this._el.style.display = 'flex';
|
||||
document.getElementById('btn-file-transfer')?.classList.add('active');
|
||||
if (this._wiredSessionId !== session.deviceId) {
|
||||
@@ -204,9 +209,6 @@
|
||||
if (this._session && this._session.client && this._session.client.fileTransfer) {
|
||||
this._session.client.fileTransfer._saveDownload = null;
|
||||
}
|
||||
if (this._session && this._session.client && this._session.client.disconnectFileConnection) {
|
||||
this._session.client.disconnectFileConnection();
|
||||
}
|
||||
};
|
||||
|
||||
FileTransferModal.prototype.isOpen = function () {
|
||||
@@ -216,9 +218,15 @@
|
||||
FileTransferModal.prototype._wireClient = function (session) {
|
||||
var self = this;
|
||||
var client = session.client;
|
||||
client.on('file_browsing', function () { self._renderRemoteLoading(); });
|
||||
client.on('file_browsing', function () {
|
||||
if (!self._remoteEntries.length) {
|
||||
self._renderRemoteLoading(t('remote.file_loading', 'Loading…'));
|
||||
}
|
||||
});
|
||||
client.on('file_connecting', function () {
|
||||
self._renderRemoteLoading(t('remote.file_connecting', 'Connecting file transfer session…'));
|
||||
if (!self._remoteEntries.length) {
|
||||
self._renderRemoteLoading(t('remote.file_connecting', 'Connecting file transfer session…'));
|
||||
}
|
||||
});
|
||||
client.on('file_connect_error', function (data) {
|
||||
self._renderRemoteError(data.error || t('remote.file_connect_failed', 'Could not open file transfer session'));
|
||||
|
||||
@@ -19,12 +19,14 @@ class RDFileTransfer {
|
||||
* @param {Function} opts.sendMessage - Function to send peer message: (msgObj) => void
|
||||
* @param {Function} opts.emit - Event emitter: (event, ...args) => void
|
||||
* @param {Function} [opts.ensureConnected] - Async hook before browse/upload
|
||||
* @param {Function} [opts.isConnected] - Returns true when file relay is ready
|
||||
*/
|
||||
constructor(opts) {
|
||||
this._proto = opts.proto;
|
||||
this._sendMessage = opts.sendMessage;
|
||||
this._emit = opts.emit;
|
||||
this._ensureConnected = opts.ensureConnected || null;
|
||||
this._isConnected = opts.isConnected || null;
|
||||
|
||||
/** @type {string} Current remote directory path */
|
||||
this._currentPath = '';
|
||||
@@ -95,10 +97,16 @@ class RDFileTransfer {
|
||||
});
|
||||
}
|
||||
|
||||
_needsFileConnection() {
|
||||
return this._ensureConnected && (!this._isConnected || !this._isConnected());
|
||||
}
|
||||
|
||||
_runWithConnection(run) {
|
||||
const self = this;
|
||||
if (this._ensureConnected) {
|
||||
this._emit('file_connecting');
|
||||
if (this._needsFileConnection()) {
|
||||
this._emit('file_connecting');
|
||||
}
|
||||
return this._ensureConnected().then(function () {
|
||||
run();
|
||||
}).catch(function (err) {
|
||||
@@ -188,7 +196,9 @@ class RDFileTransfer {
|
||||
}, 5000);
|
||||
};
|
||||
if (this._ensureConnected) {
|
||||
this._emit('file_connecting');
|
||||
if (this._needsFileConnection()) {
|
||||
this._emit('file_connecting');
|
||||
}
|
||||
this._ensureConnected().then(run).catch(function (err) {
|
||||
self._emit('file_connect_error', { error: err.message || String(err) });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user