-
-
Notifications
You must be signed in to change notification settings - Fork 93
Expand file tree
/
Copy pathTutorialStep.tsx
More file actions
105 lines (99 loc) · 2.88 KB
/
TutorialStep.tsx
File metadata and controls
105 lines (99 loc) · 2.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import type { ActiveTutorialNoErrorsState } from "@cursorless/lib-common";
import type { WebviewApi } from "vscode-webview";
import { ArrowLeftIcon } from "./ArrowLeftIcon";
import { ArrowRightIcon } from "./ArrowRightIcon";
import { CloseIcon } from "./CloseIcon";
import { Command } from "./Command";
import { ProgressBar } from "./ProgressBar";
interface Props {
state: ActiveTutorialNoErrorsState;
vscode: WebviewApi<undefined>;
}
export function TutorialStep({ state, vscode }: Props) {
const renderProgress = () => {
return (
<div className="mt-2 mb-2 d-flex align-items-center gap-1">
<ProgressBar
currentStep={state.stepNumber}
stepCount={state.stepCount}
/>
<button
className="btn btn-link p-0 d-inline-flex"
onClick={() =>
vscode.postMessage({
type: "list",
})
}
>
<CloseIcon />
</button>
</div>
);
};
const renderStepContent = () => {
if (!state.preConditionsMet) {
return (
<>
<div>Whoops! Looks like you've stepped off the beaten path.</div>
<div className="mt-1">
Feel free to keep playing, then say{" "}
<Command spokenForm="tutorial resume" /> to resume the tutorial.
</div>
</>
);
}
return (
<>
{state.stepContent.map((paragraph, i) => (
<div key={i} className="mt-1">
{paragraph.map((fragment, j) => {
switch (fragment.type) {
case "string":
return <span key={j}>{fragment.value}</span>;
case "command":
return <Command key={j} spokenForm={fragment.value} />;
case "term":
return <span key={j}>"{fragment.value}"</span>;
default: {
// Ensure we handle all cases
const _unused: never = fragment;
}
}
})}
</div>
))}
<div className="mt-2 d-flex w-100 align-items-center justify-content-between">
<button
className="btn btn-link p-0 d-inline-flex"
onClick={() =>
vscode.postMessage({
type: "previous",
})
}
>
<ArrowLeftIcon size={12} />
</button>
<span className="tutorial-step-counter">
{state.stepNumber + 1} / {state.stepCount}{" "}
</span>
<button
className="btn btn-link p-0 d-inline-flex"
onClick={() =>
vscode.postMessage({
type: "next",
})
}
>
<ArrowRightIcon size={12} />
</button>
</div>
</>
);
};
return (
<>
{renderProgress()}
{renderStepContent()}
</>
);
}