diff --git a/ftl/core/preferences.ftl b/ftl/core/preferences.ftl
index 1c694a6a9..75cd4cde1 100644
--- a/ftl/core/preferences.ftl
+++ b/ftl/core/preferences.ftl
@@ -24,8 +24,9 @@ preferences-show-play-buttons-on-cards-with = Show play buttons on cards with au
preferences-show-remaining-card-count = Show remaining card count
preferences-some-settings-will-take-effect-after = Some settings will take effect after you restart Anki.
preferences-tab-synchronisation = Synchronization
-preferences-synchronizationnot-currently-enabled-click-the-sync = Synchronization
Not currently enabled; click the sync button in the main window to enable.
preferences-synchronize-audio-and-images-too = Synchronize audio and images too
+preferences-not-logged-in = Not currently logged in to AnkiWeb.
+preferences-login-successful-sync-now = Log-in successful. Save preferences and sync now?
preferences-timebox-time-limit = Timebox time limit
preferences-user-interface-size = User interface size
preferences-when-adding-default-to-current-deck = When adding, default to current deck
diff --git a/ftl/core/sync.ftl b/ftl/core/sync.ftl
index 32aafa930..3240fc0ec 100644
--- a/ftl/core/sync.ftl
+++ b/ftl/core/sync.ftl
@@ -63,5 +63,6 @@ sync-syncing = Syncing...
sync-checking = Checking...
sync-connecting = Connecting...
sync-added-updated-count = Added/modified: { $up }↑ { $down }↓
+sync-log-in-button = Log In
sync-log-out-button = Log Out
sync-collection-complete = Collection sync complete.
diff --git a/qt/aqt/about.py b/qt/aqt/about.py
index a41e0af73..8847b7d20 100644
--- a/qt/aqt/about.py
+++ b/qt/aqt/about.py
@@ -189,6 +189,7 @@ def show(mw: aqt.AnkiQt) -> QDialog:
"Gustavo Sales",
"Akash Reddy",
"Marko Sisovic",
+ "Lucas Scharenbroch",
)
)
diff --git a/qt/aqt/forms/preferences.ui b/qt/aqt/forms/preferences.ui
index 9a9673a0b..a3145772d 100644
--- a/qt/aqt/forms/preferences.ui
+++ b/qt/aqt/forms/preferences.ui
@@ -725,13 +725,6 @@
-
-
-
-
-
-
-
-
-
-
@@ -783,7 +776,7 @@
-
-
+
0
@@ -791,7 +784,23 @@
- LOGOUT
+ sync_log_out_button
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ sync_log_in_button
false
@@ -1098,7 +1107,8 @@
fullSync
network_timeout
media_log
- syncDeauth
+ syncLogout
+ syncLogin
custom_sync_url
minutes_between_backups
daily_backups
diff --git a/qt/aqt/preferences.py b/qt/aqt/preferences.py
index b8ddfa3b3..b1c35917d 100644
--- a/qt/aqt/preferences.py
+++ b/qt/aqt/preferences.py
@@ -1,6 +1,8 @@
# Copyright: Ankitects Pty Ltd and contributors
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
+from __future__ import annotations
+
import functools
import re
@@ -13,9 +15,11 @@ from aqt import AnkiQt
from aqt.operations.collection import set_preferences
from aqt.profiles import VideoDriver
from aqt.qt import *
+from aqt.sync import sync_login
from aqt.theme import Theme
from aqt.utils import (
HelpPage,
+ askUser,
disable_help_button,
is_win,
openHelp,
@@ -73,6 +77,9 @@ class Preferences(QDialog):
line_edit.setPlaceholderText(tr.preferences_shortcut_placeholder())
def accept(self) -> None:
+ self.accept_with_callback()
+
+ def accept_with_callback(self, callback: Callable[[], None] | None = None) -> None:
# avoid exception if main window is already closed
if not self.mw.col:
return
@@ -84,6 +91,9 @@ class Preferences(QDialog):
self.done(0)
aqt.dialogs.markClosed("Preferences")
+ if callback:
+ callback()
+
self.update_collection(after_collection_update)
def reject(self) -> None:
@@ -181,24 +191,33 @@ class Preferences(QDialog):
self.form.syncOnProgramOpen.setChecked(self.mw.pm.auto_syncing_enabled())
self.form.syncMedia.setChecked(self.mw.pm.media_syncing_enabled())
self.form.autoSyncMedia.setChecked(self.mw.pm.auto_sync_media_minutes() != 0)
- if not self.prof.get("syncKey"):
- self._hide_sync_auth_settings()
- else:
- self.form.syncUser.setText(self.prof.get("syncUser", ""))
- qconnect(self.form.syncDeauth.clicked, self.sync_logout)
- self.form.syncDeauth.setText(tr.sync_log_out_button())
self.form.custom_sync_url.setText(self.mw.pm.custom_sync_url())
self.form.network_timeout.setValue(self.mw.pm.network_timeout())
+ self.update_login_status()
+ qconnect(self.form.syncLogout.clicked, self.sync_logout)
+ qconnect(self.form.syncLogin.clicked, self.sync_login)
+
+ def update_login_status(self) -> None:
+ if not self.prof.get("syncKey"):
+ self.form.syncUser.setText(tr.preferences_not_logged_in())
+ self.form.syncLogin.setVisible(True)
+ self.form.syncLogout.setVisible(False)
+ else:
+ self.form.syncUser.setText(self.prof.get("syncUser", ""))
+ self.form.syncLogin.setVisible(False)
+ self.form.syncLogout.setVisible(True)
+
def on_media_log(self) -> None:
self.mw.media_syncer.show_sync_log()
- def _hide_sync_auth_settings(self) -> None:
- self.form.syncDeauth.setVisible(False)
- self.form.syncUser.setText("")
- self.form.syncLabel.setText(
- tr.preferences_synchronizationnot_currently_enabled_click_the_sync()
- )
+ def sync_login(self) -> None:
+ def on_success():
+ if self.prof.get("syncKey"):
+ self.update_login_status()
+ self.confirm_sync_after_login()
+
+ sync_login(self.mw, on_success)
def sync_logout(self) -> None:
if self.mw.media_syncer.is_syncing():
@@ -206,7 +225,11 @@ class Preferences(QDialog):
return
self.prof["syncKey"] = None
self.mw.col.media.force_resync()
- self._hide_sync_auth_settings()
+ self.update_login_status()
+
+ def confirm_sync_after_login(self) -> None:
+ if askUser(tr.preferences_login_successful_sync_now()):
+ self.accept_with_callback(self.mw.on_sync_button_clicked)
def update_network(self) -> None:
self.prof["autoSync"] = self.form.syncOnProgramOpen.isChecked()
diff --git a/qt/aqt/sync.py b/qt/aqt/sync.py
index af142d818..36e1d5a19 100644
--- a/qt/aqt/sync.py
+++ b/qt/aqt/sync.py
@@ -357,6 +357,7 @@ def get_id_and_pass_from_user(
vbox.addWidget(bb)
diag.setLayout(vbox)
diag.show()
+ user.setFocus()
accepted = diag.exec()
if not accepted: