mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
Tweaks to add-on startup failure screen / update checks
- Add a Check for Updates button to the screen - Make the update list screen non-modal, so that other modal pop-ups at startup don't leave the user stuck - When manually checking for updates, update Anki's last check time
This commit is contained in:
parent
9a027a8c48
commit
865296254a
3 changed files with 58 additions and 31 deletions
|
@ -8,8 +8,10 @@ addons-failed-to-load2 =
|
||||||
The following add-ons failed to load:
|
The following add-ons failed to load:
|
||||||
{ $addons }
|
{ $addons }
|
||||||
|
|
||||||
Use Tools>Add-ons to check for updates. For add-ons that don't have
|
They may need to be updated to support this version of Anki. Click the { addons-check-for-updates } button
|
||||||
an update available, you can disable or delete the add-on to prevent this
|
to see if any updates are available.
|
||||||
|
|
||||||
|
For add-ons that don't have an update available, you can disable or delete the add-on to prevent this
|
||||||
message from appearing.
|
message from appearing.
|
||||||
addons-startup-failed = Add-on Startup Failed
|
addons-startup-failed = Add-on Startup Failed
|
||||||
# Shown in the add-on configuration screen (Tools>Add-ons>Config), in the title bar
|
# Shown in the add-on configuration screen (Tools>Add-ons>Config), in the title bar
|
||||||
|
|
|
@ -256,18 +256,33 @@ class AddonManager:
|
||||||
)
|
)
|
||||||
txt = f"# {tr.addons_startup_failed()}\n{error}"
|
txt = f"# {tr.addons_startup_failed()}\n{error}"
|
||||||
html2 = markdown.markdown(txt)
|
html2 = markdown.markdown(txt)
|
||||||
print(html2)
|
box: QDialogButtonBox
|
||||||
(diag, _) = showText(
|
(diag, box) = showText(
|
||||||
html2,
|
html2,
|
||||||
type="html",
|
type="html",
|
||||||
copyBtn=True,
|
copyBtn=True,
|
||||||
run=False,
|
run=False,
|
||||||
)
|
)
|
||||||
|
but = box.addButton(
|
||||||
|
tr.addons_check_for_updates(), QDialogButtonBox.ButtonRole.ActionRole
|
||||||
|
)
|
||||||
|
but.clicked.connect(self.check_for_updates_after_load_failure)
|
||||||
from aqt import mw
|
from aqt import mw
|
||||||
|
|
||||||
# calling show immediately appears to crash
|
# calling show immediately appears to crash
|
||||||
mw.progress.single_shot(1000, diag.show)
|
mw.progress.single_shot(1000, diag.show)
|
||||||
|
|
||||||
|
def check_for_updates_after_load_failure(self) -> None:
|
||||||
|
from aqt import mw
|
||||||
|
|
||||||
|
tooltip(tr.addons_checking())
|
||||||
|
|
||||||
|
def on_done(log: list[DownloadLogEntry]) -> None:
|
||||||
|
if not log:
|
||||||
|
tooltip(tr.addons_no_updates_available())
|
||||||
|
|
||||||
|
mw.check_for_addon_updates(by_user=True, on_done=on_done)
|
||||||
|
|
||||||
def onAddonsDialog(self) -> None:
|
def onAddonsDialog(self) -> None:
|
||||||
aqt.dialogs.open("AddonsDialog", self)
|
aqt.dialogs.open("AddonsDialog", self)
|
||||||
|
|
||||||
|
@ -1326,12 +1341,14 @@ class ChooseAddonsToUpdateList(QListWidget):
|
||||||
|
|
||||||
|
|
||||||
class ChooseAddonsToUpdateDialog(QDialog):
|
class ChooseAddonsToUpdateDialog(QDialog):
|
||||||
|
_on_done: Callable[[list[int]], None]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, parent: QWidget, mgr: AddonManager, updated_addons: list[AddonInfo]
|
self, parent: QWidget, mgr: AddonManager, updated_addons: list[AddonInfo]
|
||||||
) -> None:
|
) -> None:
|
||||||
QDialog.__init__(self, parent)
|
QDialog.__init__(self, parent)
|
||||||
self.setWindowTitle(tr.addons_choose_update_window_title())
|
self.setWindowTitle(tr.addons_choose_update_window_title())
|
||||||
self.setWindowModality(Qt.WindowModality.WindowModal)
|
self.setWindowModality(Qt.WindowModality.NonModal)
|
||||||
self.mgr = mgr
|
self.mgr = mgr
|
||||||
self.updated_addons = updated_addons
|
self.updated_addons = updated_addons
|
||||||
self.setup()
|
self.setup()
|
||||||
|
@ -1358,15 +1375,15 @@ class ChooseAddonsToUpdateDialog(QDialog):
|
||||||
layout.addWidget(button_box)
|
layout.addWidget(button_box)
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
def ask(self) -> list[int]:
|
def ask(self, on_done: Callable[[list[int]], None]) -> None:
|
||||||
"Returns a list of selected addons' ids"
|
self._on_done = on_done
|
||||||
ret = self.exec()
|
self.show()
|
||||||
|
|
||||||
|
def accept(self) -> None:
|
||||||
saveGeom(self, "addonsChooseUpdate")
|
saveGeom(self, "addonsChooseUpdate")
|
||||||
self.addons_list_widget.save_check_state()
|
self.addons_list_widget.save_check_state()
|
||||||
if ret == QDialog.DialogCode.Accepted:
|
self._on_done(self.addons_list_widget.get_selected_addon_ids())
|
||||||
return self.addons_list_widget.get_selected_addon_ids()
|
QDialog.accept(self)
|
||||||
else:
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
def fetch_update_info(ids: list[int]) -> list[AddonInfo]:
|
def fetch_update_info(ids: list[int]) -> list[AddonInfo]:
|
||||||
|
@ -1463,10 +1480,11 @@ def prompt_to_update(
|
||||||
if not prompt_update:
|
if not prompt_update:
|
||||||
return
|
return
|
||||||
|
|
||||||
ids = ChooseAddonsToUpdateDialog(parent, mgr, updated_addons).ask()
|
def after_choosing(ids: list[int]) -> None:
|
||||||
if not ids:
|
if ids:
|
||||||
return
|
download_addons(parent, mgr, ids, on_done, client)
|
||||||
download_addons(parent, mgr, ids, on_done, client)
|
|
||||||
|
ChooseAddonsToUpdateDialog(parent, mgr, updated_addons).ask(after_choosing)
|
||||||
|
|
||||||
|
|
||||||
# Editing config
|
# Editing config
|
||||||
|
|
|
@ -501,7 +501,7 @@ class AnkiQt(QMainWindow):
|
||||||
if onsuccess:
|
if onsuccess:
|
||||||
onsuccess()
|
onsuccess()
|
||||||
if not self.safeMode:
|
if not self.safeMode:
|
||||||
self.maybe_check_for_addon_updates(self.setupAutoUpdate)
|
self.maybe_check_for_addon_updates(self.setup_auto_update)
|
||||||
|
|
||||||
self.maybe_auto_sync_on_open_close(_onsuccess)
|
self.maybe_auto_sync_on_open_close(_onsuccess)
|
||||||
|
|
||||||
|
@ -963,26 +963,33 @@ title="{}" {}>{}</button>""".format(
|
||||||
self.addonManager.loadAddons()
|
self.addonManager.loadAddons()
|
||||||
|
|
||||||
def maybe_check_for_addon_updates(
|
def maybe_check_for_addon_updates(
|
||||||
self, on_done: Callable[[], None] | None = None
|
self, on_done: Callable[[list[DownloadLogEntry]], None] | None = None
|
||||||
) -> None:
|
) -> None:
|
||||||
last_check = self.pm.last_addon_update_check()
|
last_check = self.pm.last_addon_update_check()
|
||||||
elap = int_time() - last_check
|
elap = int_time() - last_check
|
||||||
|
|
||||||
|
if elap > 86_400 or self.pm.last_run_version != int_version():
|
||||||
|
self.check_for_addon_updates(by_user=False, on_done=on_done)
|
||||||
|
elif on_done:
|
||||||
|
on_done([])
|
||||||
|
|
||||||
|
def check_for_addon_updates(
|
||||||
|
self,
|
||||||
|
by_user: bool,
|
||||||
|
on_done: Callable[[list[DownloadLogEntry]], None] | None = None,
|
||||||
|
) -> None:
|
||||||
def wrap_on_updates_installed(log: list[DownloadLogEntry]) -> None:
|
def wrap_on_updates_installed(log: list[DownloadLogEntry]) -> None:
|
||||||
self.on_updates_installed(log)
|
self.on_updates_installed(log)
|
||||||
if on_done:
|
|
||||||
on_done()
|
|
||||||
|
|
||||||
if elap > 86_400 or self.pm.last_run_version != int_version():
|
|
||||||
check_and_prompt_for_updates(
|
|
||||||
self,
|
|
||||||
self.addonManager,
|
|
||||||
wrap_on_updates_installed,
|
|
||||||
requested_by_user=False,
|
|
||||||
)
|
|
||||||
self.pm.set_last_addon_update_check(int_time())
|
self.pm.set_last_addon_update_check(int_time())
|
||||||
elif on_done:
|
if on_done:
|
||||||
on_done()
|
on_done(log)
|
||||||
|
|
||||||
|
check_and_prompt_for_updates(
|
||||||
|
self,
|
||||||
|
self.addonManager,
|
||||||
|
wrap_on_updates_installed,
|
||||||
|
requested_by_user=by_user,
|
||||||
|
)
|
||||||
|
|
||||||
def on_updates_installed(self, log: list[DownloadLogEntry]) -> None:
|
def on_updates_installed(self, log: list[DownloadLogEntry]) -> None:
|
||||||
if log:
|
if log:
|
||||||
|
@ -1413,7 +1420,7 @@ title="{}" {}>{}</button>""".format(
|
||||||
# Auto update
|
# Auto update
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def setupAutoUpdate(self) -> None:
|
def setup_auto_update(self, _log: list[DownloadLogEntry]) -> None:
|
||||||
from aqt.update import check_for_update
|
from aqt.update import check_for_update
|
||||||
|
|
||||||
check_for_update()
|
check_for_update()
|
||||||
|
|
Loading…
Reference in a new issue