feat(GODT-3121): reuse InfoTooltip.
This commit is contained in:
parent
e5db9b1ccc
commit
88c4737ba4
|
@ -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 {
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
<file>qml/BugReport/BugReportFlow.qml</file>
|
||||
<file>qml/BugReport/BugReportView.qml</file>
|
||||
<file>qml/BugReport/CategoryItem.qml</file>
|
||||
<file>qml/BugReport/QuestionItem.qml</file>
|
||||
<file>qml/Proton/Action.qml</file>
|
||||
<file>qml/Proton/ApplicationWindow.qml</file>
|
||||
<file>qml/Proton/Button.qml</file>
|
||||
|
@ -109,7 +110,6 @@
|
|||
<file>qml/Proton/TextArea.qml</file>
|
||||
<file>qml/Proton/TextField.qml</file>
|
||||
<file>qml/Proton/Toggle.qml</file>
|
||||
<file>qml/QuestionItem.qml</file>
|
||||
<file>qml/Resources/bug_report_flow.json</file>
|
||||
<file>qml/Resources/Help/Template.html</file>
|
||||
<file>qml/Resources/Help/WhyBridge.html</file>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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<<article.Index), "Duplicate index %d in knowledge base", article.Index)
|
||||
bits |= bits | (1 << article.Index)
|
||||
require.NotEmpty(t, article.URL, "KB article with index %d has no URL", article.Index)
|
||||
require.NotEmpty(t, article.Title, "KB article with index %d has no title", article.Index)
|
||||
require.NotEmpty(t, article.Keywords, "KB article with index %d has no keyword", article.Index)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,11 @@ package user
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/ProtonMail/gluon/reporter"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/configstatus"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/kb"
|
||||
)
|
||||
|
||||
func (user *User) SendConfigStatusSuccess(ctx context.Context) {
|
||||
|
@ -198,31 +200,16 @@ func (user *User) ExternalLinkClicked(article string) {
|
|||
return
|
||||
}
|
||||
|
||||
var trackedLinks = [...]string{
|
||||
"https://proton.me/support/bridge",
|
||||
"https://proton.me/support/protonmail-bridge-clients-apple-mail",
|
||||
"https://proton.me/support/protonmail-bridge-clients-macos-outlook-2019",
|
||||
"https://proton.me/support/protonmail-bridge-clients-windows-outlook-2019",
|
||||
"https://proton.me/support/protonmail-bridge-clients-windows-thunderbird",
|
||||
"https://proton.me/support/protonmail-bridge-configure-client",
|
||||
"https://proton.me/support/bridge-address-list-has-changed",
|
||||
"https://proton.me/blog/tls-ssl-certificate#Extra-security-precautions-taken-by-ProtonMail",
|
||||
"https://proton.me/support/bridge-cant-move-cache",
|
||||
"https://proton.me/support/difference-combined-addresses-mode-split-addresses-mode",
|
||||
"https://proton.me/support/bridge-imap-login-failed",
|
||||
"https://proton.me/support/port-already-occupied-error",
|
||||
"https://proton.me/support/bridge-cannot-access-keychain",
|
||||
"https://proton.me/support/protonmail-bridge-manual-update",
|
||||
"https://proton.me/support/bridge-internal-error",
|
||||
"https://proton.me/support/apple-mail-certificate",
|
||||
"https://proton.me/support/macos-certificate-warning",
|
||||
"https://proton.me/support/why-you-need-bridge",
|
||||
articles, err := kb.GetArticleList()
|
||||
if err != nil {
|
||||
user.log.WithError(err).Error("Failed to retrieve list of KB articles.")
|
||||
return
|
||||
}
|
||||
|
||||
var reportToTelemetry bool
|
||||
for id, url := range trackedLinks {
|
||||
if url == article {
|
||||
if err := user.configStatus.RecordLinkClicked(uint(id)); err != nil {
|
||||
for _, a := range articles {
|
||||
if strings.EqualFold(a.URL, article) {
|
||||
if err := user.configStatus.RecordLinkClicked(a.Index); err != nil {
|
||||
user.log.WithError(err).Error("Failed to log LinkClicked in config_status.")
|
||||
}
|
||||
reportToTelemetry = true
|
||||
|
|
Loading…
Reference in New Issue