manual send (to ip)
This commit is contained in:
@@ -74,6 +74,10 @@ void AppController::initialize()
|
||||
this, &AppController::onUploadCompleted);
|
||||
connect(m_httpClient, &LocalSend::HttpClient::uploadError,
|
||||
this, &AppController::onUploadError);
|
||||
connect(m_httpClient, &LocalSend::HttpClient::registerCompleted,
|
||||
this, &AppController::onManualRegisterCompleted);
|
||||
connect(m_httpClient, &LocalSend::HttpClient::registerError,
|
||||
this, &AppController::onManualRegisterError);
|
||||
|
||||
startDiscovery();
|
||||
}
|
||||
@@ -556,6 +560,46 @@ void AppController::sendTo(const QString& deviceFingerprint)
|
||||
sendFiles(deviceFingerprint, m_pendingSendPaths);
|
||||
}
|
||||
|
||||
void AppController::sendToAddress(const QString& address)
|
||||
{
|
||||
if (m_pendingSendPaths.isEmpty()) {
|
||||
emit sendError(QStringLiteral("No files selected"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (sending()) {
|
||||
emit sendError(QStringLiteral("Already sending files"));
|
||||
return;
|
||||
}
|
||||
|
||||
QString ip = address;
|
||||
quint16 port = m_settings->port();
|
||||
|
||||
if (address.contains(':')) {
|
||||
int colonPos = address.lastIndexOf(':');
|
||||
ip = address.left(colonPos);
|
||||
bool ok = false;
|
||||
int parsedPort = address.mid(colonPos + 1).toInt(&ok);
|
||||
if (ok && parsedPort > 0 && parsedPort <= 65535) {
|
||||
port = static_cast<quint16>(parsedPort);
|
||||
}
|
||||
}
|
||||
|
||||
QHostAddress hostAddr(ip);
|
||||
if (hostAddr.isNull()) {
|
||||
emit sendError(QStringLiteral("Invalid IP address: %1").arg(ip));
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[AppController] sendToAddress:" << ip << "port:" << port;
|
||||
|
||||
m_manualSendDevice = LocalSend::Device(ip, port);
|
||||
m_manualSendDevice.discoveryMethod = LocalSend::DiscoveryMethod::HttpTarget;
|
||||
m_manualSendPending = true;
|
||||
|
||||
m_httpClient->registerDevice(m_manualSendDevice, buildRegisterDto());
|
||||
}
|
||||
|
||||
void AppController::sendFiles(const QString& deviceFingerprint, const QStringList& filePaths)
|
||||
{
|
||||
if (!m_devices.contains(deviceFingerprint)) {
|
||||
@@ -898,3 +942,42 @@ void AppController::resetReceiveState()
|
||||
emit receivingChanged();
|
||||
emit receiveProgressChanged();
|
||||
}
|
||||
|
||||
void AppController::onManualRegisterCompleted(const LocalSend::InfoDto& peerInfo)
|
||||
{
|
||||
if (!m_manualSendPending) return;
|
||||
m_manualSendPending = false;
|
||||
|
||||
m_manualSendDevice.alias = peerInfo.alias;
|
||||
m_manualSendDevice.deviceModel = peerInfo.deviceModel;
|
||||
m_manualSendDevice.deviceType = peerInfo.deviceType;
|
||||
m_manualSendDevice.version = peerInfo.version;
|
||||
m_manualSendDevice.fingerprint = peerInfo.fingerprint;
|
||||
|
||||
qDebug() << "[AppController] Manual register completed:" << m_manualSendDevice.alias
|
||||
<< "fingerprint:" << m_manualSendDevice.fingerprint;
|
||||
|
||||
if (!m_devices.contains(m_manualSendDevice.fingerprint)) {
|
||||
m_devices.insert(m_manualSendDevice.fingerprint, m_manualSendDevice);
|
||||
emit devicesChanged();
|
||||
}
|
||||
|
||||
sendFiles(m_manualSendDevice.fingerprint, m_pendingSendPaths);
|
||||
}
|
||||
|
||||
void AppController::onManualRegisterError(const QString& error)
|
||||
{
|
||||
if (!m_manualSendPending) return;
|
||||
|
||||
if (m_manualSendDevice.protocol == LocalSend::ProtocolType::Http) {
|
||||
qWarning() << "[AppController] Manual register failed with HTTP, retrying with HTTPS:" << error;
|
||||
m_manualSendDevice.protocol = LocalSend::ProtocolType::Https;
|
||||
m_httpClient->registerDevice(m_manualSendDevice, buildRegisterDto());
|
||||
return;
|
||||
}
|
||||
|
||||
m_manualSendPending = false;
|
||||
|
||||
qWarning() << "[AppController] Manual register error:" << error;
|
||||
emit sendError(QStringLiteral("Cannot reach device at %1: %2").arg(m_manualSendDevice.ip).arg(error));
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ public:
|
||||
|
||||
Q_INVOKABLE void sendFiles(const QString& deviceFingerprint, const QStringList& filePaths);
|
||||
Q_INVOKABLE void sendTo(const QString& deviceFingerprint);
|
||||
Q_INVOKABLE void sendToAddress(const QString& address);
|
||||
Q_INVOKABLE void cancelSend();
|
||||
Q_INVOKABLE void addFiles(const QStringList& filePaths);
|
||||
Q_INVOKABLE void removePendingFile(int index);
|
||||
@@ -137,6 +138,8 @@ private slots:
|
||||
void onUploadProgress(qint64 sent, qint64 total);
|
||||
void onUploadCompleted();
|
||||
void onUploadError(const QString& error);
|
||||
void onManualRegisterCompleted(const LocalSend::InfoDto& peerInfo);
|
||||
void onManualRegisterError(const QString& error);
|
||||
|
||||
void onCancelRequest(const QString& sessionId);
|
||||
|
||||
@@ -175,4 +178,7 @@ private:
|
||||
LocalSend::RegisterDto buildRegisterDto() const;
|
||||
void resetSendState();
|
||||
void resetReceiveState();
|
||||
|
||||
bool m_manualSendPending = false;
|
||||
LocalSend::Device m_manualSendDevice;
|
||||
};
|
||||
|
||||
@@ -410,6 +410,51 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: manualSendDialog
|
||||
anchors.centerIn: parent
|
||||
modal: true
|
||||
title: qsTr("Manual Sending")
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 12
|
||||
|
||||
Label {
|
||||
text: qsTr("Enter the IP address of the target device.")
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: manualAddressInput
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("IP address (e.g., 192.168.1.100:53317)")
|
||||
onAccepted: manualSendDialog.accepted()
|
||||
}
|
||||
}
|
||||
|
||||
footer: DialogButtonBox {
|
||||
Button {
|
||||
text: qsTr("Cancel")
|
||||
DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
|
||||
}
|
||||
Button {
|
||||
text: qsTr("Send")
|
||||
DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
|
||||
enabled: manualAddressInput.text.trim().length > 0
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
appController.sendToAddress(manualAddressInput.text.trim())
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
manualAddressInput.text = ""
|
||||
manualAddressInput.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: setPinDialog
|
||||
anchors.centerIn: parent
|
||||
@@ -646,6 +691,11 @@ ApplicationWindow {
|
||||
text: qsTr("Refresh")
|
||||
onClicked: appController.refreshDevices()
|
||||
}
|
||||
Button {
|
||||
text: qsTr("Manual Send")
|
||||
enabled: appController.hasPendingFiles && !appController.sending
|
||||
onClicked: manualSendDialog.open()
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
Label {
|
||||
text: qsTr("Alias: %1").arg(appController.alias)
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
signals:
|
||||
void infoReceived(const InfoDto& info);
|
||||
void infoError(const QString& error);
|
||||
void registerCompleted();
|
||||
void registerCompleted(const InfoDto& peerInfo);
|
||||
void registerError(const QString& error);
|
||||
void prepareUploadResponse(const PrepareUploadResponseDto& response);
|
||||
void prepareUploadError(const QString& error);
|
||||
|
||||
@@ -95,7 +95,17 @@ void HttpClient::registerDevice(const Device& device, const RegisterDto& dto)
|
||||
return;
|
||||
}
|
||||
|
||||
emit registerCompleted();
|
||||
QByteArray responseData = reply->readAll();
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(responseData, &error);
|
||||
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
emit registerError(QStringLiteral("Invalid JSON response"));
|
||||
return;
|
||||
}
|
||||
|
||||
InfoDto info = InfoDto::fromJson(doc.object());
|
||||
emit registerCompleted(info);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user