Skip to content

Commit 1240503

Browse files
Sane hint logic, animate Train model.
1 parent a9dbf5d commit 1240503

File tree

7 files changed

+207
-97
lines changed

7 files changed

+207
-97
lines changed

src/components/DataSamplesTable.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { FormattedMessage, useIntl } from "react-intl";
1111
import { useConnectActions } from "../connect-actions-hooks";
1212
import { useConnectionStage } from "../connection-stage-hooks";
1313
import { keyboardShortcuts, useShortcut } from "../keyboard-shortcut-hooks";
14-
import { ActionData } from "../model";
14+
import { ActionData, DataSamplesPageHint } from "../model";
1515
import { useStore } from "../store";
1616
import { recordButtonId } from "./ActionDataSamplesCard";
1717
import { actionNameInputId } from "./ActionNameCard";
@@ -53,13 +53,13 @@ const headings: GridColumnHeadingItemProps[] = [
5353
interface DataSamplesTableProps {
5454
selectedActionIdx: number;
5555
setSelectedActionIdx: (idx: number) => void;
56-
showHints: boolean;
56+
hint: DataSamplesPageHint;
5757
}
5858

5959
const DataSamplesTable = ({
6060
selectedActionIdx: selectedActionIdx,
6161
setSelectedActionIdx: setSelectedActionIdx,
62-
showHints,
62+
hint,
6363
}: DataSamplesTableProps) => {
6464
const actions = useStore((s) => s.actions);
6565
// Default to first action being selected if last action is deleted.
@@ -215,13 +215,12 @@ const DataSamplesTable = ({
215215
<DataSamplesTableRow
216216
key={action.ID}
217217
action={action}
218-
actions={actions}
219218
newRecordingId={newRecordingId}
220219
clearNewRecordingId={() => setNewRecordingId(undefined)}
221220
selected={selectedAction.ID === action.ID}
222221
onSelectRow={() => setSelectedActionIdx(idx)}
223222
onRecord={handleRecord}
224-
showHints={showHints}
223+
hint={hint}
225224
onDeleteAction={deleteActionConfirmOnOpen}
226225
renameShortcutScopeRef={renameActionShortcutScopeRef}
227226
/>

src/components/DataSamplesTableHints.tsx

Lines changed: 105 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,125 @@
33
*
44
* SPDX-License-Identifier: MIT
55
*/
6-
import { Box, GridItem, HStack, Stack, Text, VStack } from "@chakra-ui/react";
6+
import {
7+
AspectRatio,
8+
Box,
9+
HStack,
10+
Image,
11+
Stack,
12+
Text,
13+
VStack,
14+
} from "@chakra-ui/react";
715
import { FormattedMessage } from "react-intl";
816
import { useConnectionStage } from "../connection-stage-hooks";
17+
import { Action } from "../model";
918
import Emoji, { animations } from "./Emoji";
1019
import EmojiArrow from "./EmojiArrow";
1120
import UpCurveArrow from "./UpCurveArrow";
21+
import moveMicrobitImage from "../images/move-microbit.svg";
1222

1323
export const NameActionHint = () => {
1424
return (
15-
<GridItem h="120px">
16-
<VStack m={0} p={2} w={200} transform="translate(-30px, 45px)">
17-
<Stack spacing={0} color="brand.500" ml={-8}>
18-
<EmojiArrow />
19-
<Box transform="rotate(-8deg)">
20-
<Emoji ml="25px" boxSize={16} animation={animations.spin} />
21-
</Box>
22-
</Stack>
23-
<Text textAlign="center">
24-
<FormattedMessage id="name-action-hint" />
25-
</Text>
26-
</VStack>
27-
</GridItem>
25+
<VStack m={0} p={2} w={200} transform="translate(-30px, 45px)">
26+
<Stack spacing={0} color="brand.500" ml={-8}>
27+
<EmojiArrow />
28+
<Box transform="rotate(-8deg)">
29+
<Emoji ml="25px" boxSize={16} animation={animations.spin} />
30+
</Box>
31+
</Stack>
32+
<Text textAlign="center">
33+
<FormattedMessage id="name-action-hint" />
34+
</Text>
35+
</VStack>
2836
);
2937
};
3038

3139
export const RecordButtonHint = () => {
3240
const { isConnected } = useConnectionStage();
3341
return (
34-
<GridItem h="120px">
35-
<HStack m={0} p={2} transform="translateX(65px)" w="calc(100% - 65px)">
36-
<UpCurveArrow w="60px" h="93px" color="brand.500" />
37-
{isConnected ? (
38-
<Text textAlign="center" maxW={200}>
39-
<FormattedMessage id="record-hint-button-b" />
40-
</Text>
41-
) : (
42-
<Text textAlign="center" maxW={125}>
43-
<FormattedMessage id="record-hint" />
44-
</Text>
45-
)}
42+
<HStack m={0} p={2} transform="translateX(65px)" w="calc(100% - 65px)">
43+
<UpCurveArrow w="60px" h="93px" color="brand.500" />
44+
{/* Emoji? Or explain button B visually? */}
45+
{isConnected ? (
46+
<Text textAlign="center" maxW={200}>
47+
<FormattedMessage id="record-hint-button-b" />
48+
</Text>
49+
) : (
50+
<Text textAlign="center" maxW={125}>
51+
<FormattedMessage id="record-hint" />
52+
</Text>
53+
)}
54+
</HStack>
55+
);
56+
};
57+
58+
export const RecordMoreHint = ({ recorded }: { recorded: number }) => {
59+
return (
60+
<HStack m={0} p={2} transform="translateX(65px)" w="calc(100% - 65px)">
61+
<UpCurveArrow w="60px" h="93px" color="brand.500" />
62+
<Emoji
63+
transform="rotate(-8deg)"
64+
leftEye={recorded == 2 ? "tick" : "round"}
65+
/>
66+
<Text maxW="20ch" textAlign="center">
67+
{recorded === 1
68+
? "Record at least 2 more data samples"
69+
: "Record at least 1 more data sample"}
70+
</Text>
71+
</HStack>
72+
);
73+
};
74+
75+
export const AddActionHint = ({ action }: { action: Action }) => {
76+
return (
77+
<HStack
78+
m={0}
79+
position="absolute"
80+
left={16}
81+
bottom={12}
82+
spacing={3}
83+
alignItems="flex-start"
84+
>
85+
<HStack spacing={0} alignItems="flex-start">
86+
<EmojiArrow
87+
w="60px"
88+
h="93px"
89+
color="brand.500"
90+
transform="rotate(-80deg)"
91+
/>
92+
<Box transform="rotate(-8deg)">
93+
<Emoji
94+
leftEye="tick"
95+
rightEye="tick"
96+
pb={3}
97+
animation={animations.spin}
98+
/>
99+
</Box>
46100
</HStack>
47-
</GridItem>
101+
<Text textAlign="center">
102+
Finished recording for {action.name}?<br />
103+
Add another action
104+
</Text>
105+
</HStack>
106+
);
107+
};
108+
109+
export const MoveMicrobitHint = () => {
110+
return (
111+
<HStack m={0} position="absolute" right={16} bottom={12} spacing={0}>
112+
<EmojiArrow
113+
mt={8}
114+
transform="rotate(-80deg)"
115+
transformOrigin="center"
116+
color="brand.500"
117+
/>
118+
{/* Ratio hides excess whitespace */}
119+
<AspectRatio ratio={30 / 25} w={36} animation={animations.wobble}>
120+
<Image src={moveMicrobitImage} />
121+
</AspectRatio>
122+
<Text textAlign="center" w={48}>
123+
Shake the micro:bit and watch the graph change
124+
</Text>
125+
</HStack>
48126
);
49127
};

src/components/DataSamplesTableRow.tsx

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,23 @@
77
import { Box, GridItem } from "@chakra-ui/react";
88
import { RefType } from "react-hotkeys-hook/dist/types";
99
import { useIntl } from "react-intl";
10-
import { ActionData } from "../model";
10+
import { ActionData, DataSamplesPageHint } from "../model";
1111
import ActionDataSamplesCard from "./ActionDataSamplesCard";
1212
import ActionNameCard, { ActionCardNameViewMode } from "./ActionNameCard";
13-
import { NameActionHint, RecordButtonHint } from "./DataSamplesTableHints";
13+
import {
14+
NameActionHint,
15+
RecordButtonHint,
16+
RecordMoreHint,
17+
} from "./DataSamplesTableHints";
1418
import { RecordingOptions } from "./RecordingDialog";
1519

1620
interface DataSamplesTableRowProps {
1721
preview?: boolean;
1822
action: ActionData;
19-
actions: ActionData[];
2023
selected: boolean;
2124
onSelectRow?: () => void;
2225
onRecord?: (recordingOptions: RecordingOptions) => void;
23-
showHints: boolean;
26+
hint: DataSamplesPageHint;
2427
newRecordingId?: number;
2528
clearNewRecordingId?: () => void;
2629
onDeleteAction?: () => void;
@@ -29,24 +32,17 @@ interface DataSamplesTableRowProps {
2932

3033
const DataSamplesTableRow = ({
3134
action,
32-
actions,
3335
selected,
3436
onSelectRow,
3537
onRecord,
3638
preview,
37-
showHints,
39+
hint,
3840
newRecordingId,
3941
clearNewRecordingId,
4042
onDeleteAction,
4143
renameShortcutScopeRef,
4244
}: DataSamplesTableRowProps) => {
4345
const intl = useIntl();
44-
const needsNameHint =
45-
actions.length === 1 &&
46-
action.name.length === 0 &&
47-
action.recordings.length === 0;
48-
const needsRecordHint =
49-
!needsNameHint && actions.length === 1 && action.recordings.length === 0;
5046
return (
5147
<>
5248
<Box
@@ -74,7 +70,11 @@ const DataSamplesTableRow = ({
7470
}
7571
/>
7672
</GridItem>
77-
{showHints && needsNameHint && <NameActionHint />}
73+
{hint === "name-action" && (
74+
<GridItem h="120px">
75+
<NameActionHint />
76+
</GridItem>
77+
)}
7878
<GridItem>
7979
{(action.name.length > 0 || action.recordings.length > 0) && (
8080
<ActionDataSamplesCard
@@ -88,11 +88,16 @@ const DataSamplesTableRow = ({
8888
/>
8989
)}
9090
</GridItem>
91-
{showHints && needsRecordHint && (
91+
{(hint === "record" || hint === "record-more") && (
9292
<>
9393
{/* Skip first column to correctly place hint. */}
9494
<GridItem />
95-
<RecordButtonHint />
95+
<GridItem h="120px">
96+
{hint === "record" && <RecordButtonHint />}
97+
{hint === "record-more" && (
98+
<RecordMoreHint recorded={action.recordings.length} />
99+
)}
100+
</GridItem>
96101
</>
97102
)}
98103
</Box>

src/components/Emoji.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,23 @@ export const animations = {
1515
transform: "rotate(-15deg)",
1616
},
1717
})} 2s`,
18+
tada: `${keyframes({
19+
"0%": {
20+
transform: "scale(1) rotate(0deg)",
21+
},
22+
"10%, 20%": {
23+
transform: "scale(0.95) rotate(-3deg)",
24+
},
25+
"30%, 50%, 70%, 90%": {
26+
transform: "scale(1.1) rotate(3deg)",
27+
},
28+
"40%, 60%, 80%": {
29+
transform: "scale(1.1) rotate(-3deg)",
30+
},
31+
"100%": {
32+
transform: "scale(1) rotate(0deg)",
33+
},
34+
})} 1s ease-in-out`,
1835
spin: `${keyframes({
1936
"0%": {
2037
transform: "rotate3d(0, 1, 0, 0deg)",
@@ -37,10 +54,12 @@ interface EmojiProps extends IconProps {
3754
const Emoji = ({
3855
leftEye = "round",
3956
rightEye = "round",
57+
boxSize = 16,
58+
color = "brand.500",
4059
...props
4160
}: EmojiProps) => {
4261
return (
43-
<Icon {...props} viewBox="0 0 124 101">
62+
<Icon boxSize={boxSize} color={color} {...props} viewBox="0 0 124 101">
4463
{/* Outline */}
4564
<path
4665
d="M88.874 0.0159531V0.00657654H34.1453V0.0159531C14.6584 0.173286 0 15.7146 0 36.3026C0 56.6373 14.4073 72.0239 33.6396 72.4399V72.46H88.5953C108.233 72.46 123.041 56.9173 123.041 36.3026C123.041 15.7093 108.371 0.162621 88.874 0.0159531ZM88.5953 57.0106L34.1084 56.9999C23.3745 56.8133 14.726 47.5906 14.726 36.2346C14.726 24.7599 23.5516 15.4586 34.4396 15.4586H88.5953C99.4792 15.4586 108.307 24.7599 108.307 36.2346C108.307 47.7092 99.4792 57.0106 88.5953 57.0106Z"

src/model.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,14 @@ export enum DataSamplesView {
223223
GraphAndDataFeatures = "graph and data features",
224224
}
225225

226+
export type DataSamplesPageHint =
227+
| null
228+
| "move-microbit"
229+
| "name-action"
230+
| "record"
231+
| "record-more"
232+
| "add-action";
233+
226234
export enum PostImportDialogState {
227235
None = "none",
228236
Error = "error",

0 commit comments

Comments
 (0)