From 88c4737ba47a370e4e32441917e9c4d64446f5ab Mon Sep 17 00:00:00 2001 From: Xavier Michelon Date: Mon, 4 Dec 2023 18:01:48 +0100 Subject: [PATCH] feat(GODT-3121): reuse InfoTooltip. --- internal/configstatus/config_status.go | 8 ++-- .../bridge-gui/bridge-gui/Resources.qrc | 2 +- .../bridge-gui/qml/BugReport/CategoryItem.qml | 41 +++---------------- .../qml/{ => BugReport}/QuestionItem.qml | 0 .../bridge-gui/qml/Proton/InfoTooltip.qml | 15 +++---- internal/kb/kbArticleList.json | 39 +++++++++++++++++- internal/kb/suggester.go | 7 ++-- internal/kb/suggester_test.go | 13 +++--- internal/user/config_status.go | 31 ++++---------- 9 files changed, 78 insertions(+), 78 deletions(-) rename internal/frontend/bridge-gui/bridge-gui/qml/{ => BugReport}/QuestionItem.qml (100%) diff --git a/internal/configstatus/config_status.go b/internal/configstatus/config_status.go index 559fbdb3..2746a893 100644 --- a/internal/configstatus/config_status.go +++ b/internal/configstatus/config_status.go @@ -135,7 +135,7 @@ func (status *ConfigurationStatus) ApplyProgress() error { return status.Save() } -func (status *ConfigurationStatus) RecordLinkClicked(link uint) error { +func (status *ConfigurationStatus) RecordLinkClicked(link uint64) error { status.DataLock.Lock() defer status.DataLock.Unlock() @@ -198,11 +198,11 @@ func (data *ConfigurationStatusData) init() { data.DataV1.FailureDetails = "" } -func (data *ConfigurationStatusData) setClickedLink(pos uint) { +func (data *ConfigurationStatusData) setClickedLink(pos uint64) { data.DataV1.ClickedLink |= 1 << pos } -func (data *ConfigurationStatusData) hasLinkClicked(pos uint) bool { +func (data *ConfigurationStatusData) hasLinkClicked(pos uint64) bool { val := data.DataV1.ClickedLink & (1 << pos) return val > 0 } @@ -211,7 +211,7 @@ func (data *ConfigurationStatusData) clickedLinkToString() string { var str = "" var first = true for i := 0; i < 64; i++ { - if data.hasLinkClicked(uint(i)) { + if data.hasLinkClicked(uint64(i)) { if !first { str += "," } else { diff --git a/internal/frontend/bridge-gui/bridge-gui/Resources.qrc b/internal/frontend/bridge-gui/bridge-gui/Resources.qrc index 68c2707b..5e1f823a 100644 --- a/internal/frontend/bridge-gui/bridge-gui/Resources.qrc +++ b/internal/frontend/bridge-gui/bridge-gui/Resources.qrc @@ -89,6 +89,7 @@ qml/BugReport/BugReportFlow.qml qml/BugReport/BugReportView.qml qml/BugReport/CategoryItem.qml + qml/BugReport/QuestionItem.qml qml/Proton/Action.qml qml/Proton/ApplicationWindow.qml qml/Proton/Button.qml @@ -109,7 +110,6 @@ qml/Proton/TextArea.qml qml/Proton/TextField.qml qml/Proton/Toggle.qml - qml/QuestionItem.qml qml/Resources/bug_report_flow.json qml/Resources/Help/Template.html qml/Resources/Help/WhyBridge.html diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/BugReport/CategoryItem.qml b/internal/frontend/bridge-gui/bridge-gui/qml/BugReport/CategoryItem.qml index 2d4afae2..e268ca10 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/BugReport/CategoryItem.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/BugReport/CategoryItem.qml @@ -33,7 +33,7 @@ Item { RowLayout { anchors.fill: parent - spacing: 16 + spacing: 12 Label { id: mainLabel @@ -45,42 +45,13 @@ Item { wrapMode: Text.WordWrap } - ColorImage { - id: infoImage + InfoTooltip { Layout.alignment: Qt.AlignVCenter + Layout.topMargin: 4 Layout.bottomMargin: root._bottomMargin - color: root.colorScheme.interaction_norm - height: 21 - width: 21 - source: "/qml/icons/ic-info-circle.svg" - sourceSize.height: 21 - sourceSize.width: 21 - visible: root.hint !== "" - MouseArea { - id: imageArea - anchors.fill: infoImage - hoverEnabled: true - } - ToolTip { - id: toolTipinfo - text: root.hint - visible: imageArea.containsMouse - implicitWidth: Math.min(400, tooltipText.implicitWidth) - background: Rectangle { - radius: 4 - border.color: root.colorScheme.border_weak - color: root.colorScheme.background_weak - } - contentItem: Text { - id: tooltipText - color: root.colorScheme.text_hint - text: toolTipinfo.text - wrapMode: Text.WordWrap - - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } - } + colorScheme: root.colorScheme + text: root.hint + size: 16 } // fill height so the footer label will always be attached to the bottom diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/QuestionItem.qml b/internal/frontend/bridge-gui/bridge-gui/qml/BugReport/QuestionItem.qml similarity index 100% rename from internal/frontend/bridge-gui/bridge-gui/qml/QuestionItem.qml rename to internal/frontend/bridge-gui/bridge-gui/qml/BugReport/QuestionItem.qml diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/Proton/InfoTooltip.qml b/internal/frontend/bridge-gui/bridge-gui/qml/Proton/InfoTooltip.qml index 7da4b680..d0d1c863 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/Proton/InfoTooltip.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/Proton/InfoTooltip.qml @@ -19,17 +19,18 @@ import QtQuick.Controls import QtQuick.Layouts ColorImage { + id: root + property var colorScheme property string text - id: root - Layout.alignment: Qt.AlignVCenter - Layout.bottomMargin: root._bottomMargin + property int size: 16 + color: root.colorScheme.interaction_norm - height: sourceSize.height - width: sourceSize.width + height: size + width: size source: "/qml/icons/ic-info-circle.svg" - sourceSize.height: 16 - sourceSize.width: 16 + sourceSize.height: size + sourceSize.width: size visible: root.hint !== "" MouseArea { id: imageArea diff --git a/internal/kb/kbArticleList.json b/internal/kb/kbArticleList.json index 438b7094..d9b819a0 100644 --- a/internal/kb/kbArticleList.json +++ b/internal/kb/kbArticleList.json @@ -1,5 +1,6 @@ [ { + "index": 0, "url": "https://proton.me/support/automatically-start-bridge", "title": "Automatically start Bridge", "keywords": [ @@ -9,6 +10,7 @@ ] }, { + "index": 1, "url": "https://proton.me/support/bridge-automatic-update", "title": "Automatic Update and Bridge", "keywords": [ @@ -16,6 +18,7 @@ ] }, { + "index": 2, "url": "https://proton.me/support/messages-encrypted-via-bridge", "title": "Are my messages encrypted via Proton Mail Bridge?", "keywords": [ @@ -23,6 +26,7 @@ ] }, { + "index": 3, "url": "https://proton.me/support/labels-in-bridge", "title": "Labels in Bridge", "keywords": [ @@ -30,6 +34,7 @@ ] }, { + "index": 4, "url": "https://proton.me/support/bridge-ssl-connection-issue", "title": "Proton Mail Bridge connection issues with Thunderbird, Outlook, and Apple Mail", "keywords": [ @@ -37,6 +42,7 @@ ] }, { + "index": 5, "url": "https://proton.me/support/sending-pgp-emails-bridge", "title": "Sending PGP emails in Proton Mail Bridge", "keywords": [ @@ -44,6 +50,7 @@ ] }, { + "index": 6, "url": "https://proton.me/support/difference-combined-addresses-mode-split-addresses-mode", "title": "Difference between combined addresses mode and split addresses mode", "keywords": [ @@ -51,6 +58,7 @@ ] }, { + "index": 7, "url": "https://proton.me/support/thunderbird-connection-server-timed-error", "title": "Thunderbird: 'Connection to server timed out' error", "keywords": [ @@ -58,6 +66,7 @@ ] }, { + "index": 8, "url": "https://proton.me/support/update-required", "title": "Update required", "keywords": [ @@ -65,6 +74,7 @@ ] }, { + "index": 9, "url": "https://proton.me/support/port-already-occupied-error", "title": "Port already occupied error", "keywords": [ @@ -72,6 +82,7 @@ ] }, { + "index": 10, "url": "https://proton.me/support/clients-supported-bridge", "title": "Email clients supported by Proton Mail Bridge", "keywords": [ @@ -79,6 +90,7 @@ ] }, { + "index": 11, "url": "https://proton.me/support/imap-smtp-and-pop3-setup", "title": "IMAP, SMTP, and POP3 setup", "keywords": [ @@ -86,6 +98,7 @@ ] }, { + "index": 12, "url": "https://proton.me/support/protonmail-bridge-install", "title": "How to install Proton Mail Bridge", "keywords": [ @@ -93,6 +106,7 @@ ] }, { + "index": 13, "url": "https://proton.me/support/bridge-for-linux", "title": "Proton Mail Bridge for Linux", "keywords": [ @@ -100,6 +114,7 @@ ] }, { + "index": 14, "url": "https://proton.me/support/operating-systems-supported-bridge", "title": "System requirements for Proton Mail Bridge", "keywords": [ @@ -107,6 +122,7 @@ ] }, { + "index": 15, "url": "https://proton.me/support/protonmail-bridge-configure-client", "title": "How to configure your email client for Proton Mail Bridge", "keywords": [ @@ -114,6 +130,7 @@ ] }, { + "index": 16, "url": "https://proton.me/support/invalid-password-error-setting-email-client", "title": "Invalid password error while setting up email client", "keywords": [ @@ -121,6 +138,7 @@ ] }, { + "index": 17, "url": "https://proton.me/support/protonmail-bridge-clients-windows-outlook-2019", "title": "Proton Mail Bridge Microsoft Outlook for Windows 2019 setup guide", "keywords": [ @@ -128,6 +146,7 @@ ] }, { + "index": 18, "url": "https://proton.me/support/protonmail-bridge-clients-windows-outlook-2016", "title": "Proton Mail Bridge Microsoft Outlook 2016 for Windows setup guide", "keywords": [ @@ -135,6 +154,7 @@ ] }, { + "index": 19, "url": "https://proton.me/support/protonmail-bridge-clients-apple-mail", "title": "Proton Mail Bridge Apple Mail setup guide", "keywords": [ @@ -142,6 +162,7 @@ ] }, { + "index": 20, "url": "https://proton.me/support/protonmail-bridge-clients-macos-new-outlook", "title": "Proton Mail Bridge new Outlook for macOS setup guide", "keywords": [ @@ -149,6 +170,7 @@ ] }, { + "index": 21, "url": "https://proton.me/support/protonmail-bridge-clients-windows-thunderbird", "title": "Proton Mail Bridge Thunderbird setup guide for Windows, macOS, and Linux", "keywords": [ @@ -156,6 +178,7 @@ ] }, { + "index": 22, "url": "https://proton.me/support/protonmail-bridge-clients-macos-outlook-2016", "title": "Proton Mail Bridge Microsoft Outlook 2016 for macOS setup guide", "keywords": [ @@ -163,6 +186,7 @@ ] }, { + "index": 23, "url": "https://proton.me/support/protonmail-bridge-clients-macos-outlook-2019", "title": "Proton Mail Bridge Microsoft Outlook 2019 for macOS setup guide", "keywords": [ @@ -170,6 +194,7 @@ ] }, { + "index": 24, "url": "https://proton.me/support/protonmail-bridge-clients-windows-outlook-2013", "title": "Proton Mail Bridge Microsoft Outlook 2013 for Windows setup guide", "keywords": [ @@ -177,6 +202,7 @@ ] }, { + "index": 25, "url": "https://proton.me/support/protonmail-bridge-clients-macos-outlook-2011", "title": "Proton Mail Bridge Microsoft Outlook 2011 for macOS setup guide", "keywords": [ @@ -184,6 +210,7 @@ ] }, { + "index": 26, "url": "https://proton.me/support/install-bridge-linux-pkgbuild-file", "title": "Installing Proton Mail Bridge for Linux using a PKGBUILD file", "keywords": [ @@ -191,6 +218,7 @@ ] }, { + "index": 27, "url": "https://proton.me/support/installing-bridge-linux-deb-file", "title": "Installing Proton Mail Bridge for Linux using a DEB file", "keywords": [ @@ -198,6 +226,7 @@ ] }, { + "index": 28, "url": "https://proton.me/support/verifying-bridge-package", "title": "Verifying the Proton Mail Bridge package for Linux", "keywords": [ @@ -205,6 +234,7 @@ ] }, { + "index": 29, "url": "https://proton.me/support/bridge-cli-guide", "title": "Bridge CLI (command line interface) guide", "keywords": [ @@ -212,6 +242,7 @@ ] }, { + "index": 30, "url": "https://proton.me/support/install-bridge-linux-rpm-file", "title": "Installing Proton Mail Bridge for Linux using an RPM file", "keywords": [ @@ -219,6 +250,7 @@ ] }, { + "index": 31, "url": "https://proton.me/support/bridge-linux-login-error", "title": "How to fix Proton Bridge login errors", "keywords": [ @@ -226,6 +258,7 @@ ] }, { + "index": 32, "url": "https://proton.me/support/bridge-linux-tray-icon", "title": "How to fix a missing system tray icon in Linux", "keywords": [ @@ -233,6 +266,7 @@ ] }, { + "index": 33, "url": "https://proton.me/support/why-you-need-bridge", "title": "Why you need Proton Mail Bridge", "keywords": [ @@ -240,6 +274,7 @@ ] }, { + "index": 34, "url": "https://proton.me/support/protonmail-bridge-manual-update", "title": "How to manually update Proton Mail Bridge", "keywords": [ @@ -247,6 +282,7 @@ ] }, { + "index": 35, "url": "https://proton.me/support/macos-certificate-warning", "title": "Warning when installing Proton Mail Bridge on macOS", "keywords": [ @@ -254,10 +290,11 @@ ] }, { + "index": 36, "url": "https://proton.me/support/apple-mail-certificate", "title": "Why you need to install a certificate for Apple Mail with Proton Mail Bridge", "keywords": [ "TBD" ] } - ] +] diff --git a/internal/kb/suggester.go b/internal/kb/suggester.go index cd6a5c15..42b9af77 100644 --- a/internal/kb/suggester.go +++ b/internal/kb/suggester.go @@ -27,6 +27,7 @@ var articleListString []byte // Article is a struct that holds information about a knowledge-base article. type Article struct { + Index uint64 `json:"index"` URL string `json:"url"` Title string `json:"title"` Keywords []string `json:"keywords"` @@ -34,8 +35,8 @@ type Article struct { type ArticleList []Article -// getArticleList returns the list of KB articles. -func getArticleList() (ArticleList, error) { +// GetArticleList returns the list of KB articles. +func GetArticleList() (ArticleList, error) { var articles ArticleList err := json.Unmarshal(articleListString, &articles) @@ -44,7 +45,7 @@ func getArticleList() (ArticleList, error) { // GetSuggestions return a list of up to 3 suggestions for KB articles matching the given user input. func GetSuggestions(_ string) (ArticleList, error) { - articles, err := getArticleList() + articles, err := GetArticleList() if err != nil { return ArticleList{}, err } diff --git a/internal/kb/suggester_test.go b/internal/kb/suggester_test.go index 604a282f..d6749c30 100644 --- a/internal/kb/suggester_test.go +++ b/internal/kb/suggester_test.go @@ -24,14 +24,17 @@ import ( ) func Test_ArticleList(t *testing.T) { - articles, err := getArticleList() + articles, err := GetArticleList() require.NoError(t, err) require.NotEmpty(t, articles) - + var bits uint64 for _, article := range articles { - require.NotEmpty(t, article.URL) - require.NotEmpty(t, article.Title) - require.NotEmpty(t, article.Keywords) + require.Truef(t, article.Index < 64, "Invalid KB article index %d, (must be < 64)", article.Index) + require.Zerof(t, bits&(1<