From c6a63cf959cf417d365e4f9ae9a20ce73a29abea Mon Sep 17 00:00:00 2001 From: Lucas Scharenbroch Date: Mon, 12 Feb 2024 00:29:16 -0600 Subject: [PATCH] Add log-in button to preferences screen (#2994) * Add log-in button to preferences screen * Fix to python to conform to linter * Add translations for log in/out * Clean up whitespace/naming * Move translations from python to qt forms * Remove sync-not-enabled text on prefs screen * Add my name to about.py * Add "sync now?" dialog upon successful login * Close preferences dialog before syncing * Yet another Qt 6.6.1 focus fix (dae) Like 9364dad49ad0676a510554c980adfb363e8f70b7 --- ftl/core/preferences.ftl | 3 ++- ftl/core/sync.ftl | 1 + qt/aqt/about.py | 1 + qt/aqt/forms/preferences.ui | 30 +++++++++++++++-------- qt/aqt/preferences.py | 49 +++++++++++++++++++++++++++---------- qt/aqt/sync.py | 1 + 6 files changed, 61 insertions(+), 24 deletions(-) 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: