mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-18 18:03:08 +08:00
[fix] support self-hosted server URLs with paths
This commit is contained in:
@@ -63,6 +63,7 @@
|
||||
#include "rd_log.h"
|
||||
#include "server_window_state.h"
|
||||
#include "signal_server_settings.h"
|
||||
#include "signal_server_address.h"
|
||||
#include "ui/announcement_text.h"
|
||||
#include "ui/ui_localization.h"
|
||||
#include "update_checker.h"
|
||||
@@ -1285,6 +1286,7 @@ void GuiApplication::ResetSettingsUi() {
|
||||
ui_->main->set_file_save_path(file_transfer_save_path_buf_);
|
||||
ui_->main->set_server_host(signal_server_ip_self_);
|
||||
ui_->main->set_server_port(signal_server_port_self_);
|
||||
ui_->main->set_self_host_settings_error("");
|
||||
}
|
||||
|
||||
void GuiApplication::BindMainCallbacks() {
|
||||
@@ -1419,29 +1421,14 @@ void GuiApplication::BindMainCallbacks() {
|
||||
ui_->main->set_file_save_path(folder);
|
||||
}
|
||||
});
|
||||
main->on_save_settings([this] { SaveSettingsFromUi(); });
|
||||
main->on_save_settings([this] { return SaveSettingsFromUi(); });
|
||||
main->on_cancel_settings([this] { ResetSettingsUi(); });
|
||||
main->on_save_self_hosted_settings([this] {
|
||||
const std::string host(ui_->main->get_server_host());
|
||||
const auto signal_port = ParsePort(ui_->main->get_server_port());
|
||||
if (!host.empty()) {
|
||||
config_center_->SetServerHost(host);
|
||||
std::memset(signal_server_ip_self_, 0, sizeof(signal_server_ip_self_));
|
||||
std::strncpy(signal_server_ip_self_, host.c_str(),
|
||||
sizeof(signal_server_ip_self_) - 1);
|
||||
std::memset(signal_server_ip_, 0, sizeof(signal_server_ip_));
|
||||
std::strncpy(signal_server_ip_, host.c_str(),
|
||||
sizeof(signal_server_ip_) - 1);
|
||||
}
|
||||
if (signal_port) {
|
||||
config_center_->SetServerPort(*signal_port);
|
||||
std::snprintf(signal_server_port_self_, sizeof(signal_server_port_self_),
|
||||
"%d", *signal_port);
|
||||
std::snprintf(signal_server_port_, sizeof(signal_server_port_), "%d",
|
||||
*signal_port);
|
||||
}
|
||||
// Stage the endpoint until the surrounding settings dialog is confirmed.
|
||||
return ValidateSelfHostedSettingsFromUi();
|
||||
});
|
||||
main->on_cancel_self_hosted_settings([this] {
|
||||
ui_->main->set_self_host_settings_error("");
|
||||
const std::string host = config_center_->GetSignalServerHost();
|
||||
ui_->main->set_server_host(UiText(host));
|
||||
const int signal_port = config_center_->GetSignalServerPort();
|
||||
@@ -3496,9 +3483,45 @@ void GuiApplication::SyncServerWindow() {
|
||||
PositionServerWindows();
|
||||
}
|
||||
|
||||
void GuiApplication::SaveSettingsFromUi() {
|
||||
bool GuiApplication::ValidateSelfHostedSettingsFromUi() {
|
||||
auto& main = ui_->main;
|
||||
const auto address = minirtc::ParseSignalServerAddress(
|
||||
std::string(main->get_server_host()));
|
||||
if (!address) {
|
||||
main->set_self_host_settings_error(UiText(
|
||||
localization::self_hosted_address_invalid[localization_language_index_]));
|
||||
return false;
|
||||
}
|
||||
const auto port = address->port ? address->port : ParsePort(main->get_server_port());
|
||||
if (!port) {
|
||||
main->set_self_host_settings_error(UiText(
|
||||
localization::self_hosted_port_invalid[localization_language_index_]));
|
||||
return false;
|
||||
}
|
||||
main->set_server_host(UiText(address->Address()));
|
||||
main->set_server_port(UiText(std::to_string(*port)));
|
||||
main->set_self_host_settings_error("");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GuiApplication::SaveSettingsFromUi() {
|
||||
const auto previous_server = GetSignalServerSettings(*config_center_);
|
||||
auto& main = ui_->main;
|
||||
const bool has_endpoint = main->get_self_hosted_enabled() ||
|
||||
!std::string(main->get_server_host()).empty() ||
|
||||
!std::string(main->get_server_port()).empty();
|
||||
if (has_endpoint && !ValidateSelfHostedSettingsFromUi()) {
|
||||
main->set_self_host_settings_open(true);
|
||||
return false;
|
||||
}
|
||||
if ((has_endpoint && config_center_->SetServerEndpoint(
|
||||
std::string(main->get_server_host()), *ParsePort(main->get_server_port())) != 0) ||
|
||||
config_center_->SetSelfHosted(main->get_self_hosted_enabled()) != 0) {
|
||||
main->set_self_host_settings_error(UiText(
|
||||
localization::self_hosted_save_failed[localization_language_index_]));
|
||||
main->set_self_host_settings_open(true);
|
||||
return false;
|
||||
}
|
||||
language_button_value_ =
|
||||
localization::detail::ClampLanguageIndex(main->get_language_index());
|
||||
video_encode_format_button_value_ = std::clamp(main->get_codec_index(), 0, 1);
|
||||
@@ -3564,17 +3587,9 @@ void GuiApplication::SaveSettingsFromUi() {
|
||||
sizeof(file_transfer_save_path_buf_) - 1);
|
||||
config_center_->SetFileTransferSavePath(path);
|
||||
|
||||
const std::string host(main->get_server_host());
|
||||
if (!host.empty()) {
|
||||
config_center_->SetServerHost(host);
|
||||
}
|
||||
if (const auto port = ParsePort(main->get_server_port())) {
|
||||
config_center_->SetServerPort(*port);
|
||||
}
|
||||
|
||||
config_center_->SetSelfHosted(enable_self_hosted_);
|
||||
ApplySettingsFromConfig(previous_server !=
|
||||
GetSignalServerSettings(*config_center_));
|
||||
return true;
|
||||
}
|
||||
|
||||
void GuiApplication::ApplySettingsFromConfig(bool reconnect) {
|
||||
|
||||
@@ -76,7 +76,8 @@ private:
|
||||
#endif
|
||||
void UpdateLocalization();
|
||||
void ResetSettingsUi();
|
||||
void SaveSettingsFromUi();
|
||||
bool ValidateSelfHostedSettingsFromUi();
|
||||
bool SaveSettingsFromUi();
|
||||
void ApplySettingsFromConfig(bool reconnect);
|
||||
#if _WIN32 && CROSSDESK_PORTABLE
|
||||
void CheckPortableWindowsService();
|
||||
|
||||
@@ -240,6 +240,9 @@ struct TranslationRow {
|
||||
"Server Address:", u8"Адрес сервера:") \
|
||||
X(self_hosted_server_port, u8"信令服务端口:", \
|
||||
"Signal Service Port:", u8"Порт сигнального сервиса:") \
|
||||
X(self_hosted_address_invalid, u8"请输入有效的主机名、IP 或 HTTPS/WSS 信令地址,可包含路径。", "Enter a valid host, IP, or HTTPS/WSS signaling URL. Paths are supported.", u8"Введите имя хоста, IP или HTTPS/WSS-адрес сигнального сервиса. Путь допустим.") \
|
||||
X(self_hosted_port_invalid, u8"请输入 1–65535 范围内的信令端口。", "Enter a signaling port between 1 and 65535.", u8"Введите порт сигнального сервиса от 1 до 65535.") \
|
||||
X(self_hosted_save_failed, u8"配置保存失败,请检查配置目录是否可写后重试。", "Could not save settings. Check that the configuration directory is writable and retry.", u8"Не удалось сохранить настройки. Проверьте доступ на запись в каталог конфигурации.") \
|
||||
X(ok, u8"确认", "OK", u8"ОК") \
|
||||
X(cancel, u8"取消", "Cancel", u8"Отмена") \
|
||||
X(new_password, u8"请输入六位密码:", \
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <set>
|
||||
#include <system_error>
|
||||
|
||||
#include "signal_server_address.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
@@ -51,9 +53,12 @@ void AnnouncementInbox::Configure(std::string host, int port,
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (directory_.empty() || host.empty() || port <= 0 || device_id.empty())
|
||||
return;
|
||||
for (auto& ch : host)
|
||||
auto address = minirtc::ParseSignalServerAddress(host);
|
||||
if (!address) return;
|
||||
for (auto& ch : address->host)
|
||||
if (ch >= 'A' && ch <= 'Z') ch += 'a' - 'A';
|
||||
if (host.back() == '.') host.pop_back();
|
||||
if (address->host.back() == '.') address->host.pop_back();
|
||||
host = address->Address();
|
||||
const auto scope = json::array({host, port, device_id}).dump();
|
||||
if (scope_ == scope) return;
|
||||
scope_ = scope;
|
||||
|
||||
@@ -379,6 +379,7 @@ export component MainWindow inherits Window {
|
||||
in-out property <string> file-save-path: "";
|
||||
in-out property <string> server-host: "";
|
||||
in-out property <string> server-port: "";
|
||||
in-out property <string> self-host-settings-error: "";
|
||||
in property <bool> settings-session-active: false;
|
||||
// Keep the setting visible on every platform. Unsupported builds expose it
|
||||
// as disabled so the fixed settings layout never turns into a blank row.
|
||||
@@ -393,9 +394,9 @@ export component MainWindow inherits Window {
|
||||
callback recent-connect(string);
|
||||
callback recent-edit-alias(string, string);
|
||||
callback recent-delete(string);
|
||||
callback save-settings;
|
||||
callback save-settings() -> bool;
|
||||
callback cancel-settings;
|
||||
callback save-self-hosted-settings;
|
||||
callback save-self-hosted-settings() -> bool;
|
||||
callback cancel-self-hosted-settings;
|
||||
callback browse-save-path;
|
||||
callback open-download;
|
||||
@@ -418,6 +419,9 @@ export component MainWindow inherits Window {
|
||||
in-out property <bool> settings-open: false;
|
||||
private property <length> settings-scroll-y: 0px;
|
||||
in-out property <bool> self-host-settings-open: false;
|
||||
changed self-host-settings-open => {
|
||||
if !root.self-host-settings-open { root.self-host-settings-error = ""; }
|
||||
}
|
||||
in-out property <bool> about-open: false;
|
||||
in-out property <bool> update-open: false;
|
||||
in-out property <bool> reset-password-open: false;
|
||||
@@ -1809,7 +1813,7 @@ export component MainWindow inherits Window {
|
||||
}
|
||||
|
||||
Rectangle { x: 7px; y: 286px; width: parent.width - 14px; height: 1px; background: ImGuiLineStyle.separator; }
|
||||
CompactButton { x: root.compact-language ? 63px : 89px; y: 297px; primary: true; text: UiStrings.ok; clicked => { root.save-settings(); root.settings-open = false; root.self-host-settings-open = false; } }
|
||||
CompactButton { x: root.compact-language ? 63px : 89px; y: 297px; primary: true; text: UiStrings.ok; clicked => { if root.save-settings() { root.settings-open = false; root.self-host-settings-open = false; } } }
|
||||
CompactButton { x: root.compact-language ? 104px : 130px; y: 297px; width: root.compact-language ? 34px : 56px; text: UiStrings.cancel; clicked => { root.cancel-settings(); root.settings-open = false; root.self-host-settings-open = false; } }
|
||||
}
|
||||
}
|
||||
@@ -1822,7 +1826,7 @@ export component MainWindow inherits Window {
|
||||
x: root.compact-language ? 190px : 140px;
|
||||
y: 105px;
|
||||
width: root.compact-language ? 260px : 360px;
|
||||
height: 138px;
|
||||
height: root.self-host-settings-error == "" ? 138px : 202px;
|
||||
border-radius: 7px;
|
||||
|
||||
Rectangle {
|
||||
@@ -1846,7 +1850,7 @@ export component MainWindow inherits Window {
|
||||
border-width: 1px;
|
||||
border-color: ImGuiLineStyle.border;
|
||||
border-radius: 4px;
|
||||
LineEdit { x: 1px; y: 1.5px; width: parent.width - 2px; height: parent.height - 2px; text <=> root.server-host; font-size: ImGuiFontStyle.body; }
|
||||
LineEdit { x: 1px; y: 1.5px; width: parent.width - 2px; height: parent.height - 2px; text <=> root.server-host; input-type: InputType.text; font-size: ImGuiFontStyle.body; }
|
||||
LineEditFocusUnderlineMask { x: 5px; y: parent.height - 3px; width: parent.width - 10px; }
|
||||
}
|
||||
Text { x: 8px; y: 61px; width: root.compact-language ? 88px : 165px; height: 24px; text: UiStrings.server-port; font-size: ImGuiFontStyle.body; overflow: elide; vertical-alignment: center; }
|
||||
@@ -1862,8 +1866,13 @@ export component MainWindow inherits Window {
|
||||
LineEdit { x: 1px; y: 1.5px; width: parent.width - 2px; height: parent.height - 2px; text <=> root.server-port; input-type: InputType.number; font-size: ImGuiFontStyle.body; }
|
||||
LineEditFocusUnderlineMask { x: 5px; y: parent.height - 3px; width: parent.width - 10px; }
|
||||
}
|
||||
CompactButton { x: root.compact-language ? 93px : 135px; y: 100px; primary: true; text: UiStrings.ok; clicked => { root.save-self-hosted-settings(); root.self-host-settings-open = false; } }
|
||||
CompactButton { x: root.compact-language ? 134px : 176px; y: 100px; width: root.compact-language ? 34px : 56px; text: UiStrings.cancel; clicked => { root.cancel-self-hosted-settings(); root.self-host-settings-open = false; } }
|
||||
if root.self-host-settings-error != "": Text {
|
||||
x: 8px; y: 89px; width: parent.width - 16px; height: 64px;
|
||||
text: root.self-host-settings-error; color: #b3261e;
|
||||
font-size: ImGuiFontStyle.body; wrap: word-wrap;
|
||||
}
|
||||
CompactButton { x: root.compact-language ? 93px : 135px; y: parent.height - 38px; primary: true; text: UiStrings.ok; clicked => { if root.save-self-hosted-settings() { root.self-host-settings-open = false; } } }
|
||||
CompactButton { x: root.compact-language ? 134px : 176px; y: parent.height - 38px; width: root.compact-language ? 34px : 56px; text: UiStrings.cancel; clicked => { root.cancel-self-hosted-settings(); root.self-host-settings-open = false; } }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user