fix[onboarding] Broken links to "Terms" and "Privacy"
- display the locally bundled privacy/terms of use texts in a popup - add support for reading text files with both relative and absolute files or URLs, useful for having the same file path in both storybook and the app Fixes #13877
This commit is contained in:
parent
e7a1f5e831
commit
666ba77051
|
@ -0,0 +1,55 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQml 2.15
|
||||
|
||||
import AppLayouts.Onboarding.popups 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
orientation: Qt.Vertical
|
||||
|
||||
Logs { id: logs }
|
||||
|
||||
function openDialog() {
|
||||
popupComponent.createObject(popupBg)
|
||||
}
|
||||
|
||||
Component.onCompleted: openDialog()
|
||||
|
||||
Item {
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
PopupBackground {
|
||||
id: popupBg
|
||||
anchors.fill: parent
|
||||
|
||||
Button {
|
||||
anchors.centerIn: parent
|
||||
text: "Reopen"
|
||||
|
||||
onClicked: openDialog()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: popupComponent
|
||||
BeforeGetStartedModal {
|
||||
id: popup
|
||||
anchors.centerIn: parent
|
||||
modal: false
|
||||
visible: true
|
||||
onClosed: destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Popups
|
||||
|
||||
// https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?type=design&node-id=38555-18004&mode=design&t=WHoI8vkSC9JScbPx-0
|
|
@ -17,15 +17,15 @@ QString StringUtilsInternal::escapeHtml(const QString& unsafe) const
|
|||
}
|
||||
|
||||
QString resolveFileUsingQmlImportPaths(QQmlEngine *engine, const QString &relativeFilePath) {
|
||||
QStringList importPaths = engine->importPathList();
|
||||
const auto importPaths = engine->importPathList();
|
||||
for (const auto &path : importPaths) {
|
||||
QString fullPath = path + "/" + relativeFilePath;
|
||||
const auto fullPath = path + QStringLiteral("/") + relativeFilePath;
|
||||
QFile file(fullPath);
|
||||
if (file.exists()) {
|
||||
return fullPath;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
|
||||
QString StringUtilsInternal::readTextFile(const QString& filePath) const
|
||||
|
@ -36,18 +36,27 @@ QString StringUtilsInternal::readTextFile(const QString& filePath) const
|
|||
return {};
|
||||
}
|
||||
|
||||
const auto resolvedFilePath = selector->selector()->select(filePath);
|
||||
QString selectedFilePath;
|
||||
const auto maybeFileUrl = QUrl(filePath).toLocalFile(); // support local file URLs (e.g. "file:///foo/bar/baz.txt")
|
||||
|
||||
QFile file(resolvedFilePath);
|
||||
if (QFile::exists(maybeFileUrl))
|
||||
selectedFilePath = maybeFileUrl;
|
||||
else
|
||||
selectedFilePath = selector->selector()->select(filePath);
|
||||
|
||||
if (selectedFilePath.startsWith(QLatin1String("qrc:/"))) // for some reason doesn't work with the "qrc:/" prefix, drop it
|
||||
selectedFilePath.remove(0, 3);
|
||||
|
||||
QFile file(selectedFilePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
auto fileUrl = resolveFileUsingQmlImportPaths(m_engine, filePath);
|
||||
if (fileUrl.isEmpty()) {
|
||||
const auto resolvedFilePath = resolveFileUsingQmlImportPaths(m_engine, filePath);
|
||||
if (resolvedFilePath.isEmpty()) {
|
||||
qWarning() << Q_FUNC_INFO << "Can't find file in QML import paths" << filePath;
|
||||
return {};
|
||||
}
|
||||
file.setFileName(fileUrl);
|
||||
file.setFileName(resolvedFilePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
qWarning() << Q_FUNC_INFO << "Error opening existing file" << fileUrl << "for reading";
|
||||
qWarning() << Q_FUNC_INFO << "Error opening existing file" << resolvedFilePath << "for reading";
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import QtQml.Models 2.14
|
|||
import utils 1.0
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Utils 0.1 as SQUtils
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Popups.Dialog 0.1
|
||||
|
@ -13,7 +14,7 @@ import StatusQ.Popups.Dialog 0.1
|
|||
StatusDialog {
|
||||
id: root
|
||||
|
||||
width: 480
|
||||
width: 600
|
||||
topPadding: Style.current.bigPadding
|
||||
bottomPadding: Style.current.bigPadding
|
||||
closePolicy: Popup.NoAutoClose
|
||||
|
@ -28,96 +29,94 @@ StatusDialog {
|
|||
StatusButton {
|
||||
objectName: "getStartedStatusButton"
|
||||
enabled: acknowledge.checked && termsOfUse.checked
|
||||
size: StatusBaseButton.Size.Large
|
||||
font.weight: Font.Medium
|
||||
text: qsTr("Get Started")
|
||||
text: qsTr("Get started")
|
||||
onClicked: root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
Column {
|
||||
width: 416
|
||||
spacing: Style.current.padding
|
||||
anchors.centerIn: parent
|
||||
contentItem: ColumnLayout {
|
||||
spacing: Style.current.padding
|
||||
|
||||
StatusCheckBox {
|
||||
id: acknowledge
|
||||
objectName: "acknowledgeCheckBox"
|
||||
spacing: Style.current.halfPadding
|
||||
font.pixelSize: 15
|
||||
width: parent.width
|
||||
text: qsTr("I acknowledge that Status Desktop is in Beta and by using it I take the full responsibility for all risks concerning my data and funds.")
|
||||
}
|
||||
StatusCheckBox {
|
||||
Layout.fillWidth: true
|
||||
id: acknowledge
|
||||
objectName: "acknowledgeCheckBox"
|
||||
spacing: Style.current.halfPadding
|
||||
text: qsTr("I acknowledge that Status Desktop is in Beta and by using it I take the full responsibility for all risks concerning my data and funds.")
|
||||
}
|
||||
|
||||
StatusCheckBox {
|
||||
id: termsOfUse
|
||||
objectName: "termsOfUseCheckBox"
|
||||
width: parent.width
|
||||
font.pixelSize: 15
|
||||
StatusCheckBox {
|
||||
Layout.fillWidth: true
|
||||
id: termsOfUse
|
||||
objectName: "termsOfUseCheckBox"
|
||||
|
||||
contentItem: Row {
|
||||
spacing: 4
|
||||
leftPadding: termsOfUse.indicator.width + termsOfUse.spacing
|
||||
contentItem: Row {
|
||||
spacing: 4
|
||||
leftPadding: termsOfUse.indicator.width + termsOfUse.spacing
|
||||
|
||||
StatusBaseText {
|
||||
text: qsTr("I accept Status")
|
||||
font.pixelSize: 15
|
||||
StatusBaseText {
|
||||
text: qsTr("I accept Status")
|
||||
}
|
||||
|
||||
StatusLinkText {
|
||||
objectName: "termsOfUseLink"
|
||||
text: qsTr("Terms of Use")
|
||||
color: Theme.palette.primaryColor1
|
||||
font.weight: Font.Medium
|
||||
font.pixelSize: Theme.primaryTextFontSize
|
||||
onClicked: {
|
||||
detailsPopup.title = qsTr("Status Software Terms of Use")
|
||||
detailsPopup.textFile = SQUtils.StringUtils.readTextFile(Qt.resolvedUrl("../../../../imports/assets/docs/terms-of-use.mdwn"))
|
||||
detailsPopup.open()
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
objectName: "termsOfUseLink"
|
||||
text: qsTr("Terms of Use")
|
||||
color: Theme.palette.primaryColor1
|
||||
font.pixelSize: 15
|
||||
font.weight: Font.Medium
|
||||
StatusBaseText {
|
||||
text: "&"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
parent.font.underline = true
|
||||
}
|
||||
onExited: {
|
||||
parent.font.underline = false
|
||||
}
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://status.im/terms-of-use/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
text: "&"
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
StatusBaseText {
|
||||
objectName: "privacyPolicyLink"
|
||||
text: qsTr("Privacy Policy")
|
||||
color: Theme.palette.primaryColor1
|
||||
font.pixelSize: 15
|
||||
font.weight: Font.Medium
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
parent.font.underline = true
|
||||
}
|
||||
onExited: {
|
||||
parent.font.underline = false
|
||||
}
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://status.im/privacy-policy/")
|
||||
}
|
||||
}
|
||||
StatusLinkText {
|
||||
objectName: "privacyPolicyLink"
|
||||
text: qsTr("Privacy Policy")
|
||||
color: Theme.palette.primaryColor1
|
||||
font.weight: Font.Medium
|
||||
font.pixelSize: Theme.primaryTextFontSize
|
||||
onClicked: {
|
||||
detailsPopup.title = qsTr("Status Software Privacy Statement")
|
||||
detailsPopup.textFile = SQUtils.StringUtils.readTextFile(Qt.resolvedUrl("../../../../imports/assets/docs/privacy.mdwn"))
|
||||
detailsPopup.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusDialog {
|
||||
id: detailsPopup
|
||||
|
||||
property string textFile
|
||||
|
||||
width: 600
|
||||
padding: 0
|
||||
standardButtons: Dialog.Ok
|
||||
anchors.centerIn: parent
|
||||
visible: false
|
||||
|
||||
onClosed: textFile = ""
|
||||
|
||||
StatusScrollView {
|
||||
id: scrollView
|
||||
anchors.fill: parent
|
||||
contentWidth: availableWidth
|
||||
padding: 20
|
||||
|
||||
StatusBaseText {
|
||||
width: scrollView.availableWidth
|
||||
wrapMode: Text.Wrap
|
||||
textFormat: Text.MarkdownText
|
||||
text: detailsPopup.textFile
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
BeforeGetStartedModal 1.0 BeforeGetStartedModal.qml
|
Loading…
Reference in New Issue