diff --git a/ftl/core/preferences.ftl b/ftl/core/preferences.ftl
index 23b72f267..aa09cb2ce 100644
--- a/ftl/core/preferences.ftl
+++ b/ftl/core/preferences.ftl
@@ -22,6 +22,7 @@ preferences-scheduling = Scheduling
preferences-show-learning-cards-with-larger-steps = Show learning cards with larger steps before reviews
preferences-show-next-review-time-above-answer = Show next review time above answer buttons
preferences-spacebar-rates-card = Spacebar (or enter) also answers card
+preferences-show-colored-buttons = Show colored border on answer buttons
preferences-show-play-buttons-on-cards-with = Show play buttons on cards with audio
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.
diff --git a/proto/anki/config.proto b/proto/anki/config.proto
index ea115f0fc..40371e78d 100644
--- a/proto/anki/config.proto
+++ b/proto/anki/config.proto
@@ -57,6 +57,7 @@ message ConfigKey {
LOAD_BALANCER_ENABLED = 26;
FSRS_SHORT_TERM_WITH_STEPS_ENABLED = 27;
FSRS_LEGACY_EVALUATE = 28;
+ SHOW_COLORED_BUTTONS = 29;
}
enum String {
SET_DUE_BROWSER = 0;
@@ -120,6 +121,7 @@ message Preferences {
uint32 time_limit_secs = 5;
bool load_balancer_enabled = 6;
bool fsrs_short_term_with_steps_enabled = 7;
+ bool show_colored_buttons = 8;
}
message Editing {
bool adding_defaults_to_current_deck = 1;
diff --git a/qt/aqt/data/web/css/reviewer-bottom.scss b/qt/aqt/data/web/css/reviewer-bottom.scss
index 59098a5fb..a514474f2 100644
--- a/qt/aqt/data/web/css/reviewer-bottom.scss
+++ b/qt/aqt/data/web/css/reviewer-bottom.scss
@@ -30,6 +30,27 @@ button {
position: relative;
}
+.answerButton,
+.answerButton:hover {
+ border-style: solid;
+}
+
+.answerButton:focus {
+ border-style: dashed;
+}
+
+.answerIncorrect,
+.answerIncorrect:hover,
+.answerIncorrect:focus {
+ border-color: color(border-answerIncorrect);
+}
+
+.answerCorrect,
+.answerCorrect:hover,
+.answerCorrect:focus {
+ border-color: color(border-answerCorrect);
+}
+
.hitem {
margin-top: 2px;
}
diff --git a/qt/aqt/forms/preferences.ui b/qt/aqt/forms/preferences.ui
index 0035e1f42..9383dafce 100644
--- a/qt/aqt/forms/preferences.ui
+++ b/qt/aqt/forms/preferences.ui
@@ -425,6 +425,19 @@
+ -
+
+
+
+ 0
+ 0
+
+
+
+ preferences_show_colored_buttons
+
+
+
-
@@ -1271,6 +1284,7 @@
interrupt_audio
showProgress
showEstimates
+ showColoredButtons
spacebar_rates_card
render_latex
url_schemes
diff --git a/qt/aqt/preferences.py b/qt/aqt/preferences.py
index 939dd8c2c..8a702e5d9 100644
--- a/qt/aqt/preferences.py
+++ b/qt/aqt/preferences.py
@@ -137,6 +137,7 @@ class Preferences(QDialog):
form.showEstimates.setChecked(reviewing.show_intervals_on_buttons)
form.showProgress.setChecked(reviewing.show_remaining_due_counts)
form.showPlayButtons.setChecked(not reviewing.hide_audio_play_buttons)
+ form.showColoredButtons.setChecked(reviewing.show_colored_buttons)
form.interrupt_audio.setChecked(reviewing.interrupt_audio_when_answering)
editing = self.prefs.editing
@@ -172,6 +173,7 @@ class Preferences(QDialog):
reviewing.show_intervals_on_buttons = form.showEstimates.isChecked()
reviewing.time_limit_secs = form.timeLimit.value() * 60
reviewing.hide_audio_play_buttons = not self.form.showPlayButtons.isChecked()
+ reviewing.show_colored_buttons = self.form.showColoredButtons.isChecked()
reviewing.interrupt_audio_when_answering = self.form.interrupt_audio.isChecked()
editing = self.prefs.editing
diff --git a/qt/aqt/reviewer.py b/qt/aqt/reviewer.py
index 6d68f9e3a..de13335ef 100644
--- a/qt/aqt/reviewer.py
+++ b/qt/aqt/reviewer.py
@@ -919,22 +919,42 @@ timerStopped = false;
extra = """id="defease" """
else:
extra = ""
+
+ if i == 1:
+ button_class = "answerIncorrect"
+ else:
+ button_class = "answerCorrect"
+
due = self._buttonTime(i, v3_labels=labels)
key = (
tr.actions_shortcut_key(val=aqt.mw.pm.get_answer_key(i))
if aqt.mw.pm.get_answer_key(i)
else ""
)
- return """
+
+ if not self.mw.col.get_config_bool(Config.Bool.SHOW_COLORED_BUTTONS):
+ return """
| """ % (
- extra,
- key,
- i,
- i,
- label,
- due,
- )
+ extra,
+ key,
+ i,
+ i,
+ label,
+ due,
+ )
+ else:
+ return """
+ | """ % (
+ extra,
+ button_class,
+ key,
+ i,
+ i,
+ label,
+ due,
+ )
buf = ""
for ease, label in self._answerButtonList():
diff --git a/rslib/src/backend/config.rs b/rslib/src/backend/config.rs
index b6e81ce2a..81edbf552 100644
--- a/rslib/src/backend/config.rs
+++ b/rslib/src/backend/config.rs
@@ -40,6 +40,7 @@ impl From for BoolKey {
BoolKeyProto::LoadBalancerEnabled => BoolKey::LoadBalancerEnabled,
BoolKeyProto::FsrsShortTermWithStepsEnabled => BoolKey::FsrsShortTermWithStepsEnabled,
BoolKeyProto::FsrsLegacyEvaluate => BoolKey::FsrsLegacyEvaluate,
+ BoolKeyProto::ShowColoredButtons => BoolKey::ShowColoredButtons,
}
}
}
diff --git a/rslib/src/config/bool.rs b/rslib/src/config/bool.rs
index c76787cb0..16121bcd9 100644
--- a/rslib/src/config/bool.rs
+++ b/rslib/src/config/bool.rs
@@ -54,6 +54,7 @@ pub enum BoolKey {
ShowRemainingDueCountsInStudy,
#[strum(to_string = "addToCur")]
AddingDefaultsToCurrentDeck,
+ ShowColoredButtons,
}
/// This is a workaround for old clients that used ints to represent boolean
@@ -71,6 +72,7 @@ impl Collection {
// some keys default to true
BoolKey::InterruptAudioWhenAnswering
| BoolKey::ShowIntervalsAboveAnswerButtons
+ | BoolKey::ShowColoredButtons
| BoolKey::AddingDefaultsToCurrentDeck
| BoolKey::FutureDueShowBacklog
| BoolKey::ShowRemainingDueCountsInStudy
diff --git a/rslib/src/preferences.rs b/rslib/src/preferences.rs
index 96be8e461..394d5bec8 100644
--- a/rslib/src/preferences.rs
+++ b/rslib/src/preferences.rs
@@ -97,6 +97,7 @@ impl Collection {
show_remaining_due_counts: self.get_config_bool(BoolKey::ShowRemainingDueCountsInStudy),
show_intervals_on_buttons: self
.get_config_bool(BoolKey::ShowIntervalsAboveAnswerButtons),
+ show_colored_buttons: self.get_config_bool(BoolKey::ShowColoredButtons),
time_limit_secs: self.get_answer_time_limit_secs(),
load_balancer_enabled: self.get_config_bool(BoolKey::LoadBalancerEnabled),
fsrs_short_term_with_steps_enabled: self
@@ -119,6 +120,7 @@ impl Collection {
BoolKey::ShowIntervalsAboveAnswerButtons,
s.show_intervals_on_buttons,
)?;
+ self.set_config_bool_inner(BoolKey::ShowColoredButtons, s.show_colored_buttons)?;
self.set_answer_time_limit_secs(s.time_limit_secs)?;
self.set_config_bool_inner(BoolKey::LoadBalancerEnabled, s.load_balancer_enabled)?;
self.set_config_bool_inner(
diff --git a/ts/lib/sass/_vars.scss b/ts/lib/sass/_vars.scss
index a8da766ad..65d99c6b3 100644
--- a/ts/lib/sass/_vars.scss
+++ b/ts/lib/sass/_vars.scss
@@ -178,6 +178,20 @@ $vars: (
dark: palette(blue, 5),
),
),
+ answerCorrect: (
+ "Border color of answer buttons that show the answer was correct (hard, good, easy)",
+ (
+ light: palette(green, 5),
+ dark: palette(green, 5),
+ )
+ ),
+ answerIncorrect: (
+ "Border color of the answer button that shows that the answer was incorrect (again)",
+ (
+ light: palette(red, 5),
+ dark: palette(red, 5),
+ )
+ ),
),
button: (
bg: (