manual send (to ip)
This commit is contained in:
@@ -74,6 +74,10 @@ void AppController::initialize()
|
|||||||
this, &AppController::onUploadCompleted);
|
this, &AppController::onUploadCompleted);
|
||||||
connect(m_httpClient, &LocalSend::HttpClient::uploadError,
|
connect(m_httpClient, &LocalSend::HttpClient::uploadError,
|
||||||
this, &AppController::onUploadError);
|
this, &AppController::onUploadError);
|
||||||
|
connect(m_httpClient, &LocalSend::HttpClient::registerCompleted,
|
||||||
|
this, &AppController::onManualRegisterCompleted);
|
||||||
|
connect(m_httpClient, &LocalSend::HttpClient::registerError,
|
||||||
|
this, &AppController::onManualRegisterError);
|
||||||
|
|
||||||
startDiscovery();
|
startDiscovery();
|
||||||
}
|
}
|
||||||
@@ -556,6 +560,46 @@ void AppController::sendTo(const QString& deviceFingerprint)
|
|||||||
sendFiles(deviceFingerprint, m_pendingSendPaths);
|
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)
|
void AppController::sendFiles(const QString& deviceFingerprint, const QStringList& filePaths)
|
||||||
{
|
{
|
||||||
if (!m_devices.contains(deviceFingerprint)) {
|
if (!m_devices.contains(deviceFingerprint)) {
|
||||||
@@ -898,3 +942,42 @@ void AppController::resetReceiveState()
|
|||||||
emit receivingChanged();
|
emit receivingChanged();
|
||||||
emit receiveProgressChanged();
|
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 sendFiles(const QString& deviceFingerprint, const QStringList& filePaths);
|
||||||
Q_INVOKABLE void sendTo(const QString& deviceFingerprint);
|
Q_INVOKABLE void sendTo(const QString& deviceFingerprint);
|
||||||
|
Q_INVOKABLE void sendToAddress(const QString& address);
|
||||||
Q_INVOKABLE void cancelSend();
|
Q_INVOKABLE void cancelSend();
|
||||||
Q_INVOKABLE void addFiles(const QStringList& filePaths);
|
Q_INVOKABLE void addFiles(const QStringList& filePaths);
|
||||||
Q_INVOKABLE void removePendingFile(int index);
|
Q_INVOKABLE void removePendingFile(int index);
|
||||||
@@ -137,6 +138,8 @@ private slots:
|
|||||||
void onUploadProgress(qint64 sent, qint64 total);
|
void onUploadProgress(qint64 sent, qint64 total);
|
||||||
void onUploadCompleted();
|
void onUploadCompleted();
|
||||||
void onUploadError(const QString& error);
|
void onUploadError(const QString& error);
|
||||||
|
void onManualRegisterCompleted(const LocalSend::InfoDto& peerInfo);
|
||||||
|
void onManualRegisterError(const QString& error);
|
||||||
|
|
||||||
void onCancelRequest(const QString& sessionId);
|
void onCancelRequest(const QString& sessionId);
|
||||||
|
|
||||||
@@ -175,4 +178,7 @@ private:
|
|||||||
LocalSend::RegisterDto buildRegisterDto() const;
|
LocalSend::RegisterDto buildRegisterDto() const;
|
||||||
void resetSendState();
|
void resetSendState();
|
||||||
void resetReceiveState();
|
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 {
|
Dialog {
|
||||||
id: setPinDialog
|
id: setPinDialog
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -646,6 +691,11 @@ ApplicationWindow {
|
|||||||
text: qsTr("Refresh")
|
text: qsTr("Refresh")
|
||||||
onClicked: appController.refreshDevices()
|
onClicked: appController.refreshDevices()
|
||||||
}
|
}
|
||||||
|
Button {
|
||||||
|
text: qsTr("Manual Send")
|
||||||
|
enabled: appController.hasPendingFiles && !appController.sending
|
||||||
|
onClicked: manualSendDialog.open()
|
||||||
|
}
|
||||||
Item { Layout.fillWidth: true }
|
Item { Layout.fillWidth: true }
|
||||||
Label {
|
Label {
|
||||||
text: qsTr("Alias: %1").arg(appController.alias)
|
text: qsTr("Alias: %1").arg(appController.alias)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void infoReceived(const InfoDto& info);
|
void infoReceived(const InfoDto& info);
|
||||||
void infoError(const QString& error);
|
void infoError(const QString& error);
|
||||||
void registerCompleted();
|
void registerCompleted(const InfoDto& peerInfo);
|
||||||
void registerError(const QString& error);
|
void registerError(const QString& error);
|
||||||
void prepareUploadResponse(const PrepareUploadResponseDto& response);
|
void prepareUploadResponse(const PrepareUploadResponseDto& response);
|
||||||
void prepareUploadError(const QString& error);
|
void prepareUploadError(const QString& error);
|
||||||
|
|||||||
@@ -95,7 +95,17 @@ void HttpClient::registerDevice(const Device& device, const RegisterDto& dto)
|
|||||||
return;
|
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