fixed timeout & add message & fix disabled telemt|mtproxy

This commit is contained in:
dranik
2026-06-16 13:58:22 +03:00
parent 6202078e0c
commit 07aad87874
4 changed files with 76 additions and 11 deletions
@@ -390,20 +390,21 @@ void InstallUiController::refreshContainerStatus(const QString &serverId, int co
return; return;
} }
using StatusResult = std::pair<int, int>; // {status, errorCode}
InstallController *installController = m_installController; InstallController *installController = m_installController;
auto *watcher = new QFutureWatcher<int>(this); auto *watcher = new QFutureWatcher<StatusResult>(this);
QObject::connect(watcher, &QFutureWatcher<int>::finished, this, [this, watcher]() { QObject::connect(watcher, &QFutureWatcher<StatusResult>::finished, this, [this, watcher]() {
const int status = watcher->result(); const StatusResult result = watcher->result();
watcher->deleteLater(); watcher->deleteLater();
emit containerStatusRefreshed(status); emit containerStatusRefreshed(result.first, result.second);
}); });
QFuture<int> future = QtConcurrent::run([installController, serverId, container]() -> int { QFuture<StatusResult> future = QtConcurrent::run([installController, serverId, container]() -> StatusResult {
int status = 3; int status = 3;
const ErrorCode errorCode = installController->queryDockerContainerStatus(serverId, container, status); const ErrorCode errorCode = installController->queryDockerContainerStatus(serverId, container, status);
if (errorCode != ErrorCode::NoError) { if (errorCode != ErrorCode::NoError) {
return 3; return { 3, static_cast<int>(errorCode) };
} }
return status; return { status, static_cast<int>(ErrorCode::NoError) };
}); });
watcher->setFuture(future); watcher->setFuture(future);
} }
@@ -114,7 +114,7 @@ signals:
void removeAllContainersFinished(const QString &finishedMessage); void removeAllContainersFinished(const QString &finishedMessage);
void removeContainerFinished(const QString &finishedMessage); void removeContainerFinished(const QString &finishedMessage);
void setContainerEnabledFinished(bool enabled); void setContainerEnabledFinished(bool enabled);
void containerStatusRefreshed(int status); void containerStatusRefreshed(int status, int errorCode);
void containerDiagnosticsRefreshed(bool portReachable, bool upstreamReachable, int clientsConnected, void containerDiagnosticsRefreshed(bool portReachable, bool upstreamReachable, int clientsConnected,
const QString &lastConfigRefresh, const QString &statsEndpoint); const QString &lastConfigRefresh, const QString &statsEndpoint);
void containerSecretFetched(const QString &secret); void containerSecretFetched(const QString &secret);
@@ -21,6 +21,8 @@ PageType {
id: root id: root
property int containerStatus: 1 property int containerStatus: 1
// Last status-query error code (0 = none). 305 = SshTimeoutError → server unreachable.
property int statusErrorCode: 0
property bool isUpdating: false property bool isUpdating: false
property bool isCheckingStatus: false property bool isCheckingStatus: false
property bool isFetchingSecret: false property bool isFetchingSecret: false
@@ -261,6 +263,7 @@ PageType {
isCheckingStatus = false isCheckingStatus = false
isFetchingSecret = false isFetchingSecret = false
busyIndicatorShown = false busyIndicatorShown = false
statusErrorCode = 0
PageController.disableControls(false) PageController.disableControls(false)
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
diagLoading = false diagLoading = false
@@ -348,13 +351,18 @@ PageType {
enabled ? qsTr("MTProxy started") : qsTr("MTProxy stopped")) enabled ? qsTr("MTProxy started") : qsTr("MTProxy stopped"))
} }
function onContainerStatusRefreshed(status) { function onContainerStatusRefreshed(status, errorCode) {
if (!root.visible) { if (!root.visible) {
isCheckingStatus = false isCheckingStatus = false
isFetchingSecret = false isFetchingSecret = false
return return
} }
containerStatus = status containerStatus = status
root.statusErrorCode = errorCode
if (status === 3 && errorCode !== 0) {
PageController.showNotificationMessage(
qsTr("Settings locked: connection timed out (error code %1). Re-open the page to retry.").arg(errorCode))
}
root.savedTransportMode = MtProxyConfigModel.getTransportMode() root.savedTransportMode = MtProxyConfigModel.getTransportMode()
root.savedTlsDomain = MtProxyConfigModel.getTlsDomain() root.savedTlsDomain = MtProxyConfigModel.getTlsDomain()
@@ -842,6 +850,8 @@ PageType {
width: settingsListView.width width: settingsListView.width
spacing: 0 spacing: 0
readonly property bool fieldsEditable: isEnabled && containerStatus === 1 && !root.pageBusy
function mtProxyActiveSecretForBaseHex(baseHex) { function mtProxyActiveSecretForBaseHex(baseHex) {
return root.mtProxyClientSecretForTabIndex(baseHex, root.syncedSecretTabIndex, return root.mtProxyClientSecretForTabIndex(baseHex, root.syncedSecretTabIndex,
root.savedTlsDomain, MtProxyConfigModel.defaultTlsDomain()) root.savedTlsDomain, MtProxyConfigModel.defaultTlsDomain())
@@ -887,6 +897,21 @@ PageType {
} }
} }
CaptionTextType {
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 8
visible: !fieldsEditable && !root.pageBusy
text: (containerStatus === 1 || containerStatus === 2)
? qsTr("Enable MTProxy to edit settings")
: (statusErrorCode !== 0
? qsTr("Settings locked: connection timed out (error code %1). Re-open the page to retry.").arg(statusErrorCode)
: qsTr("Cannot reach the server — settings are unavailable"))
color: AmneziaStyle.color.mutedGray
wrapMode: Text.WordWrap
}
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
@@ -921,6 +946,7 @@ PageType {
image: "qrc:/images/controls/refresh-cw.svg" image: "qrc:/images/controls/refresh-cw.svg"
imageColor: AmneziaStyle.color.paleGray imageColor: AmneziaStyle.color.paleGray
visible: ServersUiController.isProcessedServerHasWriteAccess() visible: ServersUiController.isProcessedServerHasWriteAccess()
enabled: fieldsEditable
onClicked: { onClicked: {
var secretSnapshot = secret var secretSnapshot = secret
showQuestionDrawer( showQuestionDrawer(
@@ -949,6 +975,7 @@ PageType {
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: publicHostTextField id: publicHostTextField
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -1010,6 +1037,7 @@ PageType {
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: portTextField id: portTextField
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -1064,6 +1092,7 @@ PageType {
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: tagTextField id: tagTextField
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -1147,6 +1176,7 @@ PageType {
DropDownType { DropDownType {
id: transportModeDropDown id: transportModeDropDown
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -1182,6 +1212,7 @@ PageType {
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: tlsDomainTextField id: tlsDomainTextField
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -1264,6 +1295,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
spacing: 0 spacing: 0
visible: advancedHeader.expanded visible: advancedHeader.expanded
enabled: fieldsEditable
CaptionTextType { CaptionTextType {
Layout.fillWidth: true Layout.fillWidth: true
@@ -1871,7 +1903,7 @@ PageType {
Layout.rightMargin: 16 Layout.rightMargin: 16
Layout.leftMargin: 16 Layout.leftMargin: 16
visible: ServersUiController.isProcessedServerHasWriteAccess() visible: ServersUiController.isProcessedServerHasWriteAccess()
enabled: !root.mtProxyNetworkBlocked enabled: fieldsEditable && !root.mtProxyNetworkBlocked
text: qsTr("Save") text: qsTr("Save")
clickedFunc: function () { clickedFunc: function () {
if (root.mtProxyNetworkBlocked) { if (root.mtProxyNetworkBlocked) {
@@ -20,6 +20,7 @@ PageType {
id: root id: root
property int containerStatus: 1 property int containerStatus: 1
property int statusErrorCode: 0
property bool isUpdating: false property bool isUpdating: false
property bool isCheckingStatus: false property bool isCheckingStatus: false
property bool isFetchingSecret: false property bool isFetchingSecret: false
@@ -235,6 +236,7 @@ PageType {
isCheckingStatus = false isCheckingStatus = false
isFetchingSecret = false isFetchingSecret = false
busyIndicatorShown = false busyIndicatorShown = false
statusErrorCode = 0
PageController.disableControls(false) PageController.disableControls(false)
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
diagLoading = false diagLoading = false
@@ -324,13 +326,18 @@ PageType {
enabled ? qsTr("Telemt started") : qsTr("Telemt stopped")) enabled ? qsTr("Telemt started") : qsTr("Telemt stopped"))
} }
function onContainerStatusRefreshed(status) { function onContainerStatusRefreshed(status, errorCode) {
if (!root.visible) { if (!root.visible) {
isCheckingStatus = false isCheckingStatus = false
isFetchingSecret = false isFetchingSecret = false
return return
} }
containerStatus = status containerStatus = status
root.statusErrorCode = errorCode
if (status === 3 && errorCode !== 0) {
PageController.showNotificationMessage(
qsTr("Settings locked: connection timed out (error code %1). Re-open the page to retry.").arg(errorCode))
}
root.savedTransportMode = TelemtConfigModel.getTransportMode() root.savedTransportMode = TelemtConfigModel.getTransportMode()
root.savedTlsDomain = TelemtConfigModel.getTlsDomain() root.savedTlsDomain = TelemtConfigModel.getTlsDomain()
@@ -817,6 +824,8 @@ PageType {
width: settingsListView.width width: settingsListView.width
spacing: 0 spacing: 0
readonly property bool fieldsEditable: isEnabled && containerStatus === 1 && !root.pageBusy
function telemtActiveSecretForBaseHex(baseHex) { function telemtActiveSecretForBaseHex(baseHex) {
return root.telemtClientSecretForTabIndex(baseHex, root.syncedSecretTabIndex, return root.telemtClientSecretForTabIndex(baseHex, root.syncedSecretTabIndex,
root.savedTlsDomain, TelemtConfigModel.defaultTlsDomain()) root.savedTlsDomain, TelemtConfigModel.defaultTlsDomain())
@@ -850,6 +859,21 @@ PageType {
} }
} }
CaptionTextType {
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 8
visible: !fieldsEditable && !root.pageBusy
text: (containerStatus === 1 || containerStatus === 2)
? qsTr("Enable Telemt to edit settings")
: (statusErrorCode !== 0
? qsTr("Settings locked: connection timed out (error code %1). Re-open the page to retry.").arg(statusErrorCode)
: qsTr("Cannot reach the server — settings are unavailable"))
color: AmneziaStyle.color.mutedGray
wrapMode: Text.WordWrap
}
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
@@ -884,6 +908,7 @@ PageType {
image: "qrc:/images/controls/refresh-cw.svg" image: "qrc:/images/controls/refresh-cw.svg"
imageColor: AmneziaStyle.color.paleGray imageColor: AmneziaStyle.color.paleGray
visible: ServersUiController.isProcessedServerHasWriteAccess() visible: ServersUiController.isProcessedServerHasWriteAccess()
enabled: fieldsEditable
onClicked: { onClicked: {
var secretSnapshot = secret var secretSnapshot = secret
showQuestionDrawer( showQuestionDrawer(
@@ -912,6 +937,7 @@ PageType {
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: publicHostTextField id: publicHostTextField
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -973,6 +999,7 @@ PageType {
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: portTextField id: portTextField
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -1021,6 +1048,7 @@ PageType {
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: tagTextField id: tagTextField
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -1104,6 +1132,7 @@ PageType {
DropDownType { DropDownType {
id: transportModeDropDown id: transportModeDropDown
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -1139,6 +1168,7 @@ PageType {
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: tlsDomainTextField id: tlsDomainTextField
enabled: fieldsEditable
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 16 Layout.leftMargin: 16
Layout.rightMargin: 16 Layout.rightMargin: 16
@@ -1221,6 +1251,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
spacing: 0 spacing: 0
visible: advancedHeader.expanded visible: advancedHeader.expanded
enabled: fieldsEditable
CaptionTextType { CaptionTextType {
Layout.fillWidth: true Layout.fillWidth: true
@@ -1646,6 +1677,7 @@ PageType {
Layout.rightMargin: 16 Layout.rightMargin: 16
Layout.leftMargin: 16 Layout.leftMargin: 16
visible: ServersUiController.isProcessedServerHasWriteAccess() visible: ServersUiController.isProcessedServerHasWriteAccess()
enabled: fieldsEditable
text: qsTr("Save") text: qsTr("Save")
clickedFunc: function () { clickedFunc: function () {
var portValue = portTextField.textField.text === "" var portValue = portTextField.textField.text === ""