bugfix: ui fixes after merge with android tab navigation branch (#1339)

* bugfix: ui fixes after merge with android tab navigation branch

* bugfix: fix crash on quit

* chore: fix typos

* chore: remove useless comment

* bugfix: fix trigger behavior for `ListViewWithRadioButtonType`

* bugfix: fixed dropdown listview scrolling

* bugfix: fixed amfree availability display

* chore: remove item existence check in triggerCurrentItem function

---------

Co-authored-by: Cyril Anisimov <CyAn84@gmail.com>
This commit is contained in:
Nethius 2025-01-08 09:12:55 +03:00 committed by GitHub
parent 767b14b37a
commit 62f3a339b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 63 additions and 112 deletions

View file

@ -10,16 +10,15 @@ FocusController::FocusController(QQmlApplicationEngine *engine, QObject *parent)
m_focusChain {}, m_focusChain {},
m_focusedItem { nullptr }, m_focusedItem { nullptr },
m_rootObjects {}, m_rootObjects {},
m_defaultFocusItem { QSharedPointer<QQuickItem>() }, m_defaultFocusItem { nullptr },
m_lvfc { nullptr } m_lvfc { nullptr }
{ {
QObject::connect(m_engine.get(), &QQmlApplicationEngine::objectCreated, this, QObject::connect(m_engine, &QQmlApplicationEngine::objectCreated, this, [this](QObject *object, const QUrl &url) {
[this](QObject *object, const QUrl &url) { QQuickItem *newDefaultFocusItem = object->findChild<QQuickItem *>("defaultFocusItem");
QQuickItem *newDefaultFocusItem = object->findChild<QQuickItem *>("defaultFocusItem"); if (newDefaultFocusItem && m_defaultFocusItem != newDefaultFocusItem) {
if (newDefaultFocusItem && m_defaultFocusItem != newDefaultFocusItem) { m_defaultFocusItem = newDefaultFocusItem;
m_defaultFocusItem.reset(newDefaultFocusItem); }
} });
});
QObject::connect(this, &FocusController::focusedItemChanged, this, QObject::connect(this, &FocusController::focusedItemChanged, this,
[this]() { m_focusedItem->forceActiveFocus(Qt::TabFocusReason); }); [this]() { m_focusedItem->forceActiveFocus(Qt::TabFocusReason); });
@ -65,7 +64,7 @@ void FocusController::setFocusItem(QQuickItem *item)
void FocusController::setFocusOnDefaultItem() void FocusController::setFocusOnDefaultItem()
{ {
setFocusItem(m_defaultFocusItem.get()); setFocusItem(m_defaultFocusItem);
} }
void FocusController::pushRootObject(QObject *object) void FocusController::pushRootObject(QObject *object)

View file

@ -42,11 +42,11 @@ private:
void focusPreviousListViewItem(); void focusPreviousListViewItem();
void dropListView(); void dropListView();
QSharedPointer<QQmlApplicationEngine> m_engine; // Pointer to engine to get root object QQmlApplicationEngine *m_engine; // Pointer to engine to get root object
QList<QObject *> m_focusChain; // List of current objects to be focused QList<QObject *> m_focusChain; // List of current objects to be focused
QQuickItem *m_focusedItem; // Pointer to the active focus item QQuickItem *m_focusedItem; // Pointer to the active focus item
QStack<QObject *> m_rootObjects; QStack<QObject *> m_rootObjects; // Pointer to stack of roots for focus chain
QSharedPointer<QQuickItem> m_defaultFocusItem; QQuickItem *m_defaultFocusItem;
ListViewFocusController *m_lvfc; // ListView focus manager ListViewFocusController *m_lvfc; // ListView focus manager

View file

@ -70,7 +70,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
.arg(speed); .arg(speed);
} else if (serviceType == serviceType::amneziaFree){ } else if (serviceType == serviceType::amneziaFree){
QString description = tr("VPN to access blocked sites in regions with high levels of Internet censorship. "); QString description = tr("VPN to access blocked sites in regions with high levels of Internet censorship. ");
if (isServiceAvailable) { if (!isServiceAvailable) {
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>"); description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>");
} }
return description; return description;
@ -86,7 +86,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
} }
case IsServiceAvailableRole: { case IsServiceAvailableRole: {
if (serviceType == serviceType::amneziaFree) { if (serviceType == serviceType::amneziaFree) {
if (isServiceAvailable) { if (!isServiceAvailable) {
return false; return false;
} }
} }

View file

@ -12,7 +12,7 @@ Item {
readonly property string drawerExpandedStateName: "expanded" readonly property string drawerExpandedStateName: "expanded"
readonly property string drawerCollapsedStateName: "collapsed" readonly property string drawerCollapsedStateName: "collapsed"
readonly property bool isOpened: isExpandedStateActive() || (isCollapsedStateActive && (dragArea.drag.active === true)) readonly property bool isOpened: isExpandedStateActive() || (isCollapsedStateActive() && (dragArea.drag.active === true))
readonly property bool isClosed: isCollapsedStateActive() && (dragArea.drag.active === false) readonly property bool isClosed: isCollapsedStateActive() && (dragArea.drag.active === false)
property Component collapsedStateContent property Component collapsedStateContent
@ -123,7 +123,7 @@ Item {
id: background id: background
anchors.fill: parent anchors.fill: parent
color: root.isCollapsed ? AmneziaStyle.color.transparent : AmneziaStyle.color.translucentMidnightBlack color: root.isCollapsedStateActive() ? AmneziaStyle.color.transparent : AmneziaStyle.color.translucentMidnightBlack
Behavior on color { Behavior on color {
PropertyAnimation { duration: 200 } PropertyAnimation { duration: 200 }

View file

@ -216,9 +216,7 @@ Item {
ColumnLayout { ColumnLayout {
id: header id: header
anchors.top: parent.top anchors.fill: parent
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 16 anchors.topMargin: 16
BackButtonType { BackButtonType {
@ -226,31 +224,21 @@ Item {
backButtonImage: root.headerBackButtonImage backButtonImage: root.headerBackButtonImage
backButtonFunction: function() { menu.closeTriggered() } backButtonFunction: function() { menu.closeTriggered() }
} }
}
Column {
id: col
anchors.top: header.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 16
spacing: 16
Header2Type { Header2Type {
anchors.left: parent.left Layout.leftMargin: 16
anchors.right: parent.right Layout.rightMargin: 16
anchors.leftMargin: 16 Layout.bottomMargin: 16
anchors.rightMargin: 16 Layout.fillWidth: true
headerText: root.headerText headerText: root.headerText
width: parent.width
} }
Loader { Loader {
id: listViewLoader id: listViewLoader
sourceComponent: root.listView sourceComponent: root.listView
Layout.fillHeight: true
} }
} }
} }

View file

@ -30,6 +30,8 @@ ListView {
property bool isFocusable: true property bool isFocusable: true
ScrollBar.vertical: ScrollBarType {}
ButtonGroup { ButtonGroup {
id: buttonGroup id: buttonGroup
} }

View file

@ -20,7 +20,6 @@ Item {
id: timer id: timer
interval: 200 // Milliseconds interval: 200 // Milliseconds
onTriggered: { onTriggered: {
console.debug(">>> PageType timer triggered")
FocusController.resetRootObject() FocusController.resetRootObject()
FocusController.setFocusOnDefaultItem() FocusController.setFocusOnDefaultItem()
} }

View file

@ -266,11 +266,11 @@ PageType {
objectName: "rowLayoutLabel" objectName: "rowLayoutLabel"
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.topMargin: 8 Layout.topMargin: 8
Layout.bottomMargin: drawer.isCollapsed ? 44 : ServersModel.isDefaultServerFromApi ? 61 : 16 Layout.bottomMargin: drawer.isCollapsedStateActive ? 44 : ServersModel.isDefaultServerFromApi ? 61 : 16
spacing: 0 spacing: 0
BasicButtonType { BasicButtonType {
enabled: (ServersModel.defaultServerImagePathCollapsed !== "") && drawer.isCollapsed enabled: (ServersModel.defaultServerImagePathCollapsed !== "") && drawer.isCollapsedStateActive
hoverEnabled: enabled hoverEnabled: enabled
implicitHeight: 36 implicitHeight: 36
@ -288,8 +288,9 @@ PageType {
buttonTextLabel.font.pixelSize: 13 buttonTextLabel.font.pixelSize: 13
buttonTextLabel.font.weight: 400 buttonTextLabel.font.weight: 400
text: drawer.isCollapsed ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded text: drawer.isCollapsedStateActive ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded
leftImageSource: ServersModel.defaultServerImagePathCollapsed leftImageSource: ServersModel.defaultServerImagePathCollapsed
leftImageColor: ""
changeLeftImageSize: false changeLeftImageSize: false
rightImageSource: hoverEnabled ? "qrc:/images/controls/chevron-down.svg" : "" rightImageSource: hoverEnabled ? "qrc:/images/controls/chevron-down.svg" : ""
@ -347,7 +348,6 @@ PageType {
objectName: "containersListView" objectName: "containersListView"
rootWidth: root.width rootWidth: root.width
height: 500 // TODO: make calculated
Connections { Connections {
objectName: "rowLayoutConnections" objectName: "rowLayoutConnections"

View file

@ -36,13 +36,13 @@ PageType {
ListView { ListView {
id: listview id: listview
property bool isFocusable: true
anchors.top: backButtonLayout.bottom anchors.top: backButtonLayout.bottom
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
width: parent.width width: parent.width
property bool isFocusable: true
Keys.onTabPressed: { Keys.onTabPressed: {
FocusController.nextKeyTabItem() FocusController.nextKeyTabItem()
} }
@ -138,26 +138,6 @@ PageType {
checkEmptyText: true checkEmptyText: true
} }
TextFieldWithHeaderType {
id: mtuTextField
Layout.fillWidth: true
Layout.topMargin: 16
headerText: qsTr("MTU")
textFieldText: mtu
textField.validator: IntValidator { bottom: 576; top: 65535 }
textField.onEditingFinished: {
if (textFieldText === "") {
textFieldText = "0"
}
if (textFieldText !== mtu) {
mtu = textFieldText
}
}
checkEmptyText: true
}
TextFieldWithHeaderType { TextFieldWithHeaderType {
id: junkPacketCountTextField id: junkPacketCountTextField
Layout.fillWidth: true Layout.fillWidth: true

View file

@ -176,7 +176,6 @@ PageType {
headerText: qsTr("Hash") headerText: qsTr("Hash")
drawerParent: root drawerParent: root
parentFlickable: fl
listView: ListViewWithRadioButtonType { listView: ListViewWithRadioButtonType {
id: hashListView id: hashListView
@ -225,7 +224,6 @@ PageType {
headerText: qsTr("Cipher") headerText: qsTr("Cipher")
drawerParent: root drawerParent: root
parentFlickable: fl
listView: ListViewWithRadioButtonType { listView: ListViewWithRadioButtonType {
id: cipherListView id: cipherListView

View file

@ -16,8 +16,6 @@ import "../Components"
PageType { PageType {
id: root id: root
//defaultActiveFocusItem: listview.currentItem.mtuTextField.textField
Item { Item {
id: focusItem id: focusItem
onFocusChanged: { onFocusChanged: {

View file

@ -122,26 +122,6 @@ PageType {
checkEmptyText: true checkEmptyText: true
} }
TextFieldWithHeaderType {
id: mtuTextField
Layout.fillWidth: true
Layout.topMargin: 16
headerText: qsTr("MTU")
textFieldText: mtu
textField.validator: IntValidator { bottom: 576; top: 65535 }
textField.onEditingFinished: {
if (textFieldText === "") {
textFieldText = "0"
}
if (textFieldText !== mtu) {
mtu = textFieldText
}
}
checkEmptyText: true
}
BasicButtonType { BasicButtonType {
id: saveButton id: saveButton
Layout.fillWidth: true Layout.fillWidth: true

View file

@ -18,13 +18,13 @@ PageType {
ListView { ListView {
id: menuContent id: menuContent
property var selectedText property bool isFocusable: true
width: parent.width width: parent.width
height: menuContent.contentItem.height height: parent.height
clip: true clip: true
interactive: false interactive: true
model: ApiCountryModel model: ApiCountryModel
ButtonGroup { ButtonGroup {
@ -34,8 +34,8 @@ PageType {
delegate: ColumnLayout { delegate: ColumnLayout {
id: content id: content
implicitWidth: parent.width width: menuContent.width
implicitHeight: content.implicitHeight height: content.implicitHeight
RowLayout { RowLayout {
VerticalRadioButton { VerticalRadioButton {

View file

@ -221,15 +221,8 @@ PageType {
SettingsController.clearSettings() SettingsController.clearSettings()
PageController.goToPageHome() PageController.goToPageHome()
} }
if (!GC.isMobile()) {
// root.defaultActiveFocusItem.forceActiveFocus()
}
} }
var noButtonFunction = function() { var noButtonFunction = function() {
if (!GC.isMobile()) {
// root.defaultActiveFocusItem.forceActiveFocus()
}
} }
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)

View file

@ -109,15 +109,8 @@ PageType {
SettingsController.secondaryDns = "1.0.0.1" SettingsController.secondaryDns = "1.0.0.1"
secondaryDns.textFieldText = SettingsController.secondaryDns secondaryDns.textFieldText = SettingsController.secondaryDns
PageController.showNotificationMessage(qsTr("Settings have been reset")) PageController.showNotificationMessage(qsTr("Settings have been reset"))
if (!GC.isMobile()) {
// defaultActiveFocusItem.forceActiveFocus()
}
} }
var noButtonFunction = function() { var noButtonFunction = function() {
if (!GC.isMobile()) {
// defaultActiveFocusItem.forceActiveFocus()
}
} }
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)

View file

@ -355,6 +355,7 @@ PageType {
serverSelectorListView.selectedIndex = 0 serverSelectorListView.selectedIndex = 0
} }
serverSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning)
serverSelectorListView.triggerCurrentItem() serverSelectorListView.triggerCurrentItem()
} }
@ -410,6 +411,7 @@ PageType {
function onSeverSelectorIndexChanged() { function onSeverSelectorIndexChanged() {
var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer")) var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer"))
protocolSelectorListView.selectedIndex = defaultContainer protocolSelectorListView.selectedIndex = defaultContainer
protocolSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning)
protocolSelectorListView.triggerCurrentItem() protocolSelectorListView.triggerCurrentItem()
} }
} }
@ -603,6 +605,7 @@ PageType {
} }
clip: true clip: true
interactive: false
reuseItems: true reuseItems: true
delegate: Item { delegate: Item {
@ -667,7 +670,11 @@ PageType {
ParagraphTextType { ParagraphTextType {
color: AmneziaStyle.color.mutedGray color: AmneziaStyle.color.mutedGray
visible: creationDate visible: creationDate
Layout.fillWidth: true Layout.maximumWidth: parent.width
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Qt.ElideRight
text: qsTr("Creation date: %1").arg(creationDate) text: qsTr("Creation date: %1").arg(creationDate)
} }
@ -675,7 +682,11 @@ PageType {
ParagraphTextType { ParagraphTextType {
color: AmneziaStyle.color.mutedGray color: AmneziaStyle.color.mutedGray
visible: latestHandshake visible: latestHandshake
Layout.fillWidth: true Layout.maximumWidth: parent.width
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Qt.ElideRight
text: qsTr("Latest handshake: %1").arg(latestHandshake) text: qsTr("Latest handshake: %1").arg(latestHandshake)
} }
@ -683,7 +694,11 @@ PageType {
ParagraphTextType { ParagraphTextType {
color: AmneziaStyle.color.mutedGray color: AmneziaStyle.color.mutedGray
visible: dataReceived visible: dataReceived
Layout.fillWidth: true Layout.maximumWidth: parent.width
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Qt.ElideRight
text: qsTr("Data received: %1").arg(dataReceived) text: qsTr("Data received: %1").arg(dataReceived)
} }
@ -691,7 +706,11 @@ PageType {
ParagraphTextType { ParagraphTextType {
color: AmneziaStyle.color.mutedGray color: AmneziaStyle.color.mutedGray
visible: dataSent visible: dataSent
Layout.fillWidth: true Layout.maximumWidth: parent.width
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Qt.ElideRight
text: qsTr("Data sent: %1").arg(dataSent) text: qsTr("Data sent: %1").arg(dataSent)
} }
@ -699,7 +718,9 @@ PageType {
ParagraphTextType { ParagraphTextType {
color: AmneziaStyle.color.mutedGray color: AmneziaStyle.color.mutedGray
visible: allowedIps visible: allowedIps
Layout.fillWidth: true Layout.maximumWidth: parent.width
wrapMode: Text.Wrap
text: qsTr("Allowed IPs: %1").arg(allowedIps) text: qsTr("Allowed IPs: %1").arg(allowedIps)
} }