diff --git a/harbour-fernschreiber.pro b/harbour-fernschreiber.pro
index 46bf66b..bd59210 100644
--- a/harbour-fernschreiber.pro
+++ b/harbour-fernschreiber.pro
@@ -108,6 +108,14 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/messageContent/MessageVideo.qml \
qml/components/messageContent/MessageVoiceNote.qml \
qml/components/messageContent/WebPagePreview.qml \
+ qml/components/settingsPage/Accordion.qml \
+ qml/components/settingsPage/AccordionItem.qml \
+ qml/components/settingsPage/ResponsiveGrid.qml \
+ qml/components/settingsPage/SettingsAppearance.qml \
+ qml/components/settingsPage/SettingsBehavior.qml \
+ qml/components/settingsPage/SettingsPrivacy.qml \
+ qml/components/settingsPage/SettingsStorage.qml \
+ qml/components/settingsPage/SettingsUserProfile.qml \
qml/js/debug.js \
qml/js/functions.js \
qml/pages/ActiveSessionsPage.qml \
diff --git a/qml/components/settingsPage/Accordion.qml b/qml/components/settingsPage/Accordion.qml
new file mode 100644
index 0000000..49ab79a
--- /dev/null
+++ b/qml/components/settingsPage/Accordion.qml
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2021 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+
+
+Column {
+ width: parent.width
+ property SilicaFlickable flickable
+ property bool animate: false
+ signal setActiveArea(string activeAreaTitle)
+ function scrollUpFlickable(amount) {
+ if(flickable) {
+ flickableAnimation.to = Math.max(0, flickable.contentY - amount);
+ flickableAnimation.start()
+ }
+ }
+
+ NumberAnimation {
+ id: flickableAnimation
+ target: flickable
+ property: "contentY"
+ duration: 200
+ }
+ onSetActiveArea: {
+ if(activeAreaTitle && flickable) {
+// flickable.scrollToTop();
+ }
+ }
+}
diff --git a/qml/components/settingsPage/AccordionItem.qml b/qml/components/settingsPage/AccordionItem.qml
new file mode 100644
index 0000000..8dbbaaa
--- /dev/null
+++ b/qml/components/settingsPage/AccordionItem.qml
@@ -0,0 +1,115 @@
+/*
+ Copyright (C) 2021 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+
+Item {
+ id: area
+ width: parent.width
+ height: button.height + content.height
+ property alias icon: image
+ property alias text: label.text
+ property alias asynchronous: content.asynchronous
+ property bool expanded: false
+ default property alias els: content.sourceComponent
+ states: [
+ State {
+ when: area.expanded
+ PropertyChanges { target: image; rotation: 90 }
+ PropertyChanges { target: content; height: content.implicitHeight + Theme.paddingLarge; opacity: 1.0 }
+ }
+ ]
+ transitions: Transition {
+ to: "*"
+ enabled: area.parent.animate
+ NumberAnimation { target: content; properties: "height, opacity"; duration: 200}
+ }
+ Connections {
+ target: area.parent
+ onSetActiveArea: {
+ var expand = (activeAreaTitle === area.text);
+ if(area.expanded && !expand && area.parent.scrollUpFlickable) {
+ area.parent.scrollUpFlickable(content.implicitHeight + Theme.paddingLarge);
+ }
+
+ area.expanded = expand;
+ }
+ }
+ BackgroundItem {
+ id: button
+ height: Theme.itemSizeMedium
+ onClicked: {
+ area.parent.animate = true;
+ area.parent.setActiveArea(area.expanded ? -1 : area.text)
+ }
+ Rectangle {
+ anchors.fill: parent
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: Theme.rgba(Theme.highlightBackgroundColor, 0.15) }
+ GradientStop { position: 1.0; color: "transparent" }
+ }
+ }
+ Label {
+ id: label
+ anchors {
+ left: parent.left
+ right: image.left
+ verticalCenter: parent.verticalCenter
+ leftMargin: Theme.horizontalPageMargin + Theme.paddingLarge
+ rightMargin: Theme.paddingMedium
+ }
+ horizontalAlignment: Text.AlignRight
+ truncationMode: TruncationMode.Fade
+ font.pixelSize: Theme.fontSizeSmall
+ color: button.highlighted ? Theme.highlightColor : Theme.primaryColor
+ textFormat: Text.PlainText
+ }
+ HighlightImage {
+ id: image
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ rightMargin: Theme.horizontalPageMargin
+ }
+ width: visible ? Theme.iconSizeMedium : 0
+ highlighted: parent.highlighted
+ source: "image://theme/icon-m-right"
+ rotation: -90
+ }
+ }
+ Loader {
+ id: content
+ width: parent.width
+ height: 0
+ opacity: 0
+ anchors.top: button.bottom
+ asynchronous: true
+ clip: true
+ }
+// Column {
+// id: content
+// width: parent.width
+// anchors.top: button.bottom
+// bottomPadding: Theme.paddingLarge
+// height: 0
+// opacity: 0
+// clip: true
+// }
+}
diff --git a/qml/components/settingsPage/ResponsiveGrid.qml b/qml/components/settingsPage/ResponsiveGrid.qml
new file mode 100644
index 0000000..68a5d52
--- /dev/null
+++ b/qml/components/settingsPage/ResponsiveGrid.qml
@@ -0,0 +1,29 @@
+/*
+ Copyright (C) 2021 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+
+Grid {
+ width: parent.width - ( 2 * x )
+ columns: (appWindow.deviceOrientation & Orientation.LandscapeMask) || Screen.sizeCategory === Screen.Large || Screen.sizeCategory === Screen.ExtraLarge ? 2 : 1
+
+ readonly property real columnWidth: width/columns
+
+}
diff --git a/qml/components/settingsPage/SettingsAppearance.qml b/qml/components/settingsPage/SettingsAppearance.qml
new file mode 100644
index 0000000..f0a3d39
--- /dev/null
+++ b/qml/components/settingsPage/SettingsAppearance.qml
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2021 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+
+AccordionItem {
+ text: qsTr("Appearance")
+ Component {
+ ResponsiveGrid {
+ bottomPadding: Theme.paddingMedium
+ TextSwitch {
+ id: stickersAsEmojisTextSwitch
+ width: parent.columnWidth
+ checked: appSettings.showStickersAsEmojis
+ text: qsTr("Show stickers as emojis")
+ description: qsTr("Only display emojis instead of the actual stickers")
+ automaticCheck: false
+ onClicked: {
+ appSettings.showStickersAsEmojis = !checked
+ }
+ }
+
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.showStickersAsImages
+ text: qsTr("Show stickers as images")
+ description: qsTr("Show background for stickers and align them centrally like images")
+ automaticCheck: false
+ onClicked: {
+ appSettings.showStickersAsImages = !checked
+ }
+ enabled: !stickersAsEmojisTextSwitch.checked
+ }
+
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.animateStickers
+ text: qsTr("Animate stickers")
+ automaticCheck: false
+ onClicked: {
+ appSettings.animateStickers = !checked
+ }
+ enabled: !stickersAsEmojisTextSwitch.checked
+ }
+ }
+ }
+}
diff --git a/qml/components/settingsPage/SettingsBehavior.qml b/qml/components/settingsPage/SettingsBehavior.qml
new file mode 100644
index 0000000..a3f1be1
--- /dev/null
+++ b/qml/components/settingsPage/SettingsBehavior.qml
@@ -0,0 +1,171 @@
+/*
+ Copyright (C) 2021 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+import WerkWolf.Fernschreiber 1.0
+
+AccordionItem {
+ text: qsTr("Behavior")
+ Component {
+ ResponsiveGrid {
+ bottomPadding: Theme.paddingMedium
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.sendByEnter
+ text: qsTr("Send message by enter")
+ description: qsTr("Send your message by pressing the enter key")
+ automaticCheck: false
+ onClicked: {
+ appSettings.sendByEnter = !checked
+ }
+ }
+
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.focusTextAreaOnChatOpen
+ text: qsTr("Focus text input on chat open")
+ description: qsTr("Focus the text input area when entering a chat")
+ automaticCheck: false
+ onClicked: {
+ appSettings.focusTextAreaOnChatOpen = !checked
+ }
+ }
+
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.focusTextAreaAfterSend
+ text: qsTr("Focus text input area after send")
+ description: qsTr("Focus the text input area after sending a message")
+ automaticCheck: false
+ onClicked: {
+ appSettings.focusTextAreaAfterSend = !checked
+ }
+ }
+
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.delayMessageRead
+ text: qsTr("Delay before marking messages as read")
+ description: qsTr("Fernschreiber will wait a bit before messages are marked as read")
+ automaticCheck: false
+ onClicked: {
+ appSettings.delayMessageRead = !checked
+ }
+ }
+
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.useOpenWith
+ text: qsTr("Open-with menu integration")
+ description: qsTr("Integrate Fernschreiber into open-with menu of Sailfish OS")
+ automaticCheck: false
+ onClicked: {
+ appSettings.useOpenWith = !checked
+ }
+ }
+
+ ComboBox {
+ id: feedbackComboBox
+ width: parent.columnWidth
+ label: qsTr("Notification feedback")
+ description: qsTr("Use non-graphical feedback (sound, vibration) for notifications")
+ menu: ContextMenu {
+ id: feedbackMenu
+ x: 0
+ width: feedbackComboBox.width
+
+ MenuItem {
+ readonly property int value: AppSettings.NotificationFeedbackAll
+ text: qsTr("All events")
+ onClicked: {
+ appSettings.notificationFeedback = value
+ }
+ }
+ MenuItem {
+ readonly property int value: AppSettings.NotificationFeedbackNew
+ text: qsTr("Only new events")
+ onClicked: {
+ appSettings.notificationFeedback = value
+ }
+ }
+ MenuItem {
+ readonly property int value: AppSettings.NotificationFeedbackNone
+ text: qsTr("None")
+ onClicked: {
+ appSettings.notificationFeedback = value
+ }
+ }
+ }
+
+ Component.onCompleted: updateFeedbackSelection()
+
+ function updateFeedbackSelection() {
+ var menuItems = feedbackMenu.children
+ var n = menuItems.length
+ for (var i=0; i 0
+ automaticCheck: false
+ onClicked: {
+ appSettings.notificationTurnsDisplayOn = !checked
+ }
+ Behavior on height { SmoothedAnimation { duration: 200 } }
+ }
+
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.notificationSoundsEnabled && enabled
+ text: qsTr("Enable notification sounds")
+ description: qsTr("When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.")
+ enabled: appSettings.notificationFeedback !== AppSettings.NotificationFeedbackNone
+ height: enabled ? implicitHeight: 0
+ clip: height < implicitHeight
+ visible: height > 0
+ automaticCheck: false
+ onClicked: {
+ appSettings.notificationSoundsEnabled = !checked
+ }
+ Behavior on height { SmoothedAnimation { duration: 200 } }
+ }
+
+ }
+ }
+}
diff --git a/qml/components/settingsPage/SettingsPrivacy.qml b/qml/components/settingsPage/SettingsPrivacy.qml
new file mode 100644
index 0000000..40a2ca0
--- /dev/null
+++ b/qml/components/settingsPage/SettingsPrivacy.qml
@@ -0,0 +1,267 @@
+/*
+ Copyright (C) 2021 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+import WerkWolf.Fernschreiber 1.0
+
+AccordionItem {
+ text: qsTr("Privacy")
+ Component {
+ Column {
+ bottomPadding: Theme.paddingMedium
+ Connections {
+ target: tdLibWrapper
+ onUserPrivacySettingUpdated: {
+ Debug.log("Received updated privacy setting: " + setting + ":" + rule);
+ switch (setting) {
+ case TelegramAPI.SettingAllowChatInvites:
+ allowChatInvitesComboBox.currentIndex = rule;
+ break;
+ case TelegramAPI.SettingAllowFindingByPhoneNumber:
+ allowFindingByPhoneNumberComboBox.currentIndex = rule;
+ break;
+ case TelegramAPI.SettingShowLinkInForwardedMessages:
+ showLinkInForwardedMessagesComboBox.currentIndex = rule;
+ break;
+ case TelegramAPI.SettingShowPhoneNumber:
+ showPhoneNumberComboBox.currentIndex = rule;
+ break;
+ case TelegramAPI.SettingShowProfilePhoto:
+ showProfilePhotoComboBox.currentIndex = rule;
+ break;
+ case TelegramAPI.SettingShowStatus:
+ showStatusComboBox.currentIndex = rule;
+ break;
+ }
+ }
+ }
+ ResponsiveGrid {
+ ComboBox {
+ id: allowChatInvitesComboBox
+ width: parent.columnWidth
+ label: qsTr("Allow chat invites")
+ description: qsTr("Privacy setting for managing whether you can be invited to chats.")
+ menu: ContextMenu {
+ x: 0
+ width: allowChatInvitesComboBox.width
+
+ MenuItem {
+ text: qsTr("Yes")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleAllowAll);
+ }
+ }
+ MenuItem {
+ text: qsTr("Your contacts only")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleAllowContacts);
+ }
+ }
+ MenuItem {
+ text: qsTr("No")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleRestrictAll);
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites);
+ }
+ }
+
+ ComboBox {
+ id: allowFindingByPhoneNumberComboBox
+ width: parent.columnWidth
+ label: qsTr("Allow finding by phone number")
+ description: qsTr("Privacy setting for managing whether you can be found by your phone number.")
+ menu: ContextMenu {
+ x: 0
+ width: allowFindingByPhoneNumberComboBox.width
+
+ MenuItem {
+ text: qsTr("Yes")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber, TelegramAPI.RuleAllowAll);
+ }
+ }
+ MenuItem {
+ text: qsTr("Your contacts only")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber, TelegramAPI.RuleAllowContacts);
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber);
+ }
+ }
+
+ ComboBox {
+ id: showLinkInForwardedMessagesComboBox
+ width: parent.columnWidth
+ label: qsTr("Show link in forwarded messages")
+ description: qsTr("Privacy setting for managing whether a link to your account is included in forwarded messages.")
+ menu: ContextMenu {
+ x: 0
+ width: showLinkInForwardedMessagesComboBox.width
+
+ MenuItem {
+ text: qsTr("Yes")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleAllowAll);
+ }
+ }
+ MenuItem {
+ text: qsTr("Your contacts only")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleAllowContacts);
+ }
+ }
+ MenuItem {
+ text: qsTr("No")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleRestrictAll);
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages);
+ }
+ }
+
+ ComboBox {
+ id: showPhoneNumberComboBox
+ width: parent.columnWidth
+ label: qsTr("Show phone number")
+ description: qsTr("Privacy setting for managing whether your phone number is visible.")
+ menu: ContextMenu {
+ x: 0
+ width: showPhoneNumberComboBox.width
+
+ MenuItem {
+ text: qsTr("Yes")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleAllowAll);
+ }
+ }
+ MenuItem {
+ text: qsTr("Your contacts only")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleAllowContacts);
+ }
+ }
+ MenuItem {
+ text: qsTr("No")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleRestrictAll);
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber);
+ }
+ }
+
+ ComboBox {
+ id: showProfilePhotoComboBox
+ width: parent.columnWidth
+ label: qsTr("Show profile photo")
+ description: qsTr("Privacy setting for managing whether your profile photo is visible.")
+ menu: ContextMenu {
+ x: 0
+ width: showProfilePhotoComboBox.width
+
+ MenuItem {
+ text: qsTr("Yes")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleAllowAll);
+ }
+ }
+ MenuItem {
+ text: qsTr("Your contacts only")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleAllowContacts);
+ }
+ }
+ MenuItem {
+ text: qsTr("No")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleRestrictAll);
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto);
+ }
+ }
+
+ ComboBox {
+ id: showStatusComboBox
+ width: parent.columnWidth
+ label: qsTr("Show status")
+ description: qsTr("Privacy setting for managing whether your online status is visible.")
+ menu: ContextMenu {
+ x: 0
+ width: showStatusComboBox.width
+
+ MenuItem {
+ text: qsTr("Yes")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleAllowAll);
+ }
+ }
+ MenuItem {
+ text: qsTr("Your contacts only")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleAllowContacts);
+ }
+ }
+ MenuItem {
+ text: qsTr("No")
+ onClicked: {
+ tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleRestrictAll);
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowStatus);
+ }
+ }
+ }
+
+ TextSwitch {
+ checked: appSettings.allowInlineBotLocationAccess
+ text: qsTr("Allow sending Location to inline bots")
+ description: qsTr("Some inline bots request location data when using them")
+ automaticCheck: false
+ onClicked: {
+ appSettings.allowInlineBotLocationAccess = !checked
+ }
+ }
+ }
+ }
+
+}
diff --git a/qml/components/settingsPage/SettingsStorage.qml b/qml/components/settingsPage/SettingsStorage.qml
new file mode 100644
index 0000000..8423e0e
--- /dev/null
+++ b/qml/components/settingsPage/SettingsStorage.qml
@@ -0,0 +1,51 @@
+/*
+ Copyright (C) 2021 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+import WerkWolf.Fernschreiber 1.0
+
+AccordionItem {
+ text: qsTr("Storage")
+ Component {
+ ResponsiveGrid {
+ bottomPadding: Theme.paddingMedium
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.onlineOnlyMode
+ text: qsTr("Enable online-only mode")
+ description: qsTr("Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.")
+ automaticCheck: false
+ onClicked: {
+ appSettings.onlineOnlyMode = !checked
+ }
+ }
+
+ TextSwitch {
+ width: parent.columnWidth
+ checked: appSettings.storageOptimizer
+ text: qsTr("Enable storage optimizer")
+ automaticCheck: false
+ onClicked: {
+ appSettings.storageOptimizer = !checked
+ }
+ }
+ }
+ }
+}
diff --git a/qml/components/settingsPage/SettingsUserProfile.qml b/qml/components/settingsPage/SettingsUserProfile.qml
new file mode 100644
index 0000000..0b6f901
--- /dev/null
+++ b/qml/components/settingsPage/SettingsUserProfile.qml
@@ -0,0 +1,261 @@
+/*
+ Copyright (C) 2021 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+import Sailfish.Pickers 1.0
+import WerkWolf.Fernschreiber 1.0
+import "../"
+import "../../pages/"
+import "../../js/functions.js" as Functions
+
+AccordionItem {
+ text: qsTr("User Profile")
+ Component {
+ Column {
+ id: accordionContent
+ bottomPadding: Theme.paddingMedium
+
+ readonly property var userInformation: tdLibWrapper.getUserInformation()
+ property bool uploadInProgress: false
+
+ Component.onCompleted: {
+ tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
+ }
+
+ Connections {
+ target: tdLibWrapper
+ onOwnUserUpdated: {
+ firstNameEditArea.text = userInformation.first_name;
+ lastNameEditArea.text = userInformation.last_name;
+ userNameEditArea.text = userInformation.username;
+ }
+ onUserProfilePhotosReceived: {
+ if (extra === userInformation.id.toString()) {
+ imageContainer.thumbnailModel = photos;
+ }
+ }
+ onFileUpdated: {
+ if (uploadInProgress) {
+ profilePictureButtonColumn.visible = !fileInformation.remote.is_uploading_active;
+ uploadInProgress = fileInformation.remote.is_uploading_active;
+ if (!fileInformation.remote.is_uploading_active) {
+ uploadInProgress = false;
+ tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
+ }
+ }
+ }
+ onOkReceived: {
+ if (request === "deleteProfilePhoto") {
+ tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
+ }
+ if (request === "setProfilePhoto") {
+ tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
+ profilePictureButtonColumn.visible = true;
+ uploadInProgress = false;
+ }
+ }
+ }
+
+ ResponsiveGrid {
+ x: Theme.horizontalPageMargin
+
+ InformationEditArea {
+ id: firstNameEditArea
+ visible: true
+ canEdit: true
+ headerText: qsTr("First Name", "first name of the logged-in profile - header")
+ text: userInformation.first_name
+ width: parent.columnWidth
+ headerLeftAligned: true
+
+ onSaveButtonClicked: {
+ if(!editItem.errorHighlight) {
+ tdLibWrapper.setName(textValue, lastNameEditArea.text);
+ } else {
+ isEditing = true;
+ }
+ }
+
+ onTextEdited: {
+ if(textValue.length > 0 && textValue.length < 65) {
+ editItem.errorHighlight = false;
+ editItem.label = "";
+ editItem.placeholderText = "";
+ } else {
+ editItem.label = qsTr("Enter 1-64 characters");
+ editItem.placeholderText = editItem.label;
+ editItem.errorHighlight = true;
+ }
+ }
+ }
+
+ InformationEditArea {
+ id: lastNameEditArea
+ visible: true
+ canEdit: true
+ headerText: qsTr("Last Name", "last name of the logged-in profile - header")
+ text: userInformation.last_name
+ width: parent.columnWidth
+ headerLeftAligned: true
+
+ onSaveButtonClicked: {
+ if(!editItem.errorHighlight) {
+ tdLibWrapper.setName(firstNameEditArea.text, textValue);
+ } else {
+ isEditing = true;
+ }
+ }
+
+ onTextEdited: {
+ if(textValue.length >= 0 && textValue.length < 65) {
+ editItem.errorHighlight = false;
+ editItem.label = "";
+ editItem.placeholderText = "";
+ } else {
+ editItem.label = qsTr("Enter 0-64 characters");
+ editItem.placeholderText = editItem.label;
+ editItem.errorHighlight = true;
+ }
+ }
+ }
+
+ InformationEditArea {
+ id: userNameEditArea
+ visible: true
+ canEdit: true
+ headerText: qsTr("Username", "user name of the logged-in profile - header")
+ text: userInformation.username
+ width: parent.columnWidth
+ headerLeftAligned: true
+
+ onSaveButtonClicked: {
+ tdLibWrapper.setUsername(textValue);
+ }
+ }
+
+ }
+
+ SectionHeader {
+ horizontalAlignment: Text.AlignLeft
+ text: qsTr("Profile Pictures")
+ }
+
+ Row {
+ width: parent.width - ( 2 * Theme.horizontalPageMargin )
+ spacing: Theme.paddingMedium
+
+ Item {
+ id: imageContainer
+ anchors.verticalCenter: parent.verticalCenter
+ width: parent.width / 2
+ height: profilePictureLoader.height
+ property var thumbnailModel: ({})
+ property bool thumbnailVisible: true
+ property bool thumbnailActive: thumbnailModel.length > 0
+ property int thumbnailRadius: imageContainer.width / 2
+
+ Loader {
+ id: profilePictureLoader
+ active: imageContainer.thumbnailActive
+ asynchronous: true
+ width: Theme.itemSizeExtraLarge
+ height: Theme.itemSizeExtraLarge
+ anchors.horizontalCenter: parent.horizontalCenter
+ source: "../ProfilePictureList.qml"
+ }
+
+ ProfileThumbnail {
+ id: chatPictureReplacement
+ visible: !profilePictureLoader.active
+ replacementStringHint: Functions.getUserName(accordionContent.userInformation)
+ radius: imageContainer.thumbnailRadius
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: Theme.itemSizeExtraLarge
+ height: Theme.itemSizeExtraLarge
+ }
+ }
+
+ Column {
+ id: profilePictureButtonColumn
+ spacing: Theme.paddingSmall
+ width: parent.width / 2
+
+ Button {
+ id: addProfilePictureButton
+ text: qsTr("Add Picture")
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ onClicked: {
+ pageStack.push(imagePickerPage);
+ }
+ }
+
+ Button {
+ id: removeProfilePictureButton
+ text: qsTr("Delete Picture")
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ }
+ onClicked: {
+ var pictureIdForDeletion = imageContainer.thumbnailModel[profilePictureLoader.item.currentPictureIndex].id;
+ Remorse.popupAction(settingsPage, qsTr("Deleting profile picture"), function() { tdLibWrapper.deleteProfilePhoto(pictureIdForDeletion) });
+ }
+ }
+ }
+
+ Column {
+ id: uploadStatusColumn
+ visible: !profilePictureButtonColumn.visible
+ spacing: Theme.paddingMedium
+ width: parent.width / 2
+
+ Text {
+ id: uploadingText
+ font.pixelSize: Theme.fontSizeSmall
+ text: qsTr("Uploading...")
+ horizontalAlignment: Text.AlignHCenter
+ color: Theme.secondaryColor
+ width: parent.width
+ }
+
+ BusyIndicator {
+ anchors.horizontalCenter: parent.horizontalCenter
+ running: uploadStatusColumn.visible
+ size: BusyIndicatorSize.Medium
+ }
+
+ }
+
+ }
+
+ Component {
+ id: imagePickerPage
+ ImagePickerPage {
+ onSelectedContentPropertiesChanged: {
+ profilePictureButtonColumn.visible = false;
+ uploadInProgress = true;
+ tdLibWrapper.setProfilePhoto(selectedContentProperties.filePath);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/qml/pages/SettingsPage.qml b/qml/pages/SettingsPage.qml
index 2796198..b1cf4f9 100644
--- a/qml/pages/SettingsPage.qml
+++ b/qml/pages/SettingsPage.qml
@@ -21,6 +21,7 @@ import Sailfish.Silica 1.0
import Sailfish.Pickers 1.0
import WerkWolf.Fernschreiber 1.0
import "../components"
+import "../components/settingsPage"
import "../js/functions.js" as Functions
import "../js/debug.js" as Debug
@@ -28,50 +29,6 @@ Page {
id: settingsPage
allowedOrientations: Orientation.All
- readonly property bool landscapeLayout: settingsPage.isLandscape
- readonly property var userInformation: tdLibWrapper.getUserInformation()
- property bool uploadInProgress: false
-
- onStatusChanged: {
- if (status === PageStatus.Active) {
- tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
- }
- }
-
- Connections {
- target: tdLibWrapper
- onOwnUserUpdated: {
- firstNameEditArea.text = userInformation.first_name;
- lastNameEditArea.text = userInformation.last_name;
- userNameEditArea.text = userInformation.username;
- }
- onUserProfilePhotosReceived: {
- if (extra === userInformation.id.toString()) {
- imageContainer.thumbnailModel = photos;
- }
- }
- onFileUpdated: {
- if (uploadInProgress) {
- profilePictureButtonColumn.visible = !fileInformation.remote.is_uploading_active;
- uploadInProgress = fileInformation.remote.is_uploading_active;
- if (!fileInformation.remote.is_uploading_active) {
- uploadInProgress = false;
- tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
- }
- }
- }
- onOkReceived: {
- if (request === "deleteProfilePhoto") {
- tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
- }
- if (request === "setProfilePhoto") {
- tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
- profilePictureButtonColumn.visible = true;
- uploadInProgress = false;
- }
- }
- }
-
SilicaFlickable {
id: settingsContainer
contentHeight: column.height
@@ -80,686 +37,19 @@ Page {
Column {
id: column
width: settingsPage.width
+ bottomPadding: Theme.paddingLarge
PageHeader {
title: qsTr("Settings")
}
- SectionHeader {
- text: qsTr("User Profile")
- }
-
- Grid {
- width: parent.width - ( 2 * Theme.horizontalPageMargin )
- columns: landscapeLayout ? 2 : 1
- columnSpacing: Theme.paddingLarge
- anchors.horizontalCenter: parent.horizontalCenter
-
- readonly property real columnWidth: width/columns
-
- InformationEditArea {
- id: firstNameEditArea
- visible: true
- canEdit: true
- headerText: qsTr("First Name", "first name of the logged-in profile - header")
- text: userInformation.first_name
- width: parent.columnWidth
- headerLeftAligned: true
-
- onSaveButtonClicked: {
- if(!editItem.errorHighlight) {
- tdLibWrapper.setName(textValue, lastNameEditArea.text);
- } else {
- isEditing = true;
- }
- }
-
- onTextEdited: {
- if(textValue.length > 0 && textValue.length < 65) {
- editItem.errorHighlight = false;
- editItem.label = "";
- editItem.placeholderText = "";
- } else {
- editItem.label = qsTr("Enter 1-64 characters");
- editItem.placeholderText = editItem.label;
- editItem.errorHighlight = true;
- }
- }
- }
-
- InformationEditArea {
- id: lastNameEditArea
- visible: true
- canEdit: true
- headerText: qsTr("Last Name", "last name of the logged-in profile - header")
- text: userInformation.last_name
- width: parent.columnWidth
- headerLeftAligned: true
-
- onSaveButtonClicked: {
- if(!editItem.errorHighlight) {
- tdLibWrapper.setName(firstNameEditArea.text, textValue);
- } else {
- isEditing = true;
- }
- }
-
- onTextEdited: {
- if(textValue.length >= 0 && textValue.length < 65) {
- editItem.errorHighlight = false;
- editItem.label = "";
- editItem.placeholderText = "";
- } else {
- editItem.label = qsTr("Enter 0-64 characters");
- editItem.placeholderText = editItem.label;
- editItem.errorHighlight = true;
- }
- }
- }
-
- InformationEditArea {
- id: userNameEditArea
- visible: true
- canEdit: true
- headerText: qsTr("Username", "user name of the logged-in profile - header")
- text: userInformation.username
- width: parent.columnWidth
- headerLeftAligned: true
-
- onSaveButtonClicked: {
- tdLibWrapper.setUsername(textValue);
- }
- }
-
- }
-
- SectionHeader {
- horizontalAlignment: Text.AlignLeft
- text: qsTr("Profile Pictures")
- }
-
- Row {
- width: parent.width - ( 2 * Theme.horizontalPageMargin )
- spacing: Theme.paddingMedium
-
- Item {
- id: imageContainer
- anchors.verticalCenter: parent.verticalCenter
- width: parent.width / 2
- height: profilePictureLoader.height
- property var thumbnailModel: ({})
- property bool thumbnailVisible: true
- property bool thumbnailActive: thumbnailModel.length > 0
- property int thumbnailRadius: imageContainer.width / 2
-
- Loader {
- id: profilePictureLoader
- active: imageContainer.thumbnailActive
- asynchronous: true
- width: Theme.itemSizeExtraLarge
- height: Theme.itemSizeExtraLarge
- anchors.horizontalCenter: parent.horizontalCenter
- source: "../components/ProfilePictureList.qml"
- }
-
- ProfileThumbnail {
- id: chatPictureReplacement
- visible: !profilePictureLoader.active
- replacementStringHint: Functions.getUserName(settingsPage.userInformation)
- radius: imageContainer.thumbnailRadius
- anchors.horizontalCenter: parent.horizontalCenter
- width: Theme.itemSizeExtraLarge
- height: Theme.itemSizeExtraLarge
- }
- }
-
- Column {
- id: profilePictureButtonColumn
- spacing: Theme.paddingSmall
- width: parent.width / 2
-
- Button {
- id: addProfilePictureButton
- text: qsTr("Add Picture")
- anchors {
- horizontalCenter: parent.horizontalCenter
- }
- onClicked: {
- pageStack.push(imagePickerPage);
- }
- }
-
- Button {
- id: removeProfilePictureButton
- text: qsTr("Delete Picture")
- anchors {
- horizontalCenter: parent.horizontalCenter
- }
- onClicked: {
- var pictureIdForDeletion = imageContainer.thumbnailModel[profilePictureLoader.item.currentPictureIndex].id;
- Remorse.popupAction(settingsPage, qsTr("Deleting profile picture"), function() { tdLibWrapper.deleteProfilePhoto(pictureIdForDeletion) });
- }
- }
- }
-
- Column {
- id: uploadStatusColumn
- visible: !profilePictureButtonColumn.visible
- spacing: Theme.paddingMedium
- width: parent.width / 2
-
- Text {
- id: uploadingText
- font.pixelSize: Theme.fontSizeSmall
- text: qsTr("Uploading...")
- horizontalAlignment: Text.AlignHCenter
- color: Theme.secondaryColor
- width: parent.width
- }
-
- BusyIndicator {
- anchors.horizontalCenter: parent.horizontalCenter
- running: uploadStatusColumn.visible
- size: BusyIndicatorSize.Medium
- }
-
- }
-
- }
-
- Component {
- id: imagePickerPage
- ImagePickerPage {
- onSelectedContentPropertiesChanged: {
- profilePictureButtonColumn.visible = false;
- uploadInProgress = true;
- tdLibWrapper.setProfilePhoto(selectedContentProperties.filePath);
- }
- }
- }
-
- SectionHeader {
- horizontalAlignment: Text.AlignLeft
- text: qsTr("Privacy")
- }
-
- Grid {
- width: parent.width
- columns: landscapeLayout ? 2 : 1
- anchors.horizontalCenter: parent.horizontalCenter
-
- readonly property real columnWidth: width/columns
-
- Connections {
- target: tdLibWrapper
- onUserPrivacySettingUpdated: {
- Debug.log("Received updated privacy setting: " + setting + ":" + rule);
- switch (setting) {
- case TelegramAPI.SettingAllowChatInvites:
- allowChatInvitesComboBox.currentIndex = rule;
- break;
- case TelegramAPI.SettingAllowFindingByPhoneNumber:
- allowFindingByPhoneNumberComboBox.currentIndex = rule;
- break;
- case TelegramAPI.SettingShowLinkInForwardedMessages:
- showLinkInForwardedMessagesComboBox.currentIndex = rule;
- break;
- case TelegramAPI.SettingShowPhoneNumber:
- showPhoneNumberComboBox.currentIndex = rule;
- break;
- case TelegramAPI.SettingShowProfilePhoto:
- showProfilePhotoComboBox.currentIndex = rule;
- break;
- case TelegramAPI.SettingShowStatus:
- showStatusComboBox.currentIndex = rule;
- break;
- }
- }
- }
-
- ComboBox {
- id: allowChatInvitesComboBox
- width: parent.columnWidth
- label: qsTr("Allow chat invites")
- description: qsTr("Privacy setting for managing whether you can be invited to chats.")
- menu: ContextMenu {
- x: 0
- width: allowChatInvitesComboBox.width
-
- MenuItem {
- text: qsTr("Yes")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleAllowAll);
- }
- }
- MenuItem {
- text: qsTr("Your contacts only")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleAllowContacts);
- }
- }
- MenuItem {
- text: qsTr("No")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleRestrictAll);
- }
- }
- }
-
- Component.onCompleted: {
- currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites);
- }
- }
-
- ComboBox {
- id: allowFindingByPhoneNumberComboBox
- width: parent.columnWidth
- label: qsTr("Allow finding by phone number")
- description: qsTr("Privacy setting for managing whether you can be found by your phone number.")
- menu: ContextMenu {
- x: 0
- width: allowFindingByPhoneNumberComboBox.width
-
- MenuItem {
- text: qsTr("Yes")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber, TelegramAPI.RuleAllowAll);
- }
- }
- MenuItem {
- text: qsTr("Your contacts only")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber, TelegramAPI.RuleAllowContacts);
- }
- }
- }
-
- Component.onCompleted: {
- currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber);
- }
- }
-
- ComboBox {
- id: showLinkInForwardedMessagesComboBox
- width: parent.columnWidth
- label: qsTr("Show link in forwarded messages")
- description: qsTr("Privacy setting for managing whether a link to your account is included in forwarded messages.")
- menu: ContextMenu {
- x: 0
- width: showLinkInForwardedMessagesComboBox.width
-
- MenuItem {
- text: qsTr("Yes")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleAllowAll);
- }
- }
- MenuItem {
- text: qsTr("Your contacts only")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleAllowContacts);
- }
- }
- MenuItem {
- text: qsTr("No")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleRestrictAll);
- }
- }
- }
-
- Component.onCompleted: {
- currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages);
- }
- }
-
- ComboBox {
- id: showPhoneNumberComboBox
- width: parent.columnWidth
- label: qsTr("Show phone number")
- description: qsTr("Privacy setting for managing whether your phone number is visible.")
- menu: ContextMenu {
- x: 0
- width: showPhoneNumberComboBox.width
-
- MenuItem {
- text: qsTr("Yes")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleAllowAll);
- }
- }
- MenuItem {
- text: qsTr("Your contacts only")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleAllowContacts);
- }
- }
- MenuItem {
- text: qsTr("No")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleRestrictAll);
- }
- }
- }
-
- Component.onCompleted: {
- currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber);
- }
- }
-
- ComboBox {
- id: showProfilePhotoComboBox
- width: parent.columnWidth
- label: qsTr("Show profile photo")
- description: qsTr("Privacy setting for managing whether your profile photo is visible.")
- menu: ContextMenu {
- x: 0
- width: showProfilePhotoComboBox.width
-
- MenuItem {
- text: qsTr("Yes")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleAllowAll);
- }
- }
- MenuItem {
- text: qsTr("Your contacts only")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleAllowContacts);
- }
- }
- MenuItem {
- text: qsTr("No")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleRestrictAll);
- }
- }
- }
-
- Component.onCompleted: {
- currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto);
- }
- }
-
- ComboBox {
- id: showStatusComboBox
- width: parent.columnWidth
- label: qsTr("Show status")
- description: qsTr("Privacy setting for managing whether your online status is visible.")
- menu: ContextMenu {
- x: 0
- width: showStatusComboBox.width
-
- MenuItem {
- text: qsTr("Yes")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleAllowAll);
- }
- }
- MenuItem {
- text: qsTr("Your contacts only")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleAllowContacts);
- }
- }
- MenuItem {
- text: qsTr("No")
- onClicked: {
- tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleRestrictAll);
- }
- }
- }
-
- Component.onCompleted: {
- currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowStatus);
- }
- }
-
- }
-
- TextSwitch {
- checked: appSettings.allowInlineBotLocationAccess
- text: qsTr("Allow sending Location to inline bots")
- description: qsTr("Some inline bots request location data when using them")
- automaticCheck: false
- onClicked: {
- appSettings.allowInlineBotLocationAccess = !checked
- }
- }
-
- SectionHeader {
- text: qsTr("Behavior")
- }
-
- Grid {
- width: parent.width
- columns: landscapeLayout ? 2 : 1
-
- readonly property real columnWidth: width/columns
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.sendByEnter
- text: qsTr("Send message by enter")
- description: qsTr("Send your message by pressing the enter key")
- automaticCheck: false
- onClicked: {
- appSettings.sendByEnter = !checked
- }
- }
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.focusTextAreaOnChatOpen
- text: qsTr("Focus text input on chat open")
- description: qsTr("Focus the text input area when entering a chat")
- automaticCheck: false
- onClicked: {
- appSettings.focusTextAreaOnChatOpen = !checked
- }
- }
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.focusTextAreaAfterSend
- text: qsTr("Focus text input area after send")
- description: qsTr("Focus the text input area after sending a message")
- automaticCheck: false
- onClicked: {
- appSettings.focusTextAreaAfterSend = !checked
- }
- }
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.delayMessageRead
- text: qsTr("Delay before marking messages as read")
- description: qsTr("Fernschreiber will wait a bit before messages are marked as read")
- automaticCheck: false
- onClicked: {
- appSettings.delayMessageRead = !checked
- }
- }
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.useOpenWith
- text: qsTr("Open-with menu integration")
- description: qsTr("Integrate Fernschreiber into open-with menu of Sailfish OS")
- automaticCheck: false
- onClicked: {
- appSettings.useOpenWith = !checked
- }
- }
-
- ComboBox {
- id: feedbackComboBox
- width: parent.columnWidth
- label: qsTr("Notification feedback")
- description: qsTr("Use non-graphical feedback (sound, vibration) for notifications")
- menu: ContextMenu {
- id: feedbackMenu
- x: 0
- width: feedbackComboBox.width
-
- MenuItem {
- readonly property int value: AppSettings.NotificationFeedbackAll
- text: qsTr("All events")
- onClicked: {
- appSettings.notificationFeedback = value
- }
- }
- MenuItem {
- readonly property int value: AppSettings.NotificationFeedbackNew
- text: qsTr("Only new events")
- onClicked: {
- appSettings.notificationFeedback = value
- }
- }
- MenuItem {
- readonly property int value: AppSettings.NotificationFeedbackNone
- text: qsTr("None")
- onClicked: {
- appSettings.notificationFeedback = value
- }
- }
- }
-
- Component.onCompleted: updateFeedbackSelection()
-
- function updateFeedbackSelection() {
- var menuItems = feedbackMenu.children
- var n = menuItems.length
- for (var i=0; i 0
- automaticCheck: false
- onClicked: {
- appSettings.notificationTurnsDisplayOn = !checked
- }
- Behavior on height { SmoothedAnimation { duration: 200 } }
- }
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.notificationSoundsEnabled && enabled
- text: qsTr("Enable notification sounds")
- description: qsTr("When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.")
- enabled: appSettings.notificationFeedback !== AppSettings.NotificationFeedbackNone
- height: enabled ? implicitHeight: 0
- clip: height < implicitHeight
- visible: height > 0
- automaticCheck: false
- onClicked: {
- appSettings.notificationSoundsEnabled = !checked
- }
- Behavior on height { SmoothedAnimation { duration: 200 } }
- }
-
- }
-
- SectionHeader {
- text: qsTr("Appearance")
- }
-
- Grid {
- width: parent.width
- columns: landscapeLayout ? 2 : 1
-
- readonly property real columnWidth: width/columns
-
- TextSwitch {
- id: stickersAsEmojisTextSwitch
- width: parent.columnWidth
- checked: appSettings.showStickersAsEmojis
- text: qsTr("Show stickers as emojis")
- description: qsTr("Only display emojis instead of the actual stickers")
- automaticCheck: false
- onClicked: {
- appSettings.showStickersAsEmojis = !checked
- }
- }
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.showStickersAsImages
- text: qsTr("Show stickers as images")
- description: qsTr("Show background for stickers and align them centrally like images")
- automaticCheck: false
- onClicked: {
- appSettings.showStickersAsImages = !checked
- }
- enabled: !stickersAsEmojisTextSwitch.checked
- }
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.animateStickers
- text: qsTr("Animate stickers")
- automaticCheck: false
- onClicked: {
- appSettings.animateStickers = !checked
- }
- enabled: !stickersAsEmojisTextSwitch.checked
- }
- }
-
- SectionHeader {
- text: qsTr("Storage")
- }
-
- Grid {
- width: parent.width
- columns: landscapeLayout ? 2 : 1
-
- readonly property real columnWidth: width/columns
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.onlineOnlyMode
- text: qsTr("Enable online-only mode")
- description: qsTr("Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.")
- automaticCheck: false
- onClicked: {
- appSettings.onlineOnlyMode = !checked
- }
- }
-
- TextSwitch {
- width: parent.columnWidth
- checked: appSettings.storageOptimizer
- text: qsTr("Enable storage optimizer")
- automaticCheck: false
- onClicked: {
- appSettings.storageOptimizer = !checked
- }
- }
- }
-
- Item {
- width: 1
- height: Theme.paddingLarge // Some space at the bottom
+ Accordion {
+ flickable: settingsContainer
+ SettingsUserProfile { expanded: true; asynchronous: false }
+ SettingsPrivacy {}
+ SettingsBehavior {}
+ SettingsAppearance {}
+ SettingsStorage {}
}
}