@bojackduy/opencode-learn 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tui.js +19 -19
- package/package.json +1 -1
- package/plugins/learn-tui.tsx +18 -18
package/dist/tui.js
CHANGED
|
@@ -589,17 +589,17 @@ function QuizDialog(props) {
|
|
|
589
589
|
return;
|
|
590
590
|
}
|
|
591
591
|
if (focused() === "note") {
|
|
592
|
-
if (
|
|
592
|
+
if (lower === "tab" || seq === "\t") {
|
|
593
593
|
prevent(evt);
|
|
594
594
|
setFocused("options");
|
|
595
595
|
return;
|
|
596
596
|
}
|
|
597
|
-
if (
|
|
597
|
+
if (lower === "escape" || lower === "esc") {
|
|
598
598
|
prevent(evt);
|
|
599
599
|
setFocused("options");
|
|
600
600
|
return;
|
|
601
601
|
}
|
|
602
|
-
if (
|
|
602
|
+
if (lower === "enter" && (evt.ctrl || evt.meta)) {
|
|
603
603
|
prevent(evt);
|
|
604
604
|
setFocused("options");
|
|
605
605
|
return;
|
|
@@ -647,27 +647,27 @@ function QuizDialog(props) {
|
|
|
647
647
|
return dontKnowIdx() + 1;
|
|
648
648
|
return dontKnowIdx();
|
|
649
649
|
};
|
|
650
|
-
if (
|
|
650
|
+
if (lower === "up" || isPlainKey(evt, "k") || seq === "\x1B[A") {
|
|
651
651
|
prevent(evt);
|
|
652
652
|
setOptionIndex((i) => Math.max(0, i - 1));
|
|
653
653
|
return;
|
|
654
654
|
}
|
|
655
|
-
if (
|
|
655
|
+
if (lower === "down" || isPlainKey(evt, "j") || seq === "\x1B[B") {
|
|
656
656
|
prevent(evt);
|
|
657
657
|
setOptionIndex((i) => Math.min(maxIdx(), i + 1));
|
|
658
658
|
return;
|
|
659
659
|
}
|
|
660
|
-
if (
|
|
660
|
+
if (lower === "tab" || seq === "\t") {
|
|
661
661
|
prevent(evt);
|
|
662
662
|
setFocused("note");
|
|
663
663
|
return;
|
|
664
664
|
}
|
|
665
|
-
if (
|
|
665
|
+
if (lower === "escape" || lower === "esc") {
|
|
666
666
|
prevent(evt);
|
|
667
667
|
props.onCancel();
|
|
668
668
|
return;
|
|
669
669
|
}
|
|
670
|
-
if (
|
|
670
|
+
if (lower === "space" || seq === " ") {
|
|
671
671
|
prevent(evt);
|
|
672
672
|
const idx = optionIndex();
|
|
673
673
|
if (idx === dontKnowIdx())
|
|
@@ -692,7 +692,7 @@ function QuizDialog(props) {
|
|
|
692
692
|
}
|
|
693
693
|
return;
|
|
694
694
|
}
|
|
695
|
-
if (
|
|
695
|
+
if (lower === "enter" || seq === "\r") {
|
|
696
696
|
prevent(evt);
|
|
697
697
|
const idx = optionIndex();
|
|
698
698
|
if (idx === dontKnowIdx())
|
|
@@ -715,7 +715,7 @@ function QuizDialog(props) {
|
|
|
715
715
|
}
|
|
716
716
|
return;
|
|
717
717
|
}
|
|
718
|
-
if (seq === "ctrl+j" ||
|
|
718
|
+
if (seq === "ctrl+j" || lower === "enter" && evt.ctrl) {
|
|
719
719
|
prevent(evt);
|
|
720
720
|
submitSelect();
|
|
721
721
|
return;
|
|
@@ -1683,12 +1683,12 @@ function QuizBatchDialog(props) {
|
|
|
1683
1683
|
return;
|
|
1684
1684
|
}
|
|
1685
1685
|
if (focused() === "note") {
|
|
1686
|
-
if (
|
|
1686
|
+
if (lower === "tab" || seq === "\t") {
|
|
1687
1687
|
prevent(evt);
|
|
1688
1688
|
setFocused("options");
|
|
1689
1689
|
return;
|
|
1690
1690
|
}
|
|
1691
|
-
if (
|
|
1691
|
+
if (lower === "escape" || lower === "esc") {
|
|
1692
1692
|
prevent(evt);
|
|
1693
1693
|
setFocused("options");
|
|
1694
1694
|
return;
|
|
@@ -1713,27 +1713,27 @@ function QuizBatchDialog(props) {
|
|
|
1713
1713
|
} catch {}
|
|
1714
1714
|
return;
|
|
1715
1715
|
}
|
|
1716
|
-
if (
|
|
1716
|
+
if (lower === "up" || isPlainKeyBatch(evt, "k") || seq === "\x1B[A") {
|
|
1717
1717
|
prevent(evt);
|
|
1718
1718
|
setOptionIndex((i) => Math.max(0, i - 1));
|
|
1719
1719
|
return;
|
|
1720
1720
|
}
|
|
1721
|
-
if (
|
|
1721
|
+
if (lower === "down" || isPlainKeyBatch(evt, "j") || seq === "\x1B[B") {
|
|
1722
1722
|
prevent(evt);
|
|
1723
1723
|
setOptionIndex((i) => Math.min(isMulti() ? submitIdx() : dontKnowIdx(), i + 1));
|
|
1724
1724
|
return;
|
|
1725
1725
|
}
|
|
1726
|
-
if (
|
|
1726
|
+
if (lower === "tab" || seq === "\t") {
|
|
1727
1727
|
prevent(evt);
|
|
1728
1728
|
setFocused("note");
|
|
1729
1729
|
return;
|
|
1730
1730
|
}
|
|
1731
|
-
if (
|
|
1731
|
+
if (lower === "escape" || lower === "esc") {
|
|
1732
1732
|
prevent(evt);
|
|
1733
1733
|
props.onCancel();
|
|
1734
1734
|
return;
|
|
1735
1735
|
}
|
|
1736
|
-
if (
|
|
1736
|
+
if (lower === "space" || seq === " ") {
|
|
1737
1737
|
prevent(evt);
|
|
1738
1738
|
const i = optionIndex();
|
|
1739
1739
|
if (i === dontKnowIdx()) {
|
|
@@ -1759,7 +1759,7 @@ function QuizBatchDialog(props) {
|
|
|
1759
1759
|
}
|
|
1760
1760
|
return;
|
|
1761
1761
|
}
|
|
1762
|
-
if (
|
|
1762
|
+
if (lower === "enter" || seq === "\r") {
|
|
1763
1763
|
prevent(evt);
|
|
1764
1764
|
const i = optionIndex();
|
|
1765
1765
|
if (i === dontKnowIdx()) {
|
|
@@ -1783,7 +1783,7 @@ function QuizBatchDialog(props) {
|
|
|
1783
1783
|
}
|
|
1784
1784
|
return;
|
|
1785
1785
|
}
|
|
1786
|
-
if (seq === "ctrl+j" ||
|
|
1786
|
+
if (seq === "ctrl+j" || lower === "enter" && evt.ctrl) {
|
|
1787
1787
|
prevent(evt);
|
|
1788
1788
|
submitSelect();
|
|
1789
1789
|
return;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@bojackduy/opencode-learn",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.1",
|
|
5
5
|
"description": "Pi learn system for OpenCode — Socratic teaching, graded quiz, Obsidian md_log, and visual makers. Port of amosblomqvist/learn (video: How I Use AI to Learn Things) to OpenCode.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
package/plugins/learn-tui.tsx
CHANGED
|
@@ -286,9 +286,9 @@ function QuizDialog(props: {
|
|
|
286
286
|
}
|
|
287
287
|
// Note focused: handle Tab/Esc/Enter to exit note, otherwise let input handle typing
|
|
288
288
|
if (focused() === "note") {
|
|
289
|
-
if (
|
|
290
|
-
if (
|
|
291
|
-
if (
|
|
289
|
+
if (lower === "tab" || seq === "\t") { prevent(evt); setFocused("options"); return }
|
|
290
|
+
if (lower === "escape" || lower === "esc") { prevent(evt); setFocused("options"); return }
|
|
291
|
+
if (lower === "enter" && (evt.ctrl || evt.meta)) { prevent(evt); setFocused("options"); return }
|
|
292
292
|
// Allow typing to go to input; don't prevent
|
|
293
293
|
return
|
|
294
294
|
}
|
|
@@ -303,11 +303,11 @@ function QuizDialog(props: {
|
|
|
303
303
|
if (note().trim() && !selected().size && !dontKnow()) return dontKnowIdx() + 1
|
|
304
304
|
return dontKnowIdx()
|
|
305
305
|
}
|
|
306
|
-
if (
|
|
307
|
-
if (
|
|
308
|
-
if (
|
|
309
|
-
if (
|
|
310
|
-
if (
|
|
306
|
+
if (lower === "up" || isPlainKey(evt,"k") || seq === "\x1b[A") { prevent(evt); setOptionIndex(i => Math.max(0, i - 1)); return }
|
|
307
|
+
if (lower === "down" || isPlainKey(evt,"j") || seq === "\x1b[B") { prevent(evt); setOptionIndex(i => Math.min(maxIdx(), i + 1)); return }
|
|
308
|
+
if (lower === "tab" || seq === "\t") { prevent(evt); setFocused("note"); return }
|
|
309
|
+
if (lower === "escape" || lower === "esc") { prevent(evt); props.onCancel(); return }
|
|
310
|
+
if (lower === "space" || seq === " ") {
|
|
311
311
|
prevent(evt)
|
|
312
312
|
const idx = optionIndex()
|
|
313
313
|
if (idx === dontKnowIdx()) handleDontKnow()
|
|
@@ -321,7 +321,7 @@ function QuizDialog(props: {
|
|
|
321
321
|
}
|
|
322
322
|
return
|
|
323
323
|
}
|
|
324
|
-
if (
|
|
324
|
+
if (lower === "enter" || seq === "\r") {
|
|
325
325
|
prevent(evt)
|
|
326
326
|
const idx = optionIndex()
|
|
327
327
|
if (idx === dontKnowIdx()) handleDontKnow()
|
|
@@ -333,7 +333,7 @@ function QuizDialog(props: {
|
|
|
333
333
|
}
|
|
334
334
|
return
|
|
335
335
|
}
|
|
336
|
-
if (seq === "ctrl+j" || (
|
|
336
|
+
if (seq === "ctrl+j" || (lower === "enter" && (evt as any).ctrl)) {
|
|
337
337
|
prevent(evt); submitSelect(); return
|
|
338
338
|
}
|
|
339
339
|
})
|
|
@@ -654,16 +654,16 @@ function QuizBatchDialog(props: {
|
|
|
654
654
|
if (lower==="pageup"||seq==="\x1b[5~"){ prevent(evt); try{scrollRefBatch?.scrollBy(-scrollAmountBatch()); setTimeout(updateScrollBatch,30)}catch{} return }
|
|
655
655
|
if (lower==="pagedown"||seq==="\x1b[6~"){ prevent(evt); try{scrollRefBatch?.scrollBy(scrollAmountBatch()); setTimeout(updateScrollBatch,30)}catch{} return }
|
|
656
656
|
if(lower==="enter"||seq==="\r"||lower==="escape"||lower==="esc"){ prevent(evt); goNext() } return }
|
|
657
|
-
if(focused()==="note"){ if(
|
|
657
|
+
if(focused()==="note"){ if(lower==="tab"||seq==="\t"){prevent(evt); setFocused("options"); return} if(lower==="escape"||lower==="esc"){prevent(evt); setFocused("options"); return} return }
|
|
658
658
|
if(phase()==="select" && (isPlainKeyBatch(evt,"d")||seq==="\x04")){ prevent(evt); try{scrollRefBatch?.scrollBy(scrollAmountBatch()); setTimeout(updateScrollBatch,30); setTimeout(updateScrollBatch,120)}catch{} return }
|
|
659
659
|
if(phase()==="select" && (isPlainKeyBatch(evt,"u")||seq==="\x15")){ prevent(evt); try{scrollRefBatch?.scrollBy(-scrollAmountBatch()); setTimeout(updateScrollBatch,30); setTimeout(updateScrollBatch,120)}catch{} return }
|
|
660
|
-
if(
|
|
661
|
-
if(
|
|
662
|
-
if(
|
|
663
|
-
if(
|
|
664
|
-
if(
|
|
665
|
-
if(
|
|
666
|
-
if(seq==="ctrl+j" || (
|
|
660
|
+
if(lower==="up"||isPlainKeyBatch(evt,"k")||seq==="\x1b[A"){prevent(evt); setOptionIndex(i=>Math.max(0,i-1)); return}
|
|
661
|
+
if(lower==="down"||isPlainKeyBatch(evt,"j")||seq==="\x1b[B"){prevent(evt); setOptionIndex(i=>Math.min(isMulti()?submitIdx():dontKnowIdx(),i+1)); return}
|
|
662
|
+
if(lower==="tab"||seq==="\t"){prevent(evt); setFocused("note"); return}
|
|
663
|
+
if(lower==="escape"||lower==="esc"){prevent(evt); props.onCancel(); return}
|
|
664
|
+
if(lower==="space"||seq===" "){prevent(evt); const i=optionIndex(); if(i===dontKnowIdx()){ const willBe=!dontKnow(); setDontKnow(willBe); if(willBe) setSelected(new Map()); } else if(isMulti() && i===submitIdx()) submitSelect(); else if(isMulti()) toggle(i); else { const o=cur().options[i]; if(o){setSelected(new Map([[`opt:${i}`,{label:o.label,value:o.value,index:i+1}]])); setDontKnow(false); submitSelect()} } return}
|
|
665
|
+
if(lower==="enter"||seq==="\r"){prevent(evt); const i=optionIndex(); if(i===dontKnowIdx()){ const willBe=!dontKnow(); setDontKnow(willBe); if(willBe) setSelected(new Map()); } else if(isMulti()) submitSelect(); else { const o=cur().options[i]; if(o){setSelected(new Map([[`opt:${i}`,{label:o.label,value:o.value,index:i+1}]])); setDontKnow(false); submitSelect()} } return}
|
|
666
|
+
if(seq==="ctrl+j" || (lower==="enter" && evt.ctrl)){prevent(evt); submitSelect(); return}
|
|
667
667
|
} catch(e){ tlog("useKeyboard batch failed", String(e)) }
|
|
668
668
|
})
|
|
669
669
|
return (
|