diff --git a/src/qml/Settings/GeneralSettingsPage.qml b/src/qml/Settings/GeneralSettingsPage.qml
index b85e9953..35700f88 100644
--- a/src/qml/Settings/GeneralSettingsPage.qml
+++ b/src/qml/Settings/GeneralSettingsPage.qml
@@ -15,7 +15,6 @@ import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kasts 1.0
Kirigami.ScrollablePage {
- id: page
title: i18n("General Settings")
leftPadding: 0
@@ -28,7 +27,6 @@ Kirigami.ScrollablePage {
ColumnLayout {
spacing: 0
- width: page.width
MobileForm.FormCard {
Layout.fillWidth: true
diff --git a/src/qml/Settings/NetworkSettingsPage.qml b/src/qml/Settings/NetworkSettingsPage.qml
index da06401b..b64d0924 100644
--- a/src/qml/Settings/NetworkSettingsPage.qml
+++ b/src/qml/Settings/NetworkSettingsPage.qml
@@ -15,7 +15,6 @@ import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kasts 1.0
Kirigami.ScrollablePage {
- id: page
title: i18n("Network Settings")
leftPadding: 0
@@ -28,7 +27,6 @@ Kirigami.ScrollablePage {
ColumnLayout {
spacing: 0
- width: page.width
MobileForm.FormCard {
Layout.fillWidth: true
diff --git a/src/qml/Settings/StorageSettingsPage.qml b/src/qml/Settings/StorageSettingsPage.qml
index e724efb1..a363f049 100644
--- a/src/qml/Settings/StorageSettingsPage.qml
+++ b/src/qml/Settings/StorageSettingsPage.qml
@@ -16,7 +16,6 @@ import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kasts 1.0
Kirigami.ScrollablePage {
- id: page
title: i18n("Storage Settings")
leftPadding: 0
@@ -29,7 +28,6 @@ Kirigami.ScrollablePage {
ColumnLayout {
spacing: 0
- width: page.width
MobileForm.FormCard {
Layout.fillWidth: true
diff --git a/src/qml/Settings/SynchronizationSettingsPage.qml b/src/qml/Settings/SynchronizationSettingsPage.qml
index a585ac07..279a36bc 100644
--- a/src/qml/Settings/SynchronizationSettingsPage.qml
+++ b/src/qml/Settings/SynchronizationSettingsPage.qml
@@ -10,518 +10,570 @@ import QtQuick.Controls 2.14 as Controls
import QtQuick.Layouts 1.14
import org.kde.kirigami 2.19 as Kirigami
+import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kasts 1.0
Kirigami.ScrollablePage {
title: i18n("Synchronization Settings")
- Kirigami.FormLayout {
+ leftPadding: 0
+ rightPadding: 0
+ topPadding: Kirigami.Units.gridUnit
+ bottomPadding: Kirigami.Units.gridUnit
- Controls.Label {
- Kirigami.FormData.label: i18n("Current Status:")
- text: Sync.syncEnabled ? i18n("Logged into account \"%1\" on server \"%2\"", Sync.username, (Sync.provider == SyncUtils.GPodderNet && Sync.hostname == "") ? "gpodder.net" : Sync.hostname) : i18n("Syncing Disabled")
- wrapMode: Text.WordWrap
- }
+ Kirigami.Theme.colorSet: Kirigami.Theme.Window
+ Kirigami.Theme.inherit: false
- Controls.Label {
- Kirigami.FormData.label: i18n("Last full sync with server:")
- text: Sync.lastSuccessfulDownloadSync
- wrapMode: Text.WordWrap
- }
+ ColumnLayout {
+ spacing: 0
- Controls.Label {
- Kirigami.FormData.label: i18n("Last quick upload to sync server:")
- text: Sync.lastSuccessfulUploadSync
- wrapMode: Text.WordWrap
- }
+ MobileForm.FormCard {
+ Layout.fillWidth: true
- Controls.Button {
- text: i18n("Login")
- enabled: !Sync.syncEnabled
- onClicked: syncProviderOverlay.open()
- }
-
- Kirigami.Dialog {
- id: syncProviderOverlay
- preferredWidth: Kirigami.Units.gridUnit * 20
- standardButtons: Kirigami.Dialog.NoButton
-
- showCloseButton: true
-
- title: i18n("Select Sync Provider")
-
- ColumnLayout {
+ contentItem: ColumnLayout {
spacing: 0
- Repeater {
- focus: syncProviderOverlay.visible
+ MobileForm.FormTextDelegate {
+ id: accountStatus
+ text: i18n("Account")
+ description: Sync.syncEnabled ? i18n("Logged into account \"%1\" on server \"%2\"", Sync.username, (Sync.provider == SyncUtils.GPodderNet && Sync.hostname == "") ? "gpodder.net" : Sync.hostname) : i18n("Syncing disabled")
- model: ListModel {
- id: providerModel
- }
- Component.onCompleted: {
- providerModel.append({"name": i18n("gpodder.net"),
- "subtitle": i18n("Synchronize with official gpodder.net server"),
- "icon": "gpodder",
- "provider": Sync.GPodderNet});
- providerModel.append({"name": i18n("GPodder Nextcloud"),
- "subtitle": i18n("Synchronize with GPodder Nextcloud app"),
- "icon": "kaccounts-nextcloud",
- "provider": Sync.GPodderNextcloud});
- }
- delegate: Kirigami.BasicListItem {
- Layout.fillWidth: true
- label: model.name
- subtitle: model.subtitle
- icon: model.icon
- //highlighted: false
- iconSize: Kirigami.Units.gridUnit * 3
- Keys.onReturnPressed: clicked()
+ trailing: Controls.Button {
+ text: Sync.syncEnabled ? i18n("Logout") : i18n("Login")
onClicked: {
- Sync.provider = model.provider;
- syncProviderOverlay.close();
- syncLoginOverlay.open();
+ Sync.syncEnabled ? Sync.logout() : syncProviderOverlay.open();
+ }
+ }
+ }
+
+ MobileForm.FormDelegateSeparator { above: accountStatus; below: manualSync }
+
+ MobileForm.FormTextDelegate {
+ id: manualSync
+ text: i18n("Manually sync")
+
+ trailing: Controls.Button {
+ text: i18n("Sync Now")
+ enabled: Sync.syncEnabled
+ onClicked: {
+ syncFeedsAndEpisodes.run();
+ }
+ }
+ }
+
+ MobileForm.FormDelegateSeparator { above: manualSync; below: lastFullSync }
+
+ MobileForm.FormTextDelegate {
+ id: lastFullSync
+ text: i18n("Last full sync with server")
+ description: Sync.lastSuccessfulDownloadSync
+ }
+
+ MobileForm.FormDelegateSeparator { above: lastFullSync; below: lastQuickUpload }
+
+ MobileForm.FormTextDelegate {
+ id: lastQuickUpload
+ text: i18n("Last quick upload to sync server")
+ description: Sync.lastSuccessfulUploadSync
+ }
+ }
+ }
+
+ MobileForm.FormCard {
+ Layout.topMargin: Kirigami.Units.largeSpacing
+ Layout.fillWidth: true
+
+ contentItem: ColumnLayout {
+ spacing: 0
+
+ MobileForm.FormCardHeader {
+ title: i18n("Automatic syncing")
+ }
+
+ MobileForm.FormCheckDelegate {
+ enabled: Sync.syncEnabled
+ checked: SettingsManager.refreshOnStartup
+ text: i18n("Do full sync on startup")
+ onToggled: SettingsManager.refreshOnStartup = checked
+ }
+
+ MobileForm.FormCheckDelegate {
+ enabled: Sync.syncEnabled
+ checked: SettingsManager.syncWhenUpdatingFeeds
+ text: i18n("Do full sync when fetching podcasts")
+ onToggled: SettingsManager.syncWhenUpdatingFeeds = checked
+ }
+
+ MobileForm.FormCheckDelegate {
+ enabled: Sync.syncEnabled
+ checked: SettingsManager.syncWhenPlayerstateChanges
+ text: i18n("Upload episode play positions on play/pause toggle")
+ onToggled: SettingsManager.syncWhenPlayerstateChanges = checked
+ }
+ }
+ }
+
+ MobileForm.FormCard {
+ Layout.topMargin: Kirigami.Units.largeSpacing
+ Layout.fillWidth: true
+
+ contentItem: ColumnLayout {
+ spacing: 0
+
+ MobileForm.FormCardHeader {
+ title: i18n("Advanced options")
+ }
+
+ MobileForm.FormTextDelegate {
+ id: fetchAllEpisodeStates
+ text: i18n("Fetch all episode states from server")
+
+ trailing: Controls.Button {
+ text: i18n("Fetch")
+ enabled: Sync.syncEnabled
+ onClicked: {
+ forceSyncFeedsAndEpisodes.run();
+ }
+ }
+ }
+
+ MobileForm.FormDelegateSeparator { above: fetchAllEpisodeStates; below: fetchLocalEpisodeStates }
+
+ MobileForm.FormTextDelegate {
+ id: fetchLocalEpisodeStates
+ text: i18n("Fetch all local episode states from server")
+
+ trailing: Controls.Button {
+ enabled: Sync.syncEnabled
+ text: i18n("Push")
+ onClicked: {
+ syncPushAllStatesDialog.open();
}
}
}
}
}
+ }
- Kirigami.Dialog {
- id: syncLoginOverlay
- preferredWidth: Kirigami.Units.gridUnit * 25
- padding: Kirigami.Units.largeSpacing
+ // This item can be used to trigger an update of all feeds; it will open an
+ // overlay with options in case the operation is not allowed by the settings
+ ConnectionCheckAction {
+ id: syncFeedsAndEpisodes
- showCloseButton: true
- standardButtons: Controls.DialogButtonBox.Ok | Controls.DialogButtonBox.Cancel
- closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside
+ function action() {
+ Sync.doRegularSync();
+ }
+ }
- title: i18n("Sync Login Credentials")
+ // This item can be used to trigger an update of all feeds; it will open an
+ // overlay with options in case the operation is not allowed by the settings
+ ConnectionCheckAction {
+ id: forceSyncFeedsAndEpisodes
- onAccepted: {
- if (Sync.provider === Sync.GPodderNextcloud || customServerCheckBox.checked) {
- Sync.hostname = hostnameField.text;
- } else {
- Sync.hostname = ""
- }
- Sync.login(usernameField.text, passwordField.text);
- syncLoginOverlay.close();
+ function action() {
+ Sync.doForceSync();
+ }
+ }
+
+ Kirigami.Dialog {
+ id: syncPushAllStatesDialog
+ preferredWidth: Kirigami.Units.gridUnit * 25
+ padding: Kirigami.Units.largeSpacing
+
+ showCloseButton: true
+ standardButtons: Controls.DialogButtonBox.Ok | Controls.DialogButtonBox.Cancel
+ closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside
+
+ title: i18n("Push all local episode states to server?")
+
+ onAccepted: {
+ syncPushAllStatesDialog.close();
+ syncPushAllStates.run();
+ }
+ onRejected: syncPushAllStatesDialog.close();
+
+ RowLayout {
+ spacing: Kirigami.Units.largeSpacing
+ Kirigami.Icon {
+ Layout.preferredHeight: Kirigami.Units.gridUnit * 4
+ Layout.preferredWidth: Kirigami.Units.gridUnit * 4
+ source: Sync.provider === Sync.GPodderNextcloud ? "kaccounts-nextcloud" : "gpodder"
}
- onRejected: syncLoginOverlay.close();
-
- Column {
- spacing: Kirigami.Units.largeSpacing
- RowLayout {
- width: parent.width
- spacing: Kirigami.Units.largeSpacing
- Kirigami.Icon {
- Layout.preferredHeight: Kirigami.Units.gridUnit * 4
- Layout.preferredWidth: Kirigami.Units.gridUnit * 4
- source: Sync.provider === Sync.GPodderNextcloud ? "kaccounts-nextcloud" : "gpodder"
- }
- ColumnLayout {
- Layout.fillWidth: true
- Layout.fillHeight: true
- Kirigami.Heading {
- clip: true
- level: 2
- text: Sync.provider === Sync.GPodderNextcloud ? i18n("Sync with GPodder Nextcloud app") : i18n("Sync with gpodder.net service")
- }
- TextEdit {
- Layout.fillWidth: true
- readOnly: true
- wrapMode: Text.WordWrap
- textFormat: Text.RichText
- onLinkActivated: Qt.openUrlExternally(link)
- text: Sync.provider === Sync.GPodderNextcloud ?
- i18nc("argument is a weblink", "Sync with a Nextcloud server that has the GPodder Sync app installed: %1.
It is advised to manually create an app password for Kasts through the web interface and use those credentials." , "https://apps.nextcloud.com/apps/gpoddersync") :
- i18nc("argument is a weblink", "If you don't already have an account, you should first create one at %1", "https://gpodder.net")
- color: Kirigami.Theme.textColor
- }
- }
- }
- GridLayout {
- width: parent.width
- columns: 2
- rowSpacing: Kirigami.Units.smallSpacing
- columnSpacing: Kirigami.Units.smallSpacing
- Controls.Label {
- Layout.alignment: Qt.AlignRight
- text: i18n("Username:")
- }
- Controls.TextField {
- id: usernameField
- Layout.fillWidth: true
- text: Sync.username
- Keys.onReturnPressed: syncLoginOverlay.accepted();
- // focus: syncLoginOverlay.visible // disabled for now since it causes problem with virtual keyboard appearing at the same time as the overlay
- }
- Controls.Label {
- Layout.alignment: Qt.AlignRight
- text: i18n("Password:")
- }
- Controls.TextField {
- id: passwordField
- Layout.fillWidth: true
- echoMode: TextInput.Password
- text: Sync.password
- Keys.onReturnPressed: syncLoginOverlay.accepted();
- }
- Controls.CheckBox {
- id: customServerCheckBox
- Layout.row: 2
- Layout.column: 1
- visible: Sync.provider === Sync.GPodderNet
- checked: false
- text: i18n("Use custom server")
- }
- Controls.Label {
- visible: Sync.provider === Sync.GPodderNextcloud || customServerCheckBox.checked
- Layout.alignment: Qt.AlignRight
- text: i18n("Hostname:")
- }
- Controls.TextField {
- visible: Sync.provider === Sync.GPodderNextcloud || customServerCheckBox.checked
- id: hostnameField
- Layout.fillWidth: true
- placeholderText: Sync.provider === Sync.GPodderNet ? "https://gpodder.net" : "https://nextcloud.mydomain.org"
- text: Sync.hostname
- Keys.onReturnPressed: syncLoginOverlay.accepted();
- }
- }
+ TextEdit {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ readOnly: true
+ wrapMode: Text.WordWrap
+ text: i18n("Please note that pushing the playback state of all local episodes to the server might take a very long time and/or might overload the server. Also note that this action will overwrite all existing episode states on the server.\n\nContinue?")
+ color: Kirigami.Theme.textColor
+ Keys.onReturnPressed: accepted();
}
}
+ }
- Connections {
- target: Sync
- function onDeviceListReceived() {
- syncDeviceOverlay.open();
- syncDeviceOverlay.update();
- }
- function onLoginSucceeded() {
- if (Sync.provider === Sync.GPodderNextcloud) {
- firstSyncOverlay.open();
- }
- }
+ // This item can be used to trigger a push of all episode states to the server;
+ // it will open an overlay with options in case the operation is not allowed by the settings
+ ConnectionCheckAction {
+ id: syncPushAllStates
+
+ function action() {
+ Sync.doSyncPushAll();
}
+ }
- Kirigami.Dialog {
- id: syncDeviceOverlay
- preferredWidth: Kirigami.Units.gridUnit * 25
- padding: Kirigami.Units.largeSpacing
+ Kirigami.Dialog {
+ id: syncProviderOverlay
+ preferredWidth: Kirigami.Units.gridUnit * 20
+ standardButtons: Kirigami.Dialog.NoButton
- showCloseButton: true
+ showCloseButton: true
- title: i18n("Sync Device Settings")
+ title: i18n("Select Sync Provider")
- Column {
- spacing: Kirigami.Units.largeSpacing * 2
- Kirigami.Heading {
- level: 2
- text: i18n("Create a new device")
+ ColumnLayout {
+ spacing: 0
+
+ Repeater {
+ focus: syncProviderOverlay.visible
+
+ model: ListModel {
+ id: providerModel
}
- GridLayout {
- columns: 2
- width: parent.width
- Controls.Label {
- text: i18n("Device Name:")
- }
- Controls.TextField {
- id: deviceField
- Layout.fillWidth: true
- text: Sync.suggestedDevice
- Keys.onReturnPressed: createDeviceButton.clicked();
- // focus: syncDeviceOverlay.visible // disabled for now since it causes problem with virtual keyboard appearing at the same time as the overlay
- }
- Controls.Label {
- text: i18n("Device Description:")
- }
- Controls.TextField {
- id: deviceNameField
- Layout.fillWidth: true
- text: Sync.suggestedDeviceName
- Keys.onReturnPressed: createDeviceButton.clicked();
- }
- Controls.Label {
- text: i18n("Device Type:")
- }
- Controls.ComboBox {
- id: deviceTypeField
- textRole: "text"
- valueRole: "value"
- popup.z: 102 // popup has to go in front of OverlaySheet
- model: [{"text": i18n("other"), "value": "other"},
- {"text": i18n("desktop"), "value": "desktop"},
- {"text": i18n("laptop"), "value": "laptop"},
- {"text": i18n("server"), "value": "server"},
- {"text": i18n("mobile"), "value": "mobile"}]
- }
+ Component.onCompleted: {
+ providerModel.append({"name": i18n("gpodder.net"),
+ "subtitle": i18n("Synchronize with official gpodder.net server"),
+ "icon": "gpodder",
+ "provider": Sync.GPodderNet});
+ providerModel.append({"name": i18n("GPodder Nextcloud"),
+ "subtitle": i18n("Synchronize with GPodder Nextcloud app"),
+ "icon": "kaccounts-nextcloud",
+ "provider": Sync.GPodderNextcloud});
}
- Controls.Button {
- id: createDeviceButton
- text: i18n("Create Device")
- icon.name: "list-add"
+ delegate: Kirigami.BasicListItem {
+ Layout.fillWidth: true
+ label: model.name
+ subtitle: model.subtitle
+ icon: model.icon
+ //highlighted: false
+ iconSize: Kirigami.Units.gridUnit * 3
+ Keys.onReturnPressed: clicked()
onClicked: {
- Sync.registerNewDevice(deviceField.text, deviceNameField.text, deviceTypeField.currentValue);
- syncDeviceOverlay.close();
+ Sync.provider = model.provider;
+ syncProviderOverlay.close();
+ syncLoginOverlay.open();
}
}
- ListView {
- id: deviceList
- width: parent.width
- height: contentItem.childrenRect.height
- visible: deviceListModel.count !== 0
+ }
+ }
+ }
- header: Kirigami.Heading {
- topPadding: Kirigami.Units.gridUnit
- bottomPadding: Kirigami.Units.largeSpacing
+ Kirigami.Dialog {
+ id: syncLoginOverlay
+ preferredWidth: Kirigami.Units.gridUnit * 25
+ padding: Kirigami.Units.largeSpacing
+
+ showCloseButton: true
+ standardButtons: Controls.DialogButtonBox.Ok | Controls.DialogButtonBox.Cancel
+ closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside
+
+ title: i18n("Sync Login Credentials")
+
+ onAccepted: {
+ if (Sync.provider === Sync.GPodderNextcloud || customServerCheckBox.checked) {
+ Sync.hostname = hostnameField.text;
+ } else {
+ Sync.hostname = ""
+ }
+ Sync.login(usernameField.text, passwordField.text);
+ syncLoginOverlay.close();
+ }
+ onRejected: syncLoginOverlay.close();
+
+ Column {
+ spacing: Kirigami.Units.largeSpacing
+ RowLayout {
+ width: parent.width
+ spacing: Kirigami.Units.largeSpacing
+ Kirigami.Icon {
+ Layout.preferredHeight: Kirigami.Units.gridUnit * 4
+ Layout.preferredWidth: Kirigami.Units.gridUnit * 4
+ source: Sync.provider === Sync.GPodderNextcloud ? "kaccounts-nextcloud" : "gpodder"
+ }
+ ColumnLayout {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Kirigami.Heading {
+ clip: true
level: 2
- text: i18n("or select an existing device")
+ text: Sync.provider === Sync.GPodderNextcloud ? i18n("Sync with GPodder Nextcloud app") : i18n("Sync with gpodder.net service")
}
- model: ListModel {
- id: deviceListModel
- }
-
- delegate: Kirigami.BasicListItem {
- label: model.device.caption
- highlighted: false
- icon: model.device.type == "desktop" ? "computer" :
- model.device.type == "laptop" ? "computer-laptop" :
- model.device.type == "server" ? "network-server-database" :
- model.device.type == "mobile" ? "smartphone" :
- "emblem-music-symbolic"
- onClicked: {
- syncDeviceOverlay.close();
- Sync.device = model.device.id;
- Sync.deviceName = model.device.caption;
- Sync.syncEnabled = true;
- syncGroupOverlay.open();
- }
+ TextEdit {
+ Layout.fillWidth: true
+ readOnly: true
+ wrapMode: Text.WordWrap
+ textFormat: Text.RichText
+ onLinkActivated: Qt.openUrlExternally(link)
+ text: Sync.provider === Sync.GPodderNextcloud ?
+ i18nc("argument is a weblink", "Sync with a Nextcloud server that has the GPodder Sync app installed: %1.
It is advised to manually create an app password for Kasts through the web interface and use those credentials." , "https://apps.nextcloud.com/apps/gpoddersync") :
+ i18nc("argument is a weblink", "If you don't already have an account, you should first create one at %1", "https://gpodder.net")
+ color: Kirigami.Theme.textColor
}
}
}
-
- function update() {
- deviceListModel.clear();
- for (var index in Sync.deviceList) {
- deviceListModel.append({"device": Sync.deviceList[index]});
+ GridLayout {
+ width: parent.width
+ columns: 2
+ rowSpacing: Kirigami.Units.smallSpacing
+ columnSpacing: Kirigami.Units.smallSpacing
+ Controls.Label {
+ Layout.alignment: Qt.AlignRight
+ text: i18n("Username:")
}
- }
- }
-
- Connections {
- target: Sync
- function onDeviceCreated() {
- syncGroupOverlay.open();
- }
- }
-
- Kirigami.Dialog {
- id: syncGroupOverlay
- preferredWidth: Kirigami.Units.gridUnit * 25
- padding: Kirigami.Units.largeSpacing
-
- showCloseButton: true
- standardButtons: Controls.DialogButtonBox.Ok | Controls.DialogButtonBox.Cancel
- closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside
-
- title: i18n("Device Sync Settings")
-
- onAccepted: {
- Sync.linkUpAllDevices();
- syncGroupOverlay.close();
- }
- onRejected: {
- syncGroupOverlay.close();
- }
-
- RowLayout {
- spacing: Kirigami.Units.largeSpacing
- Kirigami.Icon {
- Layout.preferredHeight: Kirigami.Units.gridUnit * 4
- Layout.preferredWidth: Kirigami.Units.gridUnit * 4
- source: "gpodder"
- }
- TextEdit {
+ Controls.TextField {
+ id: usernameField
Layout.fillWidth: true
- Layout.fillHeight: true
- readOnly: true
- wrapMode: Text.WordWrap
- text: i18n("Should all podcast subscriptions on this gpodder.net account be synced across all devices?\nIf you don't know what this means, you should probably select \"Ok\".")
- color: Kirigami.Theme.textColor
- Keys.onReturnPressed: accepted();
+ text: Sync.username
+ Keys.onReturnPressed: syncLoginOverlay.accepted();
+ // focus: syncLoginOverlay.visible // disabled for now since it causes problem with virtual keyboard appearing at the same time as the overlay
}
- }
-
- onVisibleChanged: {
- if (!visible) {
- firstSyncOverlay.open();
+ Controls.Label {
+ Layout.alignment: Qt.AlignRight
+ text: i18n("Password:")
}
- }
- }
-
- Kirigami.Dialog {
- id: firstSyncOverlay
- preferredWidth: Kirigami.Units.gridUnit * 16
- padding: Kirigami.Units.largeSpacing
-
- showCloseButton: true
- standardButtons: Controls.DialogButtonBox.Ok | Controls.DialogButtonBox.Cancel
- closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside
-
- title: i18n("Sync Now?")
-
- onAccepted: {
- firstSyncOverlay.close();
- Sync.doRegularSync();
- }
- onRejected: firstSyncOverlay.close();
-
- RowLayout {
- spacing: Kirigami.Units.largeSpacing
- Kirigami.Icon {
- Layout.preferredHeight: Kirigami.Units.gridUnit * 4
- Layout.preferredWidth: Kirigami.Units.gridUnit * 4
- source: Sync.provider === Sync.GPodderNextcloud ? "kaccounts-nextcloud" : "gpodder"
- }
- TextEdit {
+ Controls.TextField {
+ id: passwordField
Layout.fillWidth: true
- Layout.fillHeight: true
- readOnly: true
- wrapMode: Text.WordWrap
- text: i18n("Perform a first sync now?")
- color: Kirigami.Theme.textColor
- Keys.onReturnPressed: accepted();
+ echoMode: TextInput.Password
+ text: Sync.password
+ Keys.onReturnPressed: syncLoginOverlay.accepted();
}
- }
- }
-
- Controls.Button {
- text: i18n("Logout")
- enabled: Sync.syncEnabled
- onClicked: {
- Sync.logout();
- }
- }
-
- Controls.CheckBox {
- Kirigami.FormData.label: i18n("Automatic Syncing:")
- enabled: Sync.syncEnabled
- checked: SettingsManager.refreshOnStartup
- text: i18n("Do full sync on startup")
- onToggled: SettingsManager.refreshOnStartup = checked
- }
-
- Controls.CheckBox {
- enabled: Sync.syncEnabled
- checked: SettingsManager.syncWhenUpdatingFeeds
- text: i18n("Do full sync when fetching podcasts")
- onToggled: SettingsManager.syncWhenUpdatingFeeds = checked
- }
-
- Controls.CheckBox {
- enabled: Sync.syncEnabled
- checked: SettingsManager.syncWhenPlayerstateChanges
- text: i18n("Upload episode play positions on play/pause toggle")
- onToggled: SettingsManager.syncWhenPlayerstateChanges = checked
- }
-
- Controls.Button {
- Kirigami.FormData.label: i18n("Manual Syncing:")
- text: i18n("Sync Now")
- enabled: Sync.syncEnabled
- onClicked: {
- syncFeedsAndEpisodes.run();
- }
- }
-
- // This item can be used to trigger an update of all feeds; it will open an
- // overlay with options in case the operation is not allowed by the settings
- ConnectionCheckAction {
- id: syncFeedsAndEpisodes
-
- function action() {
- Sync.doRegularSync();
- }
- }
-
- Kirigami.Heading {
- Kirigami.FormData.isSection: true
- text: i18n("Advanced Options")
- }
-
- Controls.Button {
- text: i18n("Fetch all episode states from server")
- enabled: Sync.syncEnabled
- onClicked: {
- forceSyncFeedsAndEpisodes.run();
- }
- }
-
- // This item can be used to trigger an update of all feeds; it will open an
- // overlay with options in case the operation is not allowed by the settings
- ConnectionCheckAction {
- id: forceSyncFeedsAndEpisodes
-
- function action() {
- Sync.doForceSync();
- }
- }
-
- Controls.Button {
- enabled: Sync.syncEnabled
- text: i18n("Push all local episode states to server")
- onClicked: {
- syncPushAllStatesDialog.open();
- }
- }
-
- Kirigami.Dialog {
- id: syncPushAllStatesDialog
- preferredWidth: Kirigami.Units.gridUnit * 25
- padding: Kirigami.Units.largeSpacing
-
- showCloseButton: true
- standardButtons: Controls.DialogButtonBox.Ok | Controls.DialogButtonBox.Cancel
- closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside
-
- title: i18n("Push all local episode states to server?")
-
- onAccepted: {
- syncPushAllStatesDialog.close();
- syncPushAllStates.run();
- }
- onRejected: syncPushAllStatesDialog.close();
-
- RowLayout {
- spacing: Kirigami.Units.largeSpacing
- Kirigami.Icon {
- Layout.preferredHeight: Kirigami.Units.gridUnit * 4
- Layout.preferredWidth: Kirigami.Units.gridUnit * 4
- source: Sync.provider === Sync.GPodderNextcloud ? "kaccounts-nextcloud" : "gpodder"
+ Controls.CheckBox {
+ id: customServerCheckBox
+ Layout.row: 2
+ Layout.column: 1
+ visible: Sync.provider === Sync.GPodderNet
+ checked: false
+ text: i18n("Use custom server")
}
- TextEdit {
+ Controls.Label {
+ visible: Sync.provider === Sync.GPodderNextcloud || customServerCheckBox.checked
+ Layout.alignment: Qt.AlignRight
+ text: i18n("Hostname:")
+ }
+ Controls.TextField {
+ visible: Sync.provider === Sync.GPodderNextcloud || customServerCheckBox.checked
+ id: hostnameField
Layout.fillWidth: true
- Layout.fillHeight: true
- readOnly: true
- wrapMode: Text.WordWrap
- text: i18n("Please note that pushing the playback state of all local episodes to the server might take a very long time and/or might overload the server. Also note that this action will overwrite all existing episode states on the server.\n\nContinue?")
- color: Kirigami.Theme.textColor
- Keys.onReturnPressed: accepted();
+ placeholderText: Sync.provider === Sync.GPodderNet ? "https://gpodder.net" : "https://nextcloud.mydomain.org"
+ text: Sync.hostname
+ Keys.onReturnPressed: syncLoginOverlay.accepted();
+ }
+ }
+ }
+ }
+
+ Connections {
+ target: Sync
+ function onDeviceListReceived() {
+ syncDeviceOverlay.open();
+ syncDeviceOverlay.update();
+ }
+ function onLoginSucceeded() {
+ if (Sync.provider === Sync.GPodderNextcloud) {
+ firstSyncOverlay.open();
+ }
+ }
+ }
+
+ Kirigami.Dialog {
+ id: syncDeviceOverlay
+ preferredWidth: Kirigami.Units.gridUnit * 25
+ padding: Kirigami.Units.largeSpacing
+
+ showCloseButton: true
+
+ title: i18n("Sync Device Settings")
+
+ Column {
+ spacing: Kirigami.Units.largeSpacing * 2
+ Kirigami.Heading {
+ level: 2
+ text: i18n("Create a new device")
+ }
+ GridLayout {
+ columns: 2
+ width: parent.width
+ Controls.Label {
+ text: i18n("Device Name:")
+ }
+ Controls.TextField {
+ id: deviceField
+ Layout.fillWidth: true
+ text: Sync.suggestedDevice
+ Keys.onReturnPressed: createDeviceButton.clicked();
+ // focus: syncDeviceOverlay.visible // disabled for now since it causes problem with virtual keyboard appearing at the same time as the overlay
+ }
+ Controls.Label {
+ text: i18n("Device Description:")
+ }
+ Controls.TextField {
+ id: deviceNameField
+ Layout.fillWidth: true
+ text: Sync.suggestedDeviceName
+ Keys.onReturnPressed: createDeviceButton.clicked();
+ }
+ Controls.Label {
+ text: i18n("Device Type:")
+ }
+ Controls.ComboBox {
+ id: deviceTypeField
+ textRole: "text"
+ valueRole: "value"
+ popup.z: 102 // popup has to go in front of OverlaySheet
+ model: [{"text": i18n("other"), "value": "other"},
+ {"text": i18n("desktop"), "value": "desktop"},
+ {"text": i18n("laptop"), "value": "laptop"},
+ {"text": i18n("server"), "value": "server"},
+ {"text": i18n("mobile"), "value": "mobile"}]
+ }
+ }
+ Controls.Button {
+ id: createDeviceButton
+ text: i18n("Create Device")
+ icon.name: "list-add"
+ onClicked: {
+ Sync.registerNewDevice(deviceField.text, deviceNameField.text, deviceTypeField.currentValue);
+ syncDeviceOverlay.close();
+ }
+ }
+ ListView {
+ id: deviceList
+ width: parent.width
+ height: contentItem.childrenRect.height
+ visible: deviceListModel.count !== 0
+
+ header: Kirigami.Heading {
+ topPadding: Kirigami.Units.gridUnit
+ bottomPadding: Kirigami.Units.largeSpacing
+ level: 2
+ text: i18n("or select an existing device")
+ }
+ model: ListModel {
+ id: deviceListModel
+ }
+
+ delegate: Kirigami.BasicListItem {
+ label: model.device.caption
+ highlighted: false
+ icon: model.device.type == "desktop" ? "computer" :
+ model.device.type == "laptop" ? "computer-laptop" :
+ model.device.type == "server" ? "network-server-database" :
+ model.device.type == "mobile" ? "smartphone" :
+ "emblem-music-symbolic"
+ onClicked: {
+ syncDeviceOverlay.close();
+ Sync.device = model.device.id;
+ Sync.deviceName = model.device.caption;
+ Sync.syncEnabled = true;
+ syncGroupOverlay.open();
+ }
}
}
}
- // This item can be used to trigger a push of all episode states to the server;
- // it will open an overlay with options in case the operation is not allowed by the settings
- ConnectionCheckAction {
- id: syncPushAllStates
+ function update() {
+ deviceListModel.clear();
+ for (var index in Sync.deviceList) {
+ deviceListModel.append({"device": Sync.deviceList[index]});
+ }
+ }
+ }
- function action() {
- Sync.doSyncPushAll();
+ Connections {
+ target: Sync
+ function onDeviceCreated() {
+ syncGroupOverlay.open();
+ }
+ }
+
+ Kirigami.Dialog {
+ id: syncGroupOverlay
+ preferredWidth: Kirigami.Units.gridUnit * 25
+ padding: Kirigami.Units.largeSpacing
+
+ showCloseButton: true
+ standardButtons: Controls.DialogButtonBox.Ok | Controls.DialogButtonBox.Cancel
+ closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside
+
+ title: i18n("Device Sync Settings")
+
+ onAccepted: {
+ Sync.linkUpAllDevices();
+ syncGroupOverlay.close();
+ }
+ onRejected: {
+ syncGroupOverlay.close();
+ }
+
+ RowLayout {
+ spacing: Kirigami.Units.largeSpacing
+ Kirigami.Icon {
+ Layout.preferredHeight: Kirigami.Units.gridUnit * 4
+ Layout.preferredWidth: Kirigami.Units.gridUnit * 4
+ source: "gpodder"
+ }
+ TextEdit {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ readOnly: true
+ wrapMode: Text.WordWrap
+ text: i18n("Should all podcast subscriptions on this gpodder.net account be synced across all devices?\nIf you don't know what this means, you should probably select \"Ok\".")
+ color: Kirigami.Theme.textColor
+ Keys.onReturnPressed: accepted();
}
}
+ onVisibleChanged: {
+ if (!visible) {
+ firstSyncOverlay.open();
+ }
+ }
+ }
+
+ Kirigami.Dialog {
+ id: firstSyncOverlay
+ preferredWidth: Kirigami.Units.gridUnit * 16
+ padding: Kirigami.Units.largeSpacing
+
+ showCloseButton: true
+ standardButtons: Controls.DialogButtonBox.Ok | Controls.DialogButtonBox.Cancel
+ closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside
+
+ title: i18n("Sync Now?")
+
+ onAccepted: {
+ firstSyncOverlay.close();
+ Sync.doRegularSync();
+ }
+ onRejected: firstSyncOverlay.close();
+
+ RowLayout {
+ spacing: Kirigami.Units.largeSpacing
+ Kirigami.Icon {
+ Layout.preferredHeight: Kirigami.Units.gridUnit * 4
+ Layout.preferredWidth: Kirigami.Units.gridUnit * 4
+ source: Sync.provider === Sync.GPodderNextcloud ? "kaccounts-nextcloud" : "gpodder"
+ }
+ TextEdit {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ readOnly: true
+ wrapMode: Text.WordWrap
+ text: i18n("Perform a first sync now?")
+ color: Kirigami.Theme.textColor
+ Keys.onReturnPressed: accepted();
+ }
+ }
}
}