| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
style(ai): use Phosphor duotone icons in AI UI (replace lucide) Swap the icons in all AI components added by this PR (image picker/button, quiz/scenario/assignment generators, and the editor block AI buttons) to Phosphor duotone. | 3 个月前 | |
chore: replace em dashes in comments and docstrings Comments only; no runtime strings, UI copy or behavior changed. | 12 天前 | |
feat(quiz): explicit single- and multiple-response questions The quiz builder had no way to say whether a question is pick-one or select-all-that-apply. Storage already allowed several correct options and the grader already did an exact-set match, so multi-answer worked by accident: nothing enforced single-select when authoring, and the learner got no affordance telling the two apart. - Questions carry response_type (single|multiple) and tasks carry grading_mode (all_or_nothing|partial_credit). Both live in the opaque contents JSON, so there is no migration. - Content authored before this has neither field. resolve_response_type is the single place inference lives: 2+ correct options was always a de-facto select-all. Stored questions are never rewritten, and an unrecognised value falls back to inference so a typo cannot grade a 3-correct question as a pick-one. - Single-response marks and selects like a radio group; multiple keeps toggling and says so. Both get role/aria-checked and keyboard activation, and a circle-vs-square indicator. - Partial credit awards (correct - incorrect) / total_correct, clamped, so selecting everything scores 0 rather than full marks. Default stays all-or-nothing, which reduces to the previous formula exactly. - The server grader and the learner's preview grader run the same shared helper on each side, since a divergence there shows one score and stores another. - _strip_answer_key stamps the resolved response_type on the outgoing copy: the learner needs the affordance, and the key it would otherwise be inferred from has just been removed. | 1 个月前 | |
refactor(web): convert physical direction utilities to logical ones Machine-applied output of scripts/codemod-logical.mjs across the app, plus the handful of transforms it cannot do safely. ml-/mr- become ms-/me-, pl-/pr- become ps-/pe-, left-/right- become start-/end-, and text-left, border-l and the rounded corners follow. This is a pure rename: every pair emits identical CSS under dir=ltr, verified against tailwindcss 4.2.1, so left-to-right rendering is unchanged and any visual diff there is a bug rather than a judgement call. Transforms carry a physical sign, so renaming them is wrong. Toggle knobs, hover nudges and sliding panels get explicit rtl: pairs, and motion x-offsets multiply by the direction factor from useDirection. The step wizard folds text direction into its slide axis so "next" always moves toward the inline end. Flyout menus needed a real fix rather than a rename. HoverMenu positioned itself with `left: rect.right + 8`, which is fine with the sidebar on the left but placed the menu past the viewport once the sidebar moved to the right edge — in Arabic the menus simply did not appear. It now anchors to whichever edge it grows away from, which also avoids needing the menu's width before it renders. The admin list tooltips had the same bug. Inline styles stay physical wherever the value comes from a measured DOM rect: those are already in viewport coordinates, so converting them would flip twice. Only static design offsets moved to logical properties. Also removes the dead nx-* classes on the 404 page. They came from a Nextra template and never existed in this project's Tailwind build, so they emitted nothing — including the ltr:/rtl: pair, which looked like RTL support but was not. | 2 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 3 个月前 | ||
| 12 天前 | ||
| 1 个月前 | ||
| 2 个月前 |