feat: disable language/translations selection
- make it conditionally available for testing via Settings/Advanced/Enable translations - display a tooltip and infobox explaining the current and future situation - upon app start, force the language to "en" if the translations are not enabled; and suggest app restart when they get disabled Fixes #14527
This commit is contained in:
parent
85066fccc8
commit
d0658feb26
|
@ -4,7 +4,7 @@ import ../../constants
|
||||||
|
|
||||||
# Local App Settings keys:
|
# Local App Settings keys:
|
||||||
const LAS_KEY_LANGUAGE* = "global/language"
|
const LAS_KEY_LANGUAGE* = "global/language"
|
||||||
const DEFAULT_LOCALE = "en"
|
const DEFAULT_LAS_KEY_LANGUAGE* = "en"
|
||||||
const LAS_KEY_THEME* = "global/theme"
|
const LAS_KEY_THEME* = "global/theme"
|
||||||
const DEFAULT_THEME = 2 #system theme, from qml
|
const DEFAULT_THEME = 2 #system theme, from qml
|
||||||
const LAS_KEY_GEOMETRY = "global/app_geometry"
|
const LAS_KEY_GEOMETRY = "global/app_geometry"
|
||||||
|
@ -20,6 +20,8 @@ const LAS_KEY_FAKE_LOADING_SCREEN_ENABLED = "global/fake_loading_screen"
|
||||||
let DEFAULT_FAKE_LOADING_SCREEN_ENABLED = defined(production) and not TEST_MODE_ENABLED #enabled in production, disabled in development and e2e tests
|
let DEFAULT_FAKE_LOADING_SCREEN_ENABLED = defined(production) and not TEST_MODE_ENABLED #enabled in production, disabled in development and e2e tests
|
||||||
const LAS_KEY_SHARDED_COMMUNITIES_ENABLED = "global/sharded_communities"
|
const LAS_KEY_SHARDED_COMMUNITIES_ENABLED = "global/sharded_communities"
|
||||||
const DEFAULT_LAS_KEY_SHARDED_COMMUNITIES_ENABLED = false
|
const DEFAULT_LAS_KEY_SHARDED_COMMUNITIES_ENABLED = false
|
||||||
|
const LAS_KEY_TRANSLATIONS_ENABLED = "global/translations_enabled"
|
||||||
|
const DEFAULT_LAS_KEY_TRANSLATIONS_ENABLED = false
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type LocalAppSettings* = ref object of QObject
|
type LocalAppSettings* = ref object of QObject
|
||||||
|
@ -42,7 +44,7 @@ QtObject:
|
||||||
|
|
||||||
proc languageChanged*(self: LocalAppSettings) {.signal.}
|
proc languageChanged*(self: LocalAppSettings) {.signal.}
|
||||||
proc getLanguage*(self: LocalAppSettings): string {.slot.} =
|
proc getLanguage*(self: LocalAppSettings): string {.slot.} =
|
||||||
self.settings.value(LAS_KEY_LANGUAGE, newQVariant(DEFAULT_LOCALE)).stringVal
|
self.settings.value(LAS_KEY_LANGUAGE, newQVariant(DEFAULT_LAS_KEY_LANGUAGE)).stringVal
|
||||||
proc setLanguage*(self: LocalAppSettings, value: string) {.slot.} =
|
proc setLanguage*(self: LocalAppSettings, value: string) {.slot.} =
|
||||||
self.settings.setValue(LAS_KEY_LANGUAGE, newQVariant(value))
|
self.settings.setValue(LAS_KEY_LANGUAGE, newQVariant(value))
|
||||||
self.languageChanged()
|
self.languageChanged()
|
||||||
|
@ -127,22 +129,6 @@ QtObject:
|
||||||
write = setScrollDeceleration
|
write = setScrollDeceleration
|
||||||
notify = scrollDecelerationChanged
|
notify = scrollDecelerationChanged
|
||||||
|
|
||||||
proc removeKey*(self: LocalAppSettings, key: string) =
|
|
||||||
if(self.settings.isNil):
|
|
||||||
return
|
|
||||||
|
|
||||||
self.settings.remove(key)
|
|
||||||
|
|
||||||
case key:
|
|
||||||
of LAS_KEY_LANGUAGE: self.languageChanged()
|
|
||||||
of LAS_KEY_THEME: self.themeChanged()
|
|
||||||
of LAS_KEY_GEOMETRY: self.geometryChanged()
|
|
||||||
of LAS_KEY_VISIBILITY: self.visibilityChanged()
|
|
||||||
of LAS_KEY_SCROLL_VELOCITY: self.scrollVelocityChanged()
|
|
||||||
of LAS_KEY_SCROLL_DECELERATION: self.scrollDecelerationChanged()
|
|
||||||
of LAS_KEY_CUSTOM_MOUSE_SCROLLING_ENABLED: self.isCustomMouseScrollingEnabledChanged()
|
|
||||||
|
|
||||||
|
|
||||||
proc getTestEnvironment*(self: LocalAppSettings): bool {.slot.} =
|
proc getTestEnvironment*(self: LocalAppSettings): bool {.slot.} =
|
||||||
return TEST_MODE_ENABLED
|
return TEST_MODE_ENABLED
|
||||||
|
|
||||||
|
@ -174,3 +160,35 @@ QtObject:
|
||||||
read = getWakuV2ShardedCommunitiesEnabled
|
read = getWakuV2ShardedCommunitiesEnabled
|
||||||
write = setWakuV2ShardedCommunitiesEnabled
|
write = setWakuV2ShardedCommunitiesEnabled
|
||||||
notify = wakuV2ShardedCommunitiesEnabledChanged
|
notify = wakuV2ShardedCommunitiesEnabledChanged
|
||||||
|
|
||||||
|
proc translationsEnabledChanged*(self: LocalAppSettings) {.signal.}
|
||||||
|
proc getTranslationsEnabled*(self: LocalAppSettings): bool {.slot.} =
|
||||||
|
self.settings.value(LAS_KEY_TRANSLATIONS_ENABLED, newQVariant(DEFAULT_LAS_KEY_TRANSLATIONS_ENABLED)).boolVal
|
||||||
|
proc setTranslationsEnabled*(self: LocalAppSettings, value: bool) {.slot.} =
|
||||||
|
if value == self.getTranslationsEnabled:
|
||||||
|
return
|
||||||
|
self.settings.setValue(LAS_KEY_TRANSLATIONS_ENABLED, newQVariant(value))
|
||||||
|
self.translationsEnabledChanged()
|
||||||
|
|
||||||
|
QtProperty[bool] translationsEnabled:
|
||||||
|
read = getTranslationsEnabled
|
||||||
|
write = setTranslationsEnabled
|
||||||
|
notify = translationsEnabledChanged
|
||||||
|
|
||||||
|
proc removeKey*(self: LocalAppSettings, key: string) =
|
||||||
|
if(self.settings.isNil):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.settings.remove(key)
|
||||||
|
|
||||||
|
case key:
|
||||||
|
of LAS_KEY_LANGUAGE: self.languageChanged()
|
||||||
|
of LAS_KEY_THEME: self.themeChanged()
|
||||||
|
of LAS_KEY_GEOMETRY: self.geometryChanged()
|
||||||
|
of LAS_KEY_VISIBILITY: self.visibilityChanged()
|
||||||
|
of LAS_KEY_SCROLL_VELOCITY: self.scrollVelocityChanged()
|
||||||
|
of LAS_KEY_SCROLL_DECELERATION: self.scrollDecelerationChanged()
|
||||||
|
of LAS_KEY_CUSTOM_MOUSE_SCROLLING_ENABLED: self.isCustomMouseScrollingEnabledChanged()
|
||||||
|
of LAS_KEY_FAKE_LOADING_SCREEN_ENABLED: self.fakeLoadingScreenEnabledChanged()
|
||||||
|
of LAS_KEY_SHARDED_COMMUNITIES_ENABLED: self.wakuV2ShardedCommunitiesEnabledChanged()
|
||||||
|
of LAS_KEY_TRANSLATIONS_ENABLED: self.translationsEnabledChanged()
|
||||||
|
|
|
@ -6,6 +6,7 @@ import app/core/main
|
||||||
import constants as main_constants
|
import constants as main_constants
|
||||||
|
|
||||||
import app/global/global_singleton
|
import app/global/global_singleton
|
||||||
|
import app/global/local_app_settings
|
||||||
import app/boot/app_controller
|
import app/boot/app_controller
|
||||||
|
|
||||||
when defined(macosx) and defined(arm64):
|
when defined(macosx) and defined(arm64):
|
||||||
|
@ -132,6 +133,11 @@ proc mainProc() =
|
||||||
|
|
||||||
let app = newQGuiApplication()
|
let app = newQGuiApplication()
|
||||||
|
|
||||||
|
# force default language ("en") if not "Settings/Advanced/Enable translations"
|
||||||
|
if not singletonInstance.localAppSettings.getTranslationsEnabled():
|
||||||
|
if singletonInstance.localAppSettings.getLanguage() != DEFAULT_LAS_KEY_LANGUAGE:
|
||||||
|
singletonInstance.localAppSettings.setLanguage(DEFAULT_LAS_KEY_LANGUAGE)
|
||||||
|
|
||||||
# Required by the WalletConnectSDK view right after creating the QGuiApplication instance
|
# Required by the WalletConnectSDK view right after creating the QGuiApplication instance
|
||||||
initializeWebView()
|
initializeWebView()
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,19 @@ import AppLayouts.Profile.stores 1.0
|
||||||
import Storybook 1.0
|
import Storybook 1.0
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
import mainui 1.0
|
||||||
|
|
||||||
SplitView {
|
SplitView {
|
||||||
|
id: root
|
||||||
|
|
||||||
Logs { id: logs }
|
Logs { id: logs }
|
||||||
|
|
||||||
|
Popups {
|
||||||
|
popupParent: root
|
||||||
|
rootStore: QtObject {}
|
||||||
|
communityTokensStore: QtObject {}
|
||||||
|
}
|
||||||
|
|
||||||
SplitView {
|
SplitView {
|
||||||
orientation: Qt.Vertical
|
orientation: Qt.Vertical
|
||||||
SplitView.fillWidth: true
|
SplitView.fillWidth: true
|
||||||
|
@ -19,8 +28,9 @@ SplitView {
|
||||||
LanguageView {
|
LanguageView {
|
||||||
SplitView.fillWidth: true
|
SplitView.fillWidth: true
|
||||||
SplitView.fillHeight: true
|
SplitView.fillHeight: true
|
||||||
contentWidth: parent.width
|
contentWidth: parent.width - 150
|
||||||
|
|
||||||
|
languageSelectionEnabled: ctrlLanguageSelectionEnabled.checked
|
||||||
languageStore: LanguageStore {
|
languageStore: LanguageStore {
|
||||||
property string currentLanguage: "en"
|
property string currentLanguage: "en"
|
||||||
|
|
||||||
|
@ -41,6 +51,14 @@ SplitView {
|
||||||
state: 2
|
state: 2
|
||||||
selected: true
|
selected: true
|
||||||
}
|
}
|
||||||
|
ListElement {
|
||||||
|
locale: "cs_CZ"
|
||||||
|
name: "Czech"
|
||||||
|
shortName: "čeština"
|
||||||
|
flag: "🇨🇿"
|
||||||
|
state: 1
|
||||||
|
selected: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeLanguage(language) {
|
function changeLanguage(language) {
|
||||||
|
@ -92,16 +110,12 @@ SplitView {
|
||||||
SplitView.preferredHeight: 200
|
SplitView.preferredHeight: 200
|
||||||
|
|
||||||
logsView.logText: logs.logText
|
logsView.logText: logs.logText
|
||||||
|
|
||||||
|
Switch {
|
||||||
|
id: ctrlLanguageSelectionEnabled
|
||||||
|
text: "Language selection enabled"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Control {
|
|
||||||
SplitView.minimumWidth: 300
|
|
||||||
SplitView.preferredWidth: 300
|
|
||||||
|
|
||||||
font.pixelSize: 13
|
|
||||||
|
|
||||||
// model editor will go here
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,9 +118,11 @@ Item {
|
||||||
*/
|
*/
|
||||||
property int menuAlignment: StatusListPicker.MenuAlignment.Right
|
property int menuAlignment: StatusListPicker.MenuAlignment.Right
|
||||||
|
|
||||||
|
readonly property alias button: btn
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlproperty enum StatusListPicker::MenuAlignment
|
\qmlproperty enum StatusListPicker::MenuAlignment
|
||||||
This property holds the allignment of the menu in terms of the button
|
This property holds the alignment of the menu in terms of the button
|
||||||
values can be Left, Right or Center
|
values can be Left, Right or Center
|
||||||
*/
|
*/
|
||||||
enum MenuAlignment {
|
enum MenuAlignment {
|
||||||
|
@ -216,7 +218,7 @@ Item {
|
||||||
contentColor: Theme.palette.primaryColor1
|
contentColor: Theme.palette.primaryColor1
|
||||||
text: d.selectedItemsText
|
text: d.selectedItemsText
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
type: StatusPickerButton.Type.Down
|
type: StatusPickerButton.PickerType.Down
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
picker.visible = !picker.visible
|
picker.visible = !picker.visible
|
||||||
|
|
|
@ -5,71 +5,65 @@ import QtQuick.Layouts 1.15
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Components 0.1
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
|
||||||
Button {
|
StatusButton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property color bgColor: Theme.palette.baseColor2
|
property color bgColor: Theme.palette.baseColor2
|
||||||
property color contentColor: Theme.palette.baseColor1
|
property color contentColor: Theme.palette.baseColor1
|
||||||
property var type: StatusPickerButton.Type.Next
|
property int type: StatusPickerButton.PickerType.Next
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\qmlproperty StatusAssetSettings StatusPickerButton::asset
|
\qmlproperty StatusAssetSettings StatusPickerButton::asset
|
||||||
This property holds the image settings information.
|
This property holds the image settings information.
|
||||||
*/
|
*/
|
||||||
property StatusAssetSettings asset: StatusAssetSettings {
|
asset {
|
||||||
width: 20
|
width: 20
|
||||||
height: 20
|
height: 20
|
||||||
imgIsIdenticon: false
|
imgIsIdenticon: false
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Type {
|
enum PickerType {
|
||||||
Next,
|
Next,
|
||||||
Down
|
Down
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: 446
|
|
||||||
implicitHeight: 44
|
|
||||||
font.pixelSize: 15
|
|
||||||
horizontalPadding: 16
|
horizontalPadding: 16
|
||||||
|
verticalPadding: 3
|
||||||
spacing: 4
|
spacing: 4
|
||||||
icon.width: 16
|
icon.width: 16
|
||||||
icon.height: 16
|
icon.height: 16
|
||||||
background:Rectangle {
|
background: Rectangle {
|
||||||
radius: 8
|
radius: 8
|
||||||
color: root.bgColor
|
color: root.bgColor
|
||||||
}
|
}
|
||||||
|
opacity: !root.interactive || !root.enabled ? 0.5 : 1
|
||||||
contentItem: RowLayout {
|
contentItem: RowLayout {
|
||||||
clip: true
|
|
||||||
spacing: root.spacing
|
spacing: root.spacing
|
||||||
StatusIcon {
|
StatusIcon {
|
||||||
icon: "tiny/chevron-down"
|
icon: "tiny/chevron-down"
|
||||||
visible: root.type === StatusPickerButton.Type.Down
|
visible: root.type === StatusPickerButton.PickerType.Down
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
color: !Qt.colorEqual(root.contentColor, Theme.palette.baseColor1) ? root.contentColor : Theme.palette.directColor1
|
color: !Qt.colorEqual(root.contentColor, Theme.palette.baseColor1) ? root.contentColor : Theme.palette.directColor1
|
||||||
width: root.icon.width
|
width: root.icon.width
|
||||||
height: root.icon.height
|
height: root.icon.height
|
||||||
}
|
}
|
||||||
StatusRoundedImage {
|
StatusRoundedImage {
|
||||||
visible: root.asset.name.toString() !== ""
|
visible: root.asset.name.toString() !== ""
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
Layout.preferredWidth: root.asset.width
|
Layout.preferredWidth: root.asset.width
|
||||||
Layout.preferredHeight: root.asset.height
|
Layout.preferredHeight: root.asset.height
|
||||||
image.source: root.asset.name
|
image.source: root.asset.name
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.alignment: Qt.AlignVCenter
|
font: root.font
|
||||||
font.pixelSize: root.font.pixelSize
|
|
||||||
color: root.contentColor
|
color: root.contentColor
|
||||||
text: root.text
|
text: root.text
|
||||||
clip: true
|
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
StatusIcon {
|
StatusIcon {
|
||||||
icon: "tiny/chevron-right"
|
icon: "tiny/chevron-right"
|
||||||
visible: root.type === StatusPickerButton.Type.Next
|
visible: root.type === StatusPickerButton.PickerType.Next
|
||||||
Layout.alignment: Qt.AlignVCenter
|
|
||||||
color: !Qt.colorEqual(root.contentColor, Theme.palette.baseColor1) ? root.contentColor : Theme.palette.directColor1
|
color: !Qt.colorEqual(root.contentColor, Theme.palette.baseColor1) ? root.contentColor : Theme.palette.directColor1
|
||||||
width: root.icon.width
|
width: root.icon.width
|
||||||
height: root.icon.height
|
height: root.icon.height
|
||||||
|
|
|
@ -10,9 +10,9 @@ import StatusQ.Core.Theme 0.1
|
||||||
\inqmlmodule StatusQ.Controls
|
\inqmlmodule StatusQ.Controls
|
||||||
\since StatusQ.Controls 0.1
|
\since StatusQ.Controls 0.1
|
||||||
\brief Displays a customizable WarningBox component.
|
\brief Displays a customizable WarningBox component.
|
||||||
Inherits \l{https://doc.qt.io/qt-5/qml-qtquick-controls2-control.html}{Item}.
|
Inherits \l{https://doc.qt.io/qt-5/qml-qtquick-controls2-control.html}{Control}.
|
||||||
|
|
||||||
The \c StatusWarningBox displays an customizable WarningBox for users to show an icon and text.
|
The \c StatusWarningBox displays a customizable WarningBox for users to show an icon and text.
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
\qml
|
\qml
|
||||||
|
@ -30,7 +30,6 @@ import StatusQ.Core.Theme 0.1
|
||||||
|
|
||||||
Control {
|
Control {
|
||||||
id: root
|
id: root
|
||||||
implicitWidth: 614
|
|
||||||
padding: 16
|
padding: 16
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -70,6 +69,12 @@ Control {
|
||||||
*/
|
*/
|
||||||
property int textSize: Theme.primaryTextFontSize
|
property int textSize: Theme.primaryTextFontSize
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty Component StatusWarningBox::extraContentComponent
|
||||||
|
This property lets you add some extra component on the trailing side (like a button)
|
||||||
|
*/
|
||||||
|
property alias extraContentComponent: extraContent.sourceComponent
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
radius: 8
|
radius: 8
|
||||||
opacity: 0.5
|
opacity: 0.5
|
||||||
|
@ -93,12 +98,12 @@ Control {
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
id: warningText
|
id: warningText
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: contentHeight
|
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
font.pixelSize: root.textSize
|
font.pixelSize: root.textSize
|
||||||
color: root.textColor
|
color: root.textColor
|
||||||
}
|
}
|
||||||
|
Loader {
|
||||||
|
id: extraContent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -278,6 +278,7 @@ StatusSectionLayout {
|
||||||
implicitWidth: parent.width
|
implicitWidth: parent.width
|
||||||
implicitHeight: parent.height
|
implicitHeight: parent.height
|
||||||
|
|
||||||
|
languageSelectionEnabled: localAppSettings.translationsEnabled
|
||||||
languageStore: root.store.languageStore
|
languageStore: root.store.languageStore
|
||||||
currencyStore: root.currencyStore
|
currencyStore: root.currencyStore
|
||||||
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.language)
|
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.language)
|
||||||
|
|
|
@ -339,6 +339,30 @@ SettingsContentBase {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusSettingsLineButton {
|
||||||
|
anchors.leftMargin: 0
|
||||||
|
anchors.rightMargin: 0
|
||||||
|
text: qsTr("Enable translations")
|
||||||
|
isSwitch: true
|
||||||
|
switchChecked: localAppSettings.translationsEnabled
|
||||||
|
onClicked: {
|
||||||
|
localAppSettings.translationsEnabled = !localAppSettings.translationsEnabled
|
||||||
|
if (!checked)
|
||||||
|
Global.openPopup(disableLanguagesPopupComponent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: disableLanguagesPopupComponent
|
||||||
|
ConfirmationDialog {
|
||||||
|
destroyOnClose: true
|
||||||
|
headerSettings.title: qsTr("Language reset")
|
||||||
|
confirmationText: qsTr("Display language will be switched back to English. You must restart the application for changes to take effect.")
|
||||||
|
confirmButtonLabel: qsTr("Restart")
|
||||||
|
onConfirmButtonClicked: Utils.restartApplication()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: replace with StatusQ component
|
// TODO: replace with StatusQ component
|
||||||
StatusSettingsLineButton {
|
StatusSettingsLineButton {
|
||||||
anchors.leftMargin: 0
|
anchors.leftMargin: 0
|
||||||
|
@ -479,7 +503,7 @@ SettingsContentBase {
|
||||||
onConfirmButtonClicked: {
|
onConfirmButtonClicked: {
|
||||||
root.advancedStore.toggleIsGoerliEnabled()
|
root.advancedStore.toggleIsGoerliEnabled()
|
||||||
close()
|
close()
|
||||||
Qt.quit()
|
Utils.restartApplication()
|
||||||
}
|
}
|
||||||
onCancelButtonClicked: {
|
onCancelButtonClicked: {
|
||||||
close()
|
close()
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.13
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.13
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
import shared.panels 1.0
|
import shared.panels 1.0
|
||||||
import shared.popups 1.0
|
import shared.popups 1.0
|
||||||
|
|
||||||
|
import StatusQ 0.1
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||||
|
@ -23,6 +24,7 @@ SettingsContentBase {
|
||||||
|
|
||||||
property LanguageStore languageStore
|
property LanguageStore languageStore
|
||||||
property var currencyStore
|
property var currencyStore
|
||||||
|
property bool languageSelectionEnabled
|
||||||
|
|
||||||
objectName: "languageView"
|
objectName: "languageView"
|
||||||
onVisibleChanged: { if(!visible) root.setViewIdleState()}
|
onVisibleChanged: { if(!visible) root.setViewIdleState()}
|
||||||
|
@ -93,6 +95,16 @@ SettingsContentBase {
|
||||||
Item { Layout.fillWidth: true }
|
Item { Layout.fillWidth: true }
|
||||||
StatusListPicker {
|
StatusListPicker {
|
||||||
id: languagePicker
|
id: languagePicker
|
||||||
|
|
||||||
|
button.interactive: root.languageSelectionEnabled
|
||||||
|
StatusToolTip {
|
||||||
|
y: parent.height + Style.current.padding
|
||||||
|
margins: 0
|
||||||
|
visible: !root.languageSelectionEnabled && languagePicker.button.hovered
|
||||||
|
orientation: StatusToolTip.Orientation.Bottom
|
||||||
|
text: qsTr("Translations coming soon")
|
||||||
|
}
|
||||||
|
|
||||||
property string newKey
|
property string newKey
|
||||||
|
|
||||||
function descriptionForState(state) {
|
function descriptionForState(state) {
|
||||||
|
@ -105,13 +117,13 @@ SettingsContentBase {
|
||||||
inputList: SortFilterProxyModel {
|
inputList: SortFilterProxyModel {
|
||||||
sourceModel: root.languageStore.languageModel
|
sourceModel: root.languageStore.languageModel
|
||||||
|
|
||||||
// !Don't use proxy roles cause they harm performance a lot!
|
|
||||||
// "category" is the only role that can't be mocked by StatusListPicker::proxy
|
// "category" is the only role that can't be mocked by StatusListPicker::proxy
|
||||||
// due to StatusListPicker internal implementation limitation (ListView's section.property)
|
// due to StatusListPicker internal implementation limitation (ListView's section.property)
|
||||||
proxyRoles: [
|
proxyRoles: [
|
||||||
ExpressionRole {
|
FastExpressionRole {
|
||||||
name: "category"
|
name: "category"
|
||||||
expression: languagePicker.descriptionForState(model.state)
|
expression: languagePicker.descriptionForState(model.state)
|
||||||
|
expectedRoles: ["state"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -129,7 +141,7 @@ SettingsContentBase {
|
||||||
proxy {
|
proxy {
|
||||||
key: (model) => model.locale
|
key: (model) => model.locale
|
||||||
name: (model) => model.name
|
name: (model) => model.name
|
||||||
shortName: (model) => model.native
|
shortName: (model) => model.native || model.shortName
|
||||||
symbol: (model) => ""
|
symbol: (model) => ""
|
||||||
imageSource: (model) => StatusQUtils.Emoji.iconSource(model.flag)
|
imageSource: (model) => StatusQUtils.Emoji.iconSource(model.flag)
|
||||||
selected: (model) => model.locale === root.languageStore.currentLanguage
|
selected: (model) => model.locale === root.languageStore.currentLanguage
|
||||||
|
@ -143,13 +155,28 @@ SettingsContentBase {
|
||||||
onItemPickerChanged: {
|
onItemPickerChanged: {
|
||||||
if(selected && root.languageStore.currentLanguage !== key) {
|
if(selected && root.languageStore.currentLanguage !== key) {
|
||||||
root.changeLanguage(key)
|
root.changeLanguage(key)
|
||||||
languageConfirmationDialog.active = true
|
Global.openPopup(languageConfirmationDialog)
|
||||||
languageConfirmationDialog.item.open()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusWarningBox {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.bottomMargin: Style.current.padding
|
||||||
|
borderColor: Theme.palette.baseColor2
|
||||||
|
textColor: Theme.palette.directColor1
|
||||||
|
icon: "group-chat"
|
||||||
|
iconColor: Theme.palette.baseColor1
|
||||||
|
text: qsTr("We need your help to translate Status, so that together we can bring privacy and free speech to the people everywhere, including those who need it most.")
|
||||||
|
extraContentComponent: StatusFlatButton {
|
||||||
|
icon.name: "external-link"
|
||||||
|
text: qsTr("Learn more")
|
||||||
|
size: StatusBaseButton.Size.Small
|
||||||
|
onClicked: Global.openLinkWithConfirmation(Constants.externalStatusLinkWithHttps + '/translations', Constants.externalStatusLinkWithHttps)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Separator {
|
Separator {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.bottomMargin: Style.current.padding
|
Layout.bottomMargin: Style.current.padding
|
||||||
|
@ -158,8 +185,7 @@ SettingsContentBase {
|
||||||
// Time format options:
|
// Time format options:
|
||||||
Column {
|
Column {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: Style.current.padding
|
spacing: Constants.settingsSection.itemSpacing
|
||||||
spacing: Style.current.padding
|
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
text: qsTr("Time Format")
|
text: qsTr("Time Format")
|
||||||
}
|
}
|
||||||
|
@ -183,15 +209,14 @@ SettingsContentBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Component {
|
||||||
id: languageConfirmationDialog
|
id: languageConfirmationDialog
|
||||||
active: false
|
ConfirmationDialog {
|
||||||
sourceComponent: ConfirmationDialog {
|
destroyOnClose: true
|
||||||
headerSettings.title: qsTr("Change language")
|
headerSettings.title: qsTr("Change language")
|
||||||
confirmationText: qsTr("Display language has been changed. You must restart the application for changes to take effect.")
|
confirmationText: qsTr("Display language has been changed. You must restart the application for changes to take effect.")
|
||||||
confirmButtonLabel: qsTr("Restart")
|
confirmButtonLabel: qsTr("Restart")
|
||||||
onConfirmButtonClicked: {
|
onConfirmButtonClicked: {
|
||||||
languageConfirmationDialog.active = false
|
|
||||||
Utils.restartApplication()
|
Utils.restartApplication()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue