Commit e2362072 authored by Lückemeyer's avatar Lückemeyer
Browse files

claude added learn direction toggle switch

parent 044bb284
...@@ -24,5 +24,20 @@ public interface LeitnerStateDao { ...@@ -24,5 +24,20 @@ public interface LeitnerStateDao {
"JOIN unit u ON u.id = v.unit_id " + "JOIN unit u ON u.id = v.unit_id " +
"WHERE ls.direction = :direction AND ls.box_number = :box " + "WHERE ls.direction = :direction AND ls.box_number = :box " +
"ORDER BY u.book_id ASC, u.position ASC, v.position ASC") "ORDER BY u.book_id ASC, u.position ASC, v.position ASC")
List<LeitnerState> getByBoxOrderedSync(String direction, int box); List<LeitnerState> getByBoxOrderedAsc(String direction, int box);
@Query("SELECT ls.* FROM leitner_state ls " +
"JOIN card c ON c.id = ls.card_id " +
"JOIN volet v ON v.id = c.volet_id " +
"JOIN unit u ON u.id = v.unit_id " +
"WHERE ls.direction = :direction AND ls.box_number = :box " +
"ORDER BY u.book_id DESC, u.position DESC, v.position DESC")
List<LeitnerState> getByBoxOrderedDesc(String direction, int box);
/** Dispatches to ASC or DESC based on the ascending flag. */
default List<LeitnerState> getByBoxOrderedSync(String direction, int box, boolean ascending) {
return ascending
? getByBoxOrderedAsc(direction, box)
: getByBoxOrderedDesc(direction, box);
}
} }
...@@ -68,7 +68,7 @@ public class TrainingRepository { ...@@ -68,7 +68,7 @@ public class TrainingRepository {
// ── Scheduling ──────────────────────────────────────────────────────────── // ── Scheduling ────────────────────────────────────────────────────────────
public TrainingCard nextCard(String direction) { public TrainingCard nextCard(String direction, boolean ascending) {
long dayStart = todayStartEpochSeconds(); long dayStart = todayStartEpochSeconds();
// Pending card first // Pending card first
...@@ -83,13 +83,7 @@ public class TrainingRepository { ...@@ -83,13 +83,7 @@ public class TrainingRepository {
Set<Integer> attempted = new HashSet<>(attemptedIds); Set<Integer> attempted = new HashSet<>(attemptedIds);
for (int box = 1; box <= 5; box++) { for (int box = 1; box <= 5; box++) {
for (LeitnerState ls : db.leitnerStateDao().getByBoxOrderedSync(direction, box)) { for (LeitnerState ls : db.leitnerStateDao().getByBoxOrderedSync(direction, box, ascending)) {
if (!attempted.contains(ls.id)) return buildCard(ls);
}
}
attempted = new HashSet<>();
for (int box = 1; box <= 5; box++) {
for (LeitnerState ls : db.leitnerStateDao().getByBoxOrderedSync(direction, box)) {
if (!attempted.contains(ls.id)) return buildCard(ls); if (!attempted.contains(ls.id)) return buildCard(ls);
} }
} }
......
...@@ -26,9 +26,14 @@ public class HomeFragment extends Fragment { ...@@ -26,9 +26,14 @@ public class HomeFragment extends Fragment {
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
// Toggle: checked = Learn (DESC = higher boxes first), unchecked = Repeat (ASC)
// Default to Repeat (ASC) on first launch
binding.toggleMode.setChecked(false);
binding.btnFrToNative.setOnClickListener(v -> { binding.btnFrToNative.setOnClickListener(v -> {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("direction", "fr_to_native"); args.putString("direction", "fr_to_native");
args.putBoolean("ascending", isRepeatMode());
Navigation.findNavController(v) Navigation.findNavController(v)
.navigate(R.id.action_home_to_training, args); .navigate(R.id.action_home_to_training, args);
}); });
...@@ -36,6 +41,7 @@ public class HomeFragment extends Fragment { ...@@ -36,6 +41,7 @@ public class HomeFragment extends Fragment {
binding.btnNativeToFr.setOnClickListener(v -> { binding.btnNativeToFr.setOnClickListener(v -> {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString("direction", "native_to_fr"); args.putString("direction", "native_to_fr");
args.putBoolean("ascending", isRepeatMode());
Navigation.findNavController(v) Navigation.findNavController(v)
.navigate(R.id.action_home_to_training, args); .navigate(R.id.action_home_to_training, args);
}); });
...@@ -45,6 +51,11 @@ public class HomeFragment extends Fragment { ...@@ -45,6 +51,11 @@ public class HomeFragment extends Fragment {
.navigate(R.id.action_home_to_stats)); .navigate(R.id.action_home_to_stats));
} }
/** Returns true when the toggle is in Repeat position (ASC ordering). */
private boolean isRepeatMode() {
return !binding.toggleMode.isChecked();
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
......
...@@ -20,6 +20,7 @@ public class TrainingFragment extends Fragment { ...@@ -20,6 +20,7 @@ public class TrainingFragment extends Fragment {
private FragmentTrainingBinding binding; private FragmentTrainingBinding binding;
private TrainingRepository repo; private TrainingRepository repo;
private String direction; private String direction;
private boolean ascending;
private int sessionId; private int sessionId;
private TrainingCard current; private TrainingCard current;
private final ExecutorService exec = Executors.newSingleThreadExecutor(); private final ExecutorService exec = Executors.newSingleThreadExecutor();
...@@ -35,8 +36,9 @@ public class TrainingFragment extends Fragment { ...@@ -35,8 +36,9 @@ public class TrainingFragment extends Fragment {
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
// Read direction argument passed via Bundle // Read direction and sort order arguments passed from HomeFragment
direction = requireArguments().getString("direction", "fr_to_native"); direction = requireArguments().getString("direction", "fr_to_native");
ascending = requireArguments().getBoolean("ascending", true);
repo = new TrainingRepository(requireContext()); repo = new TrainingRepository(requireContext());
exec.execute(() -> { exec.execute(() -> {
...@@ -64,7 +66,7 @@ public class TrainingFragment extends Fragment { ...@@ -64,7 +66,7 @@ public class TrainingFragment extends Fragment {
binding.layoutSolution.setVisibility(View.GONE); binding.layoutSolution.setVisibility(View.GONE);
exec.execute(() -> { exec.execute(() -> {
current = repo.nextCard(direction); current = repo.nextCard(direction, ascending);
requireActivity().runOnUiThread(() -> { requireActivity().runOnUiThread(() -> {
if (current == null) showAllDone(); if (current == null) showAllDone();
else { else {
......
...@@ -11,7 +11,40 @@ ...@@ -11,7 +11,40 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="What would you like to do?" android:text="What would you like to do?"
android:textAppearance="?attr/textAppearanceHeadline6" android:textAppearance="?attr/textAppearanceHeadline6"
android:layout_marginBottom="40dp"/> android:layout_marginBottom="32dp"/>
<!-- Repeat / Learn toggle -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_marginBottom="24dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Repeat"
android:textAppearance="?attr/textAppearanceBody1"
android:gravity="end"
android:paddingEnd="12dp"/>
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/toggle_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Learn"
android:textAppearance="?attr/textAppearanceBody1"
android:gravity="start"
android:paddingStart="12dp"/>
</LinearLayout>
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
android:id="@+id/btn_fr_to_native" android:id="@+id/btn_fr_to_native"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment