Skip to content

Commit c222cb0

Browse files
authored
feat: add sample brushes (#65)
1 parent 12da3d2 commit c222cb0

File tree

13 files changed

+240
-19
lines changed

13 files changed

+240
-19
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
"spelling": "^2.0.1"
6262
},
6363
"dependencies": {
64-
"react-scripts": "^3.4.1",
6564
"@material-ui/styles": "^4.9.0",
6665
"@semantic-release/git": "^9.0.0",
6766
"@sentry/browser": "^5.15.4",
@@ -84,9 +83,11 @@
8483
"react-dropzone": "^10.1.8",
8584
"react-icons": "^3.9.0",
8685
"react-image-annotate": "^0.2.4",
86+
"react-scripts": "^3.4.1",
8787
"react-select": "^3.0.8",
8888
"rfc6902": "^3.0.4",
8989
"seamless-immutable": "^7.1.4",
90+
"seed-random": "^2.2.0",
9091
"styled-components": "^5.0.0",
9192
"use-event-callback": "^0.1.0",
9293
"ytdl-core": "^2.0.1"
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// @flow
2+
3+
import React, { useState, useMemo, useRef, useEffect } from "react"
4+
import { useLocalStorage } from "react-use"
5+
import { createPortal } from "react-dom"
6+
import IconButton from "@material-ui/core/IconButton"
7+
import BrushIcon from "@material-ui/icons/Brush"
8+
import ArrowForwardIcon from "@material-ui/icons/ArrowForward"
9+
import { styled } from "@material-ui/core/styles"
10+
import * as colors from "@material-ui/core/colors"
11+
import Button from "@material-ui/core/Button"
12+
import TextField from "@material-ui/core/TextField"
13+
import InputAdornment from "@material-ui/core/InputAdornment"
14+
import AddBoxTwoTone from "@material-ui/icons/AddBoxTwoTone"
15+
import ExitToAppIcon from "@material-ui/icons/ExitToApp"
16+
import CircularProgress from "@material-ui/core/CircularProgress"
17+
import HeaderPopupBox from "../HeaderPopupBox"
18+
import useEventCallback from "use-event-callback"
19+
import memoize from "lodash/memoize"
20+
import getBrushColorPalette from "../../utils/get-brush-color-palette.js"
21+
22+
const Container = styled("div")({ position: "relative" })
23+
const BrushCircle = styled("div")(({ color }) => ({
24+
display: "inline",
25+
marginRight: 8,
26+
backgroundColor: color[700],
27+
width: 24,
28+
height: 24,
29+
borderRadius: 20,
30+
}))
31+
32+
const OtherColorContainers = styled("div")({
33+
paddingTop: 10,
34+
padding: 4,
35+
display: "flex",
36+
flexWrap: "wrap",
37+
})
38+
39+
const StyledIconButton = styled(IconButton)(({ iconColor, selected }) => ({
40+
display: "flex",
41+
justifyContent: "center",
42+
alignItems: "center",
43+
backgroundColor: iconColor[700],
44+
border: selected ? `4px solid ${iconColor["A200"]}` : "4px solid #fff",
45+
boxSizing: "content-box",
46+
margin: 4,
47+
transition: "transform 200ms linear",
48+
"&:hover": {
49+
backgroundColor: iconColor[800],
50+
transform: "scale(1.2,1.2)",
51+
},
52+
"&:active": {
53+
transition: "transform 100ms linear",
54+
transform: "scale(1.4,1.4)",
55+
},
56+
}))
57+
58+
const StyledButton = styled(Button)(({ selected, iconColor }) => ({
59+
justifyContent: "flex-start",
60+
marginTop: 4,
61+
marginBottom: 4,
62+
paddingTop: 8,
63+
paddingBottom: 8,
64+
backgroundColor: selected ? iconColor[50] : "#fff",
65+
border: selected ? `2px solid ${iconColor[200]}` : "2px solid #fff",
66+
"&:hover": {
67+
backgroundColor: selected ? iconColor[100] : "none",
68+
},
69+
}))
70+
71+
export default ({ selectedBrush, onChangeSelectedBrush }) => {
72+
const [open, changeOpen] = useState(false)
73+
const handleClick = useEventCallback((color) =>
74+
memoize(() => onChangeSelectedBrush(color))
75+
)
76+
77+
return (
78+
<Container
79+
onMouseEnter={() => changeOpen(true)}
80+
onMouseLeave={() => changeOpen(false)}
81+
>
82+
<IconButton>
83+
<BrushIcon
84+
style={{ color: getBrushColorPalette(selectedBrush)[800] }}
85+
/>
86+
</IconButton>
87+
<HeaderPopupBox open={open}>
88+
<h1>Sample Brushes</h1>
89+
<StyledButton
90+
selected={selectedBrush === "complete" || selectedBrush === "blue"}
91+
iconColor={colors.blue}
92+
fullWidth
93+
onClick={handleClick("complete")}
94+
>
95+
<BrushCircle color={colors.blue} />
96+
Complete
97+
</StyledButton>
98+
<StyledButton
99+
selected={
100+
selectedBrush === "review" || selectedBrush === "deepOrange"
101+
}
102+
iconColor={colors.deepOrange}
103+
fullWidth
104+
onClick={handleClick("review")}
105+
>
106+
<BrushCircle color={colors.deepOrange} />
107+
Review
108+
</StyledButton>
109+
<OtherColorContainers>
110+
<StyledIconButton
111+
onClick={handleClick("green")}
112+
selected={selectedBrush === "green"}
113+
iconColor={colors.green}
114+
/>
115+
<StyledIconButton
116+
onClick={handleClick("purple")}
117+
selected={selectedBrush === "purple"}
118+
iconColor={colors.purple}
119+
/>
120+
<StyledIconButton
121+
onClick={handleClick("pink")}
122+
selected={selectedBrush === "pink"}
123+
iconColor={colors.pink}
124+
/>
125+
<StyledIconButton
126+
onClick={handleClick("cyan")}
127+
selected={selectedBrush === "cyan"}
128+
iconColor={colors.cyan}
129+
/>
130+
<StyledIconButton
131+
onClick={handleClick("orange")}
132+
selected={selectedBrush === "orange"}
133+
iconColor={colors.orange}
134+
/>
135+
<StyledIconButton
136+
onClick={handleClick("indigo")}
137+
selected={selectedBrush === "indigo"}
138+
iconColor={colors.indigo}
139+
/>
140+
</OtherColorContainers>
141+
</HeaderPopupBox>
142+
</Container>
143+
)
144+
}

src/components/CollaborateButton/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const popupBoxBeforeAndAfter = {
3131
}
3232
const PopupBox = styled("div")({
3333
position: "absolute",
34+
zIndex: 10,
3435
top: 45,
3536
padding: 16,
3637
boxSizing: "border-box",

src/components/DesktopApp/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default () => {
3939
recentItems,
4040
} = useFileHandler()
4141

42-
const [oha, changeOHA] = useState()
42+
const [selectedBrush, setSelectedBrush] = useState("complete")
4343
const [errors, addError] = useErrors()
4444
const { addToast } = useToasts()
4545

@@ -111,6 +111,8 @@ export default () => {
111111
onOpenRecentItem: openRecentItem,
112112
isDesktop: true,
113113
onOpenFile: openFile,
114+
selectedBrush,
115+
onChangeSelectedBrush: setSelectedBrush,
114116
}}
115117
>
116118
{!file ? (
@@ -125,6 +127,7 @@ export default () => {
125127
<OHAEditor
126128
key={file.id}
127129
{...file}
130+
selectedBrush={selectedBrush}
128131
oha={file.content}
129132
onChangeFileName={(newName) => {
130133
changeFile(setIn(file, ["fileName"], newName))

src/components/Header/index.story.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ import { action } from "@storybook/addon-actions"
99
import Header from "./"
1010

1111
storiesOf("Header", module)
12-
.add("Basic", () => (
12+
.add("Tabs", () => (
1313
<Header
1414
title="Some Header"
15-
additionalButtons={[<Button>Switch to Sample Editor</Button>]}
16-
tabs={["Settings"]}
15+
tabs={["Settings", "Samples", "Label"]}
16+
currentTab="Samples"
1717
/>
1818
))
19-
.add("Tab Test", () => (
19+
.add("Sample Color", () => (
2020
<Header
2121
title="Some Header"
2222
tabs={["Settings", "Samples", "Label"]}

src/components/HeaderPopupBox/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const popupBoxBeforeAndAfter = {
1818
}
1919
const PopupBox = styled("div")({
2020
position: "absolute",
21+
zIndex: 10,
2122
top: 45,
2223
padding: 16,
2324
boxSizing: "border-box",

src/components/HeaderToolbar/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import GithubIcon from "../Header/GithubIcon"
1818
import * as colors from "@material-ui/core/colors"
1919
import IconButton from "@material-ui/core/IconButton"
2020
import packageJSON from "../../../package.json"
21+
import BrushButton from "../BrushButton"
2122

2223
const useStyles = makeStyles((theme) => ({
2324
headerButton: {
@@ -80,6 +81,8 @@ const HeaderToolbar = ({
8081
onLeaveSession,
8182
onJoinSession,
8283
onDownload,
84+
selectedBrush,
85+
onChangeSelectedBrush,
8386
isSmall,
8487
}) => {
8588
const c = useStyles()
@@ -103,6 +106,12 @@ const HeaderToolbar = ({
103106
onJoinSession={onJoinSession}
104107
/>
105108
)}
109+
{fileOpen && (
110+
<BrushButton
111+
selectedBrush={selectedBrush}
112+
onChangeSelectedBrush={onChangeSelectedBrush}
113+
/>
114+
)}
106115
{!isDesktop && fileOpen && <DownloadButton onDownload={onDownload} />}
107116
<div className={c.grow} />
108117
{additionalButtons}

src/components/LocalStorageApp/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export default () => {
3636
recentItems,
3737
} = useFileHandler()
3838
const [errors, addError] = useErrors()
39+
const [selectedBrush, setSelectedBrush] = useState("complete")
3940

4041
const onCreateTemplate = useEventCallback((template) => {
4142
changeFile({
@@ -96,6 +97,8 @@ export default () => {
9697
onCreateSession: makeSession,
9798
fileOpen: Boolean(file),
9899
onDownload,
100+
onChangeSelectedBrush: setSelectedBrush,
101+
selectedBrush,
99102
}}
100103
>
101104
{!file ? (
@@ -111,6 +114,7 @@ export default () => {
111114
<OHAEditor
112115
key={file.id}
113116
{...file}
117+
selectedBrush={selectedBrush}
114118
inSession={inSession}
115119
oha={file.content}
116120
onChangeFileName={(newName) => {

src/components/OHAEditor/index.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export default ({
6666
onChangeOHA = () => null,
6767
onFileDrop,
6868
initialMode = "settings", //= "samples"
69+
selectedBrush = "complete",
6970
}) => {
7071
const c = useStyles()
7172
const { addToast } = useToasts()
@@ -247,6 +248,20 @@ export default ({
247248
["taskOutput", singleSampleOHA.sampleIndex],
248249
output
249250
)
251+
252+
if (
253+
singleSampleOHA.taskData[0].brush !== selectedBrush &&
254+
!(
255+
singleSampleOHA.taskData[0].brush === undefined &&
256+
selectedBrush === "complete"
257+
)
258+
) {
259+
newOHA = setIn(
260+
newOHA,
261+
["taskData", singleSampleOHA.sampleIndex, "brush"],
262+
selectedBrush
263+
)
264+
}
250265
changeSingleSampleOHA(
251266
setIn(singleSampleOHA, ["taskOutput", relativeIndex], output)
252267
)
@@ -319,6 +334,7 @@ export default ({
319334
/>
320335
<SampleGrid
321336
count={(oha.taskData || []).length}
337+
taskData={oha.taskData || []}
322338
completed={(oha.taskOutput || []).map(Boolean)}
323339
onClick={(sampleIndex) => {
324340
changeSingleSampleOHA({

src/components/SampleGrid/index.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ import range from "lodash/range"
88
import * as colors from "@material-ui/core/colors"
99
import classNames from "classnames"
1010
import TablePagination from "@material-ui/core/TablePagination"
11+
import getBrushColorPalette from "../../utils/get-brush-color-palette"
1112

1213
const Container = styled("div")({
1314
flexWrap: "wrap",
1415
})
15-
const SampleDiv = styled("div")({
16+
const SampleDiv = styled("div")(({ color }) => ({
1617
margin: 4,
1718
padding: 4,
18-
backgroundColor: colors.grey[300],
19+
backgroundColor: color[500],
1920
display: "inline-flex",
2021
fontSize: 11,
2122
textAlign: "center",
@@ -25,15 +26,12 @@ const SampleDiv = styled("div")({
2526
cursor: "pointer",
2627
userSelect: "none",
2728
transition: "box-shadow 200ms ease, transform 200ms ease",
28-
"&.completed": {
29-
backgroundColor: colors.blue[500],
30-
color: "#fff",
31-
},
29+
color: color.isFaded ? "#000" : "#fff",
3230
"&.selected": {
33-
boxShadow: `0px 0px 2px 1px ${colors.blue[400]}`,
31+
boxShadow: `0px 0px 2px 1px ${color["A200"]}`,
3432
transform: "scale(1.05,1.05)",
3533
},
36-
})
34+
}))
3735

3836
const Sample = memo(
3937
({
@@ -44,6 +42,7 @@ const Sample = memo(
4442
onMouseDown,
4543
onMouseUp,
4644
onMouseEnter,
45+
brush,
4746
}) => {
4847
return (
4948
<SampleDiv
@@ -52,6 +51,7 @@ const Sample = memo(
5251
onMouseDown={() => onMouseDown(index)}
5352
onMouseUp={() => onMouseUp(index)}
5453
onMouseEnter={() => onMouseEnter(index)}
54+
color={getBrushColorPalette(brush)}
5555
>
5656
{index}
5757
</SampleDiv>
@@ -61,12 +61,13 @@ const Sample = memo(
6161
return (
6262
p.index === n.index &&
6363
p.completed === n.completed &&
64-
p.selected === n.selected
64+
p.selected === n.selected &&
65+
p.brush === n.brush
6566
)
6667
}
6768
)
6869

69-
export default ({ count, completed = [], onClick }) => {
70+
export default ({ count, completed = [], taskData, onClick }) => {
7071
const [samplesPerPage, changeSamplesPerPage] = useLocalStorage(
7172
"samplesPerPage",
7273
100
@@ -118,6 +119,9 @@ export default ({ count, completed = [], onClick }) => {
118119
key={i}
119120
index={i}
120121
completed={completed[i]}
122+
brush={
123+
completed[i] ? taskData[i].brush || "complete" : "incomplete"
124+
}
121125
selected={selectRange && i >= selectRange[0] && i < selectRange[1]}
122126
onMouseDown={startSelectRange}
123127
onMouseEnter={moveSelectRange}

0 commit comments

Comments
 (0)