jaltekruse / Free-Math

An offline React web application for managing digital math homework
http://freemathapp.org
71 stars 18 forks source link

WIP: FM255 - improve interactive grader UI #209

Open nvande opened 2 years ago

jaltekruse commented 2 years ago

I poked around for a little bit for getting a spinner showing while the grading page is changing problems. Here is a small diff that works, but I don't love the fact that my default spinner (that darkens the whole page) ends up flickering on and off quickly when moving between problems in a reasonable sized class.

I think ideally there would be a little delay to see if rendering can finish quickly, and if it doesn't then show the spinner. The react render is synchronous though, so its not like we can interrupt it.

Best thing I can think of to do is count up the number of expressions we will be rendering and make that a precondition to showing the spinner at all if we think it won't take too long. Also as discussed we can add pagination to this page, or fancy virtual scrolling or whatever like they use in the various table libraries to not fall over when people load a bunch of data.

Here is the diff for unconditionally showing the spinner at least:

Δ src/InteractiveGrader/GraderTabsComponent.js
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

──────────────────────────────────┐
• 7: const PROBLEMS = 'PROBLEMS'; │
──────────────────────────────────┘
  7 ⋮  7 │ const SET_CURRENT_PROBLEM = 'SET_CURRENT_PROBLEM';
  8 ⋮  8 │ const UNIQUE_ANSWERS = 'UNIQUE_ANSWERS';
  9 ⋮  9 │ const ANSWER = "ANSWER";
    ⋮ 10 │+const MODIFY_GLOBAL_WAITING_MSG = 'MODIFY_GLOBAL_WAITING_MSG';
    ⋮ 11 │+const GLOBAL_WAITING_MSG = 'GLOBAL_WAITING_MSG';
 10 ⋮ 12 │ 
 11 ⋮ 13 │ function GraderTabsComponent({gradingOverview, problems, currentProblem}) {
 12 ⋮ 14 │     return(

──────────────────────────────────────────────────────────────────────────────────┐
• 35: function GraderTabsComponent({gradingOverview, problems, currentProblem}) { │
──────────────────────────────────────────────────────────────────────────────────┘
 33 ⋮ 35 │                                         className={"fm-button-right fm-button-left fm-button fm-tab " + ((probNum === currentProblem) ? "fm-tab-selected" : "")}
 34 ⋮ 36 │                                         style={{marginBottom: "0px", borderRadius: "15px 15px 0px 0px"}}
 35 ⋮ 37 │                                         onClick={function() {
 36 ⋮    │-                                            window.ephemeralStore.dispatch(
 37 ⋮    │-                                                {type: SET_CURRENT_PROBLEM, CURRENT_PROBLEM: probNum})}}
    ⋮ 38 │+                                            window.ephemeralStore.dispatch(
    ⋮ 39 │+                                                { type : MODIFY_GLOBAL_WAITING_MSG,
    ⋮ 40 │+                                                  GLOBAL_WAITING_MSG: 'Changing problems'});
    ⋮ 41 │+
    ⋮ 42 │+                                            // try to force a render of the spinner before this state change which could cause a long render
    ⋮ 43 │+                                            window.setTimeout(() => {
    ⋮ 44 │+                                                window.ephemeralStore.dispatch(
    ⋮ 45 │+                                                    {type: SET_CURRENT_PROBLEM, CURRENT_PROBLEM: probNum})
    ⋮ 46 │+
    ⋮ 47 │+                                                // now close the spinner
    ⋮ 48 │+                                                window.setTimeout(() => {
    ⋮ 49 │+                                                    window.ephemeralStore.dispatch(
    ⋮ 50 │+                                                        { type : MODIFY_GLOBAL_WAITING_MSG,
    ⋮ 51 │+                                                          GLOBAL_WAITING_MSG: false});
    ⋮ 52 │+                                                });
    ⋮ 53 │+                                            });
    ⋮ 54 │+                                        }}
 38 ⋮ 55 │                                         content={
 39 ⋮ 56 │                                             (<div>
 40 ⋮ 57 │                                                 <h3>{label}</h3>