From 1c69333210824e23e68378469af6ea71b7f066ae Mon Sep 17 00:00:00 2001 From: llama Date: Mon, 12 May 2025 06:49:29 +0800 Subject: [PATCH 01/14] don't scale border width along with existing masks (#3991) --- ts/routes/image-occlusion/tools/lib.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ts/routes/image-occlusion/tools/lib.ts b/ts/routes/image-occlusion/tools/lib.ts index 35120e61c..13313b07e 100644 --- a/ts/routes/image-occlusion/tools/lib.ts +++ b/ts/routes/image-occlusion/tools/lib.ts @@ -263,6 +263,8 @@ export function enableUniformScaling(canvas: fabric.Canvas, obj: fabric.Object): export function addBorder(obj: fabric.Object): void { obj.stroke = BORDER_COLOR; + obj.strokeWidth = 1; + obj.strokeUniform = true; } export const redraw = (canvas: fabric.Canvas): void => { From 37dfbca094241b1a5ed3f0130570f309be58dd75 Mon Sep 17 00:00:00 2001 From: GithubAnon0000 <160563432+GithubAnon0000@users.noreply.github.com> Date: Thu, 15 May 2025 04:54:51 +0000 Subject: [PATCH 02/14] UPDATE answer button graph tooltip to include I) answer button name and II) description of what "correct" means (#3979) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ADD name of the button after button number (1 → again...) * ADD info string to explain what 'correct' means * Run ./check and make it happy * Apply suggestion from @dae to make text shorter --- ftl/core/statistics.ftl | 1 + ts/routes/graphs/buttons.ts | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/ftl/core/statistics.ftl b/ftl/core/statistics.ftl index 0464e0f0b..c3a2bb613 100644 --- a/ftl/core/statistics.ftl +++ b/ftl/core/statistics.ftl @@ -229,6 +229,7 @@ statistics-stability-day-single = # hour range, eg "From 14:00-15:00" statistics-hours-range = From { $hourStart }:00~{ $hourEnd }:00 statistics-hours-correct = { $correct }/{ $total } correct ({ $percent }%) +statistics-hours-correct-info = → (not 'Again') # the emoji depicts the graph displaying this number statistics-hours-reviews = 📊 { $reviews } reviews # the emoji depicts the graph displaying this number diff --git a/ts/routes/graphs/buttons.ts b/ts/routes/graphs/buttons.ts index 565ec492a..606380590 100644 --- a/ts/routes/graphs/buttons.ts +++ b/ts/routes/graphs/buttons.ts @@ -222,8 +222,23 @@ export function renderButtons( const button = tr.statisticsAnswerButtonsButtonNumber(); const timesPressed = tr.statisticsAnswerButtonsButtonPressed(); const correctStr = tr.statisticsHoursCorrect(totalCorrect(d.group)); + const correctStrInfo = tr.statisticsHoursCorrectInfo(); const pressedStr = `${timesPressed}: ${totalPressedStr(d)}`; - return `${button}: ${d.buttonNum}
${pressedStr}
${correctStr}`; + + let buttonText: string; + if (d.buttonNum === 1) { + buttonText = tr.studyingAgain(); + } else if (d.buttonNum === 2) { + buttonText = tr.studyingHard(); + } else if (d.buttonNum === 3) { + buttonText = tr.studyingGood(); + } else if (d.buttonNum === 4) { + buttonText = tr.studyingEasy(); + } else { + buttonText = ""; + } + + return `${button}: ${d.buttonNum} (${buttonText})
${pressedStr}
${correctStr} ${correctStrInfo}`; } svg.select("g.hover-columns") From f727934a428091ef6332cee6600556371436a169 Mon Sep 17 00:00:00 2001 From: GithubAnon0000 <160563432+GithubAnon0000@users.noreply.github.com> Date: Thu, 15 May 2025 05:08:41 +0000 Subject: [PATCH 03/14] CHANGE collection size too large error to add MB values and info about compressed vs. uncompressed. (#3981) * CHANGE collection size too large error to add MB values and info about compressed vs. uncompressed * Round f64 to 2 decimals * Remove line breaks from ftl/core * Remove string 'uncompressed' from code * Add string 'uncompressed' to ftl/core * Remove if statement change introduced to test changes locally * Run ./check --- ftl/core/sync.ftl | 6 +++--- rslib/src/sync/collection/upload.rs | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ftl/core/sync.ftl b/ftl/core/sync.ftl index d930adeba..34889dc9f 100644 --- a/ftl/core/sync.ftl +++ b/ftl/core/sync.ftl @@ -51,9 +51,9 @@ sync-account-required = sync-sanity-check-failed = Please use the Check Database function, then sync again. If problems persist, please force a one-way sync in the preferences screen. sync-clock-off = Unable to sync - your clock is not set to the correct time. sync-upload-too-large = - Your collection file is too large to send to AnkiWeb. You can reduce its - size by removing any unwanted decks (optionally exporting them first), and - then using Check Database to shrink the file size down. ({ $details }) + Your collection file is too large to send to AnkiWeb. You can reduce its size by removing any unwanted decks (optionally exporting them first), and then using Check Database to shrink the file size down. + + { $details } (uncompressed) sync-sign-in = Sign in sync-ankihub-dialog-heading = AnkiHub Login sync-ankihub-username-label = Username or Email: diff --git a/rslib/src/sync/collection/upload.rs b/rslib/src/sync/collection/upload.rs index 85800a329..5247a8010 100644 --- a/rslib/src/sync/collection/upload.rs +++ b/rslib/src/sync/collection/upload.rs @@ -119,9 +119,13 @@ pub enum UploadResponse { } pub fn check_upload_limit(size: usize, limit: usize) -> Result<()> { + let size_of_one_mb: f64 = 1024.0 * 1024.0; + let collection_size_in_mb: f64 = size as f64 / size_of_one_mb; + let limit_size_in_mb: f64 = limit as f64 / size_of_one_mb; + if size >= limit { Err(AnkiError::sync_error( - format!("{size} > {limit}"), + format!("{collection_size_in_mb:.2} MB > {limit_size_in_mb:.2} MB"), SyncErrorKind::UploadTooLarge, )) } else { From f7cdf4eb9eb07bc9ed373a1c3f0780047bd0f5a2 Mon Sep 17 00:00:00 2001 From: Luc Mcgrady Date: Thu, 15 May 2025 06:14:10 +0100 Subject: [PATCH 04/14] Fix/Leech suspended tooltip (#3992) * Fix/Leech suspended popup * extra check * Fix: None check * move comment --- qt/aqt/reviewer.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py index da4b37985..05e9becf4 100644 --- a/qt/aqt/reviewer.py +++ b/qt/aqt/reviewer.py @@ -551,9 +551,11 @@ class Reviewer: def after_answer(changes: OpChanges) -> None: if gui_hooks.reviewer_did_answer_card.count() > 0: self.card.load() + # v3 scheduler doesn't report this + suspended = self.card is not None and self.card.queue < 0 self._after_answering(ease) if sched.state_is_leech(answer.new_state): - self.onLeech() + self.onLeech(suspended) self.state = "transition" answer_card(parent=self.mw, answer=answer).success( @@ -949,11 +951,10 @@ timerStopped = false; # Leeches ########################################################################## - def onLeech(self, card: Card | None = None) -> None: + def onLeech(self, suspended: bool = False) -> None: # for now s = tr.studying_card_was_a_leech() - # v3 scheduler doesn't report this - if card and card.queue < 0: + if suspended: s += f" {tr.studying_it_has_been_suspended()}" tooltip(s) From 86c89907e7db32a78d0601b9da66cbad90ac37bc Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 15 May 2025 15:37:49 +1000 Subject: [PATCH 05/14] Add URL scheme whitelist (#3994) * Add experimental Cursor rules * Add the ability to customize URL schemes Closes #3965 --- .cursor/rules/i18n.md | 7 +++++ .cursor/rules/testing.md | 2 ++ ftl/core/preferences.ftl | 7 +++++ qt/aqt/forms/preferences.ui | 56 ++++++++++++++++++++--------------- qt/aqt/preferences.py | 5 ++++ qt/aqt/profiles.py | 6 ++++ qt/aqt/url_schemes.py | 58 +++++++++++++++++++++++++++++++++++++ qt/aqt/utils.py | 2 +- qt/aqt/webview.py | 4 ++- 9 files changed, 121 insertions(+), 26 deletions(-) create mode 100644 .cursor/rules/i18n.md create mode 100644 .cursor/rules/testing.md create mode 100644 qt/aqt/url_schemes.py diff --git a/.cursor/rules/i18n.md b/.cursor/rules/i18n.md new file mode 100644 index 000000000..336c9d995 --- /dev/null +++ b/.cursor/rules/i18n.md @@ -0,0 +1,7 @@ +- We use the fluent system+code generation for translation. +- New strings should be added to rslib/core/. Ask for the appropriate file if you're not sure. +- Assuming a string addons-you-have-count has been added to addons.ftl, that string is accessible in our different languages as follows: + - Python: from aqt.utils import tr; msg = tr.addons_you_have_count(count=3) + - TypeScript: import * as tr from "@generated/ftl"; tr.addonsYouHaveCount({count: 3}) + - Rust: collection.tr.addons_you_have_count(3) +- In Qt .ui files, strings that are marked as translatable will automatically use the registered ftl strings. So a QLabel with a title 'addons_you_have_count' that is marked as translatable will automatically use the translation defined in our addons.ftl file. diff --git a/.cursor/rules/testing.md b/.cursor/rules/testing.md new file mode 100644 index 000000000..47a530219 --- /dev/null +++ b/.cursor/rules/testing.md @@ -0,0 +1,2 @@ +- To build and check the project, use ./check(.bat) +- This will format files, then run lints and unit tests. diff --git a/ftl/core/preferences.ftl b/ftl/core/preferences.ftl index 69a9300a0..a0983dd6c 100644 --- a/ftl/core/preferences.ftl +++ b/ftl/core/preferences.ftl @@ -83,6 +83,13 @@ preferences-ankiweb-intro = AnkiWeb is a free service that lets you keep your fl preferences-ankihub-intro = AnkiHub provides collaborative deck editing and additional study tools. A paid subscription is required to access certain features. preferences-third-party-description = Third-party services are unaffiliated with and not endorsed by Anki. Use of these services may require payment. +## URL scheme related +preferences-url-schemes = URL Schemes +preferences-url-scheme-prompt = Allowed { preferences-url-schemes } (space-separated): +preferences-url-scheme-warning = Blocked attempt to open `{ $link }`, which may be a security issue. + + If you trust the deck author and wish to proceed, you can add `{ $scheme }` to your allowed { preferences-url-schemes }. + ## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future. preferences-basic = Basic diff --git a/qt/aqt/forms/preferences.ui b/qt/aqt/forms/preferences.ui index 34de8c80e..807d4093c 100644 --- a/qt/aqt/forms/preferences.ui +++ b/qt/aqt/forms/preferences.ui @@ -17,7 +17,7 @@ - Qt::StrongFocus + Qt::FocusPolicy::StrongFocus 0 @@ -78,7 +78,7 @@ - QComboBox::AdjustToMinimumContentsLengthWithIcon + QComboBox::SizeAdjustPolicy::AdjustToMinimumContentsLengthWithIcon @@ -260,7 +260,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -451,6 +451,13 @@ + + + + preferences_url_schemes + + + @@ -466,7 +473,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -518,10 +525,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -614,10 +621,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Expanding + QSizePolicy::Policy::Expanding @@ -739,7 +746,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -827,7 +834,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -840,7 +847,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -918,10 +925,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -953,7 +960,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1020,7 +1027,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1035,10 +1042,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -1080,7 +1087,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -1128,10 +1135,10 @@ - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Maximum + QSizePolicy::Policy::Maximum @@ -1207,7 +1214,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -1227,17 +1234,17 @@ preferences_some_settings_will_take_effect_after - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Close|QDialogButtonBox::Help + QDialogButtonBox::StandardButton::Close|QDialogButtonBox::StandardButton::Help @@ -1266,6 +1273,7 @@ showEstimates spacebar_rates_card render_latex + url_schemes pastePNG paste_strips_formatting useCurrent diff --git a/qt/aqt/preferences.py b/qt/aqt/preferences.py index 37483427a..bd87ef830 100644 --- a/qt/aqt/preferences.py +++ b/qt/aqt/preferences.py @@ -20,9 +20,11 @@ from aqt.profiles import VideoDriver from aqt.qt import * from aqt.sync import sync_login from aqt.theme import Theme +from aqt.url_schemes import show_url_schemes_dialog from aqt.utils import ( HelpPage, add_close_shortcut, + add_ellipsis_to_action_label, askUser, disable_help_button, is_win, @@ -152,6 +154,9 @@ class Preferences(QDialog): form.monthly_backups.setValue(self.prefs.backups.monthly) form.minutes_between_backups.setValue(self.prefs.backups.minimum_interval_mins) + add_ellipsis_to_action_label(self.form.url_schemes) + qconnect(self.form.url_schemes.clicked, show_url_schemes_dialog) + def update_collection(self, on_done: Callable[[], None]) -> None: form = self.form diff --git a/qt/aqt/profiles.py b/qt/aqt/profiles.py index d92d7f59f..0fd85ca8f 100644 --- a/qt/aqt/profiles.py +++ b/qt/aqt/profiles.py @@ -744,3 +744,9 @@ create table if not exists profiles def ankihub_username(self) -> str | None: return self.profile.get("thirdPartyAnkiHubUsername") + + def allowed_url_schemes(self) -> list[str]: + return self.profile.get("allowedUrlSchemes", []) + + def set_allowed_url_schemes(self, schemes: list[str]) -> None: + self.profile["allowedUrlSchemes"] = schemes diff --git a/qt/aqt/url_schemes.py b/qt/aqt/url_schemes.py new file mode 100644 index 000000000..f5ee1110d --- /dev/null +++ b/qt/aqt/url_schemes.py @@ -0,0 +1,58 @@ +# Copyright: Ankitects Pty Ltd and contributors +# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html + +from __future__ import annotations + +from markdown import markdown + +from aqt.qt import Qt, QUrl +from aqt.utils import ask_user_dialog, getText, openLink, tr + + +def show_url_schemes_dialog() -> None: + from aqt import mw + + default = " ".join(mw.pm.allowed_url_schemes()) + schemes, ok = getText( + prompt=tr.preferences_url_scheme_prompt(), + title=tr.preferences_url_schemes(), + default=default, + ) + if ok: + mw.pm.set_allowed_url_schemes(schemes.split(" ")) + mw.pm.save() + + +def is_supported_scheme(url: QUrl) -> bool: + from aqt import mw + + scheme = url.scheme().lower() + allowed_schemes = mw.pm.allowed_url_schemes() + + return scheme in allowed_schemes or scheme in ["http", "https"] + + +def open_url_if_supported_scheme(url: QUrl) -> None: + from aqt import mw + + if is_supported_scheme(url): + openLink(url) + else: + + def on_button(idx: int) -> None: + if idx == 0: + show_url_schemes_dialog() + + msg = markdown( + tr.preferences_url_scheme_warning(link=url.toString(), scheme=url.scheme()) + ) + ask_user_dialog( + msg, + buttons=[ + tr.actions_with_ellipsis(action=tr.preferences_url_schemes()), + tr.actions_close(), + ], + parent=mw, + callback=on_button, + textFormat=Qt.TextFormat.RichText, + ) diff --git a/qt/aqt/utils.py b/qt/aqt/utils.py index a11eb14b7..6ae8bace8 100644 --- a/qt/aqt/utils.py +++ b/qt/aqt/utils.py @@ -1188,7 +1188,7 @@ def disallow_full_screen() -> bool: ) -def add_ellipsis_to_action_label(*actions: QAction) -> None: +def add_ellipsis_to_action_label(*actions: QAction | QPushButton) -> None: """Pass actions to add '...' to their labels, indicating that more input is required before they can be performed. diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py index 4db506e49..966d3de5a 100644 --- a/qt/aqt/webview.py +++ b/qt/aqt/webview.py @@ -266,7 +266,9 @@ class AnkiWebPage(QWebEnginePage): print("onclick handler needs to return false") return False # load all other links in browser - openLink(url) + from aqt.url_schemes import open_url_if_supported_scheme + + open_url_if_supported_scheme(url) return False def _onCmd(self, str: str) -> Any: From 6427ff3db54d231068f1fb506099e03430c2d3b1 Mon Sep 17 00:00:00 2001 From: Kolby Moroz Liebl <31669092+KolbyML@users.noreply.github.com> Date: Thu, 15 May 2025 00:09:27 -0600 Subject: [PATCH 06/14] Fix dockerimage, by bumping rust version (#3993) --- CONTRIBUTORS | 1 + docs/syncserver/Dockerfile | 2 +- docs/syncserver/Dockerfile.distroless | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 53cb47b29..40bda393b 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -226,6 +226,7 @@ Jonathan Schoreels JL710 Matt Brubeck Yaoliang Chen +KolbyML ******************** diff --git a/docs/syncserver/Dockerfile b/docs/syncserver/Dockerfile index 204e24971..0f5554c8c 100644 --- a/docs/syncserver/Dockerfile +++ b/docs/syncserver/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.83.0-alpine3.20 AS builder +FROM rust:1.85.0-alpine3.20 AS builder ARG ANKI_VERSION diff --git a/docs/syncserver/Dockerfile.distroless b/docs/syncserver/Dockerfile.distroless index db8e81ea1..a69bb6f3d 100644 --- a/docs/syncserver/Dockerfile.distroless +++ b/docs/syncserver/Dockerfile.distroless @@ -1,4 +1,4 @@ -FROM rust:1.83.0 AS builder +FROM rust:1.85.0 AS builder ARG ANKI_VERSION From f96c8c2ac899251f6b0ff2b49c85e889aa0219c3 Mon Sep 17 00:00:00 2001 From: Adnane Taghi Date: Thu, 15 May 2025 07:52:39 +0200 Subject: [PATCH 07/14] Make URL schemes dialog more ergonomic (#4002) (originally merged into a PR branch) * Make URL schemes dialog more ergonomic * add name to contributors list * Title Case * Tweak build instructions so Cursor picks them up * Use a warning icon for the URL scheme pop-up * Default to cancelling --- .cursor/rules/building.md | 2 ++ .cursor/rules/testing.md | 2 -- CONTRIBUTORS | 1 + ftl/core/preferences.ftl | 2 ++ qt/aqt/about.py | 1 + qt/aqt/profiles.py | 8 ++++++++ qt/aqt/url_schemes.py | 25 +++++++++++++++++++------ 7 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 .cursor/rules/building.md delete mode 100644 .cursor/rules/testing.md diff --git a/.cursor/rules/building.md b/.cursor/rules/building.md new file mode 100644 index 000000000..15326d9fa --- /dev/null +++ b/.cursor/rules/building.md @@ -0,0 +1,2 @@ +- To build and check the project, use ./check in the root folder (or check.bat on Windows) +- This will format files, then run lints and unit tests. diff --git a/.cursor/rules/testing.md b/.cursor/rules/testing.md deleted file mode 100644 index 47a530219..000000000 --- a/.cursor/rules/testing.md +++ /dev/null @@ -1,2 +0,0 @@ -- To build and check the project, use ./check(.bat) -- This will format files, then run lints and unit tests. diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 40bda393b..2297786ae 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -227,6 +227,7 @@ JL710 Matt Brubeck Yaoliang Chen KolbyML +Adnane Taghi ******************** diff --git a/ftl/core/preferences.ftl b/ftl/core/preferences.ftl index a0983dd6c..7c75904eb 100644 --- a/ftl/core/preferences.ftl +++ b/ftl/core/preferences.ftl @@ -89,6 +89,8 @@ preferences-url-scheme-prompt = Allowed { preferences-url-schemes } (space-separ preferences-url-scheme-warning = Blocked attempt to open `{ $link }`, which may be a security issue. If you trust the deck author and wish to proceed, you can add `{ $scheme }` to your allowed { preferences-url-schemes }. +preferences-url-scheme-allow-once = Allow Once +preferences-url-scheme-always-allow = Always Allow ## NO NEED TO TRANSLATE. This text is no longer used by Anki, and will be removed in the future. diff --git a/qt/aqt/about.py b/qt/aqt/about.py index d06b13ad5..bf34e4395 100644 --- a/qt/aqt/about.py +++ b/qt/aqt/about.py @@ -221,6 +221,7 @@ def show(mw: aqt.AnkiQt) -> QDialog: "Yuki", "🦙 (siid)", "Mukunda Madhav Dey", + "Adnane Taghi", ) ) diff --git a/qt/aqt/profiles.py b/qt/aqt/profiles.py index 0fd85ca8f..273e6df3a 100644 --- a/qt/aqt/profiles.py +++ b/qt/aqt/profiles.py @@ -750,3 +750,11 @@ create table if not exists profiles def set_allowed_url_schemes(self, schemes: list[str]) -> None: self.profile["allowedUrlSchemes"] = schemes + + def always_allow_scheme(self, scheme: str) -> None: + schemes = self.allowed_url_schemes() + + if scheme not in schemes: + schemes.append(scheme) + + self.set_allowed_url_schemes(schemes) diff --git a/qt/aqt/url_schemes.py b/qt/aqt/url_schemes.py index f5ee1110d..ea05ee319 100644 --- a/qt/aqt/url_schemes.py +++ b/qt/aqt/url_schemes.py @@ -5,8 +5,8 @@ from __future__ import annotations from markdown import markdown -from aqt.qt import Qt, QUrl -from aqt.utils import ask_user_dialog, getText, openLink, tr +from aqt.qt import QMessageBox, Qt, QUrl +from aqt.utils import MessageBox, getText, openLink, tr def show_url_schemes_dialog() -> None: @@ -32,6 +32,13 @@ def is_supported_scheme(url: QUrl) -> bool: return scheme in allowed_schemes or scheme in ["http", "https"] +def always_allow_scheme(url: QUrl) -> None: + from aqt import mw + + scheme = url.scheme().lower() + mw.pm.always_allow_scheme(scheme) + + def open_url_if_supported_scheme(url: QUrl) -> None: from aqt import mw @@ -41,18 +48,24 @@ def open_url_if_supported_scheme(url: QUrl) -> None: def on_button(idx: int) -> None: if idx == 0: - show_url_schemes_dialog() + openLink(url) + elif idx == 1: + always_allow_scheme(url) + openLink(url) msg = markdown( tr.preferences_url_scheme_warning(link=url.toString(), scheme=url.scheme()) ) - ask_user_dialog( + MessageBox( msg, buttons=[ - tr.actions_with_ellipsis(action=tr.preferences_url_schemes()), - tr.actions_close(), + tr.preferences_url_scheme_allow_once(), + tr.preferences_url_scheme_always_allow(), + (tr.actions_cancel(), QMessageBox.ButtonRole.RejectRole), ], parent=mw, callback=on_button, textFormat=Qt.TextFormat.RichText, + default_button=2, + icon=QMessageBox.Icon.Warning, ) From 4e1a9017387c4963f5e5e4c1a5b2975a51614aa5 Mon Sep 17 00:00:00 2001 From: llama Date: Thu, 15 May 2025 14:26:51 +0800 Subject: [PATCH 08/14] Clarify field separator being a guess when importing csv (#3996) * clarify that the initially selected field separator is a guess * explain why the field seperator setting might be locked --- ftl/core/importing.ftl | 4 ++++ ts/routes/import-csv/FileOptions.svelte | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ftl/core/importing.ftl b/ftl/core/importing.ftl index c0bc724f3..70bc5f4d1 100644 --- a/ftl/core/importing.ftl +++ b/ftl/core/importing.ftl @@ -15,6 +15,7 @@ importing-colon = Colon importing-comma = Comma importing-empty-first-field = Empty first field: { $val } importing-field-separator = Field separator +importing-field-separator-guessed = Field separator (guessed) importing-field-mapping = Field mapping importing-field-of-file-is = Field { $val } of file is: importing-fields-separated-by = Fields separated by: { $val } @@ -217,6 +218,9 @@ importing-field-separator-help = Please note that if this character appears in any field itself, the field has to be quoted accordingly to the CSV standard. Spreadsheet programs like LibreOffice will do this automatically. + + It cannot be changed if the text file forces use of a specific separator via a file header. + If a file header is not present, Anki will try to guess what the separator is. importing-allow-html-in-fields-help = Enable this if the file contains HTML formatting. E.g. if the file contains the string '<br>', it will appear as a line break on your card. On the other hand, with this diff --git a/ts/routes/import-csv/FileOptions.svelte b/ts/routes/import-csv/FileOptions.svelte index 182083865..53a6c3790 100644 --- a/ts/routes/import-csv/FileOptions.svelte +++ b/ts/routes/import-csv/FileOptions.svelte @@ -65,7 +65,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html openHelpModal(Object.keys(settings).indexOf("delimiter"))} > - {settings.delimiter.title} + {$metadata.forceDelimiter + ? settings.delimiter.title + : tr.importingFieldSeparatorGuessed()} From a2a1f597bebbdc4e77f8d8e1e3e6086230582db8 Mon Sep 17 00:00:00 2001 From: llama Date: Thu, 15 May 2025 14:30:17 +0800 Subject: [PATCH 09/14] Style the fsrs params input (#3997) * style textarea and date inputs * remove redundant date input styling --- ts/lib/sass/base.scss | 3 +++ ts/routes/deck-options/DateInput.svelte | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ts/lib/sass/base.scss b/ts/lib/sass/base.scss index c997eb20a..d28659ed8 100644 --- a/ts/lib/sass/base.scss +++ b/ts/lib/sass/base.scss @@ -75,6 +75,9 @@ input[type="radio"], input[type="checkbox"] { cursor: pointer; } + +textarea, +input[type="date"], input[type="text"] { border-radius: prop(border-radius); outline: none; diff --git a/ts/routes/deck-options/DateInput.svelte b/ts/routes/deck-options/DateInput.svelte index 196422c67..95bbf6a42 100644 --- a/ts/routes/deck-options/DateInput.svelte +++ b/ts/routes/deck-options/DateInput.svelte @@ -29,10 +29,5 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html width: 100%; -webkit-appearance: none; appearance: none; - background: var(--canvas-inset); - border: 1px solid var(--border); - border-radius: var(--border-radius); - padding: 1px 0.5em; - outline: none !important; } From 8f2c708751868faf0563cc997c320b74f3d35323 Mon Sep 17 00:00:00 2001 From: user1823 <92206575+user1823@users.noreply.github.com> Date: Thu, 15 May 2025 12:01:18 +0530 Subject: [PATCH 10/14] Include reset entries in dataset exported for research (#3998) https://github.com/open-spaced-repetition/fsrs4anki-helper/pull/566#issuecomment-2875432135 --- rslib/src/storage/revlog/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rslib/src/storage/revlog/mod.rs b/rslib/src/storage/revlog/mod.rs index 043014499..31ff613fa 100644 --- a/rslib/src/storage/revlog/mod.rs +++ b/rslib/src/storage/revlog/mod.rs @@ -158,7 +158,7 @@ impl SqliteStorage { self.db .prepare_cached(concat!( include_str!("get.sql"), - " where ease between 1 and 4", + " where (ease between 1 and 4) or (ease = 0 and factor = 0)", " order by cid, id" ))? .query_and_then([], row_to_revlog_entry)? From 97b12b420ac5209188d9ae6fa0828e83f044acda Mon Sep 17 00:00:00 2001 From: llama Date: Thu, 15 May 2025 14:41:30 +0800 Subject: [PATCH 11/14] Resize fsrs params input to fit content (#3999) * resize param input on value change * resize on window resize --- ts/routes/deck-options/ParamsInput.svelte | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/ts/routes/deck-options/ParamsInput.svelte b/ts/routes/deck-options/ParamsInput.svelte index e0a493013..5bed775cf 100644 --- a/ts/routes/deck-options/ParamsInput.svelte +++ b/ts/routes/deck-options/ParamsInput.svelte @@ -3,11 +3,25 @@ Copyright: Ankitects Pty Ltd and contributors License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html --> + +