status-desktop/ui/app/AppLayouts/Profile/views/LanguageView.qml

240 lines
8.4 KiB
QML

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import utils 1.0
import shared.panels 1.0
import shared.popups 1.0
import shared.stores 1.0 as SharedStores
import StatusQ 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import AppLayouts.Profile.stores 1.0
import "../popups"
import SortFilterProxyModel 0.2
SettingsContentBase {
id: root
property LanguageStore languageStore
property SharedStores.CurrenciesStore currencyStore
property bool languageSelectionEnabled
objectName: "languageView"
onVisibleChanged: { if(!visible) root.setViewIdleState()}
onBaseAreaClicked: { root.setViewIdleState() }
function setViewIdleState() {
currencyPicker.close()
languagePicker.close()
}
function changeLanguage(key) {
languagePicker.newKey = key
Qt.callLater(root.languageStore.changeLanguage, languagePicker.newKey)
}
ColumnLayout {
spacing: Constants.settingsSection.itemSpacing
width: root.contentWidth
RowLayout {
Layout.fillWidth: true
z: root.z + 2
StatusBaseText {
text: qsTr("Set Display Currency")
}
Item { Layout.fillWidth: true }
StatusListPicker {
id: currencyPicker
property string newKey
// updateCurrency function operation blocks a little bit the UI
// so getting around it with a small pause (timer) in order to get
// the desired visual behavior
Timer {
id: currencyPause
interval: 100
onTriggered: {
const idx = StatusQUtils.ModelUtils.indexOf(currenciesModel, "key", currencyPicker.newKey)
const shortName = currenciesModel.get(idx === -1 ? 0 : idx).shortName
root.currencyStore.updateCurrency(shortName)
}
}
z: root.z + 2
inputList: CurrenciesModel {
id: currenciesModel
readonly property Connections connections: Connections {
target: root.currencyStore
function onCurrentCurrencyChanged() {
currenciesModel.setSelected(root.currencyStore.currentCurrency)
}
}
Component.onCompleted: setSelected(root.currencyStore.currentCurrency)
}
printSymbol: true
placeholderSearchText: qsTr("Search Currencies")
maxPickerHeight: 350
onItemPickerChanged: {
if(selected) {
currencyPicker.newKey = key
currencyPause.start()
}
}
}
}
RowLayout {
Layout.fillWidth: true
z: root.z + 1
StatusBaseText {
text: qsTr("Language")
}
Item { Layout.fillWidth: true }
StatusListPicker {
id: languagePicker
button.interactive: root.languageSelectionEnabled
StatusToolTip {
y: parent.height + Theme.padding
margins: 0
visible: !root.languageSelectionEnabled && languagePicker.button.hovered
orientation: StatusToolTip.Orientation.Bottom
text: qsTr("Translations coming soon")
}
property string newKey
function descriptionForState(state) {
if (state === Constants.translationsState.alpha) return qsTr("Alpha languages")
if (state === Constants.translationsState.beta) return qsTr("Beta languages")
return ""
}
objectName: "languagePicker"
inputList: SortFilterProxyModel {
sourceModel: root.languageStore.languageModel
// "category" is the only role that can't be mocked by StatusListPicker::proxy
// due to StatusListPicker internal implementation limitation (ListView's section.property)
proxyRoles: [
FastExpressionRole {
name: "category"
expression: languagePicker.descriptionForState(model.state)
expectedRoles: ["state"]
}
]
sorters: [
RoleSorter {
roleName: "state"
sortOrder: Qt.DescendingOrder
},
StringSorter {
roleName: "name"
}
]
}
proxy {
key: (model) => model.locale
name: (model) => model.name
shortName: (model) => model.native || model.shortName
symbol: (model) => ""
imageSource: (model) => StatusQUtils.Emoji.iconSource(model.flag)
selected: (model) => model.locale === root.languageStore.currentLanguage
setSelected: (model, val) => null // readonly
}
z: root.z + 1
placeholderSearchText: qsTr("Search Languages")
maxPickerHeight: 350
onItemPickerChanged: {
if(selected && root.languageStore.currentLanguage !== key) {
root.changeLanguage(key)
Global.openPopup(languageConfirmationDialog)
}
}
}
}
StatusWarningBox {
Layout.fillWidth: true
Layout.bottomMargin: Theme.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 {
Layout.fillWidth: true
Layout.bottomMargin: Theme.padding
}
// Time format options:
Column {
Layout.fillWidth: true
spacing: Constants.settingsSection.itemSpacing
StatusBaseText {
text: qsTr("Time Format")
}
StatusCheckBox {
id: use24hDefault
text: qsTr("Use System Settings")
font.pixelSize: 13
checked: LocaleUtils.settings.timeFormatUsesDefaults
onToggled: {
LocaleUtils.settings.timeFormatUsesDefaults = checked
if (checked)
LocaleUtils.settings.timeFormatUses24Hours = LocaleUtils.is24hTimeFormatDefault()
}
}
StatusCheckBox {
text: qsTr("Use 24-Hour Time")
font.pixelSize: 13
enabled: !use24hDefault.checked
checked: LocaleUtils.settings.timeFormatUses24Hours
onToggled: LocaleUtils.settings.timeFormatUses24Hours = checked
}
}
Component {
id: languageConfirmationDialog
ConfirmationDialog {
destroyOnClose: true
headerSettings.title: qsTr("Change language")
confirmationText: qsTr("Display language has been changed. You must restart the application for changes to take effect.")
confirmButtonLabel: qsTr("Restart")
onConfirmButtonClicked: SystemUtils.restartApplication()
}
}
}
}