Added nickname editing

This commit is contained in:
Mitchell McCaffrey 2020-04-06 15:38:36 +10:00
parent ac9189c606
commit bd5cfbbd4b
4 changed files with 165 additions and 69 deletions

View File

@ -6,7 +6,7 @@ import {
Image as UIImage, Image as UIImage,
Flex, Flex,
Label, Label,
Input Input,
} from "theme-ui"; } from "theme-ui";
import Modal from "./Modal"; import Modal from "./Modal";
@ -38,13 +38,13 @@ function AddMapButton({ onMapChanged }) {
const file = event.target.files[0]; const file = event.target.files[0];
const url = URL.createObjectURL(file); const url = URL.createObjectURL(file);
let image = new Image(); let image = new Image();
image.onload = function() { image.onload = function () {
mapDataRef.current = { mapDataRef.current = {
file, file,
rows, rows,
columns, columns,
width: image.width, width: image.width,
height: image.height height: image.height,
}; };
setImageLoaded(true); setImageLoaded(true);
}; };
@ -85,7 +85,7 @@ function AddMapButton({ onMapChanged }) {
<Modal isOpen={isAddModalOpen} onRequestClose={closeModal}> <Modal isOpen={isAddModalOpen} onRequestClose={closeModal}>
<Box <Box
as="form" as="form"
onSubmit={e => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
handleDone(); handleDone();
}} }}
@ -106,7 +106,7 @@ function AddMapButton({ onMapChanged }) {
minHeight: "200px", minHeight: "200px",
maxHeight: "500px", maxHeight: "500px",
objectFit: "contain", objectFit: "contain",
borderRadius: "4px" borderRadius: "4px",
}} }}
src={mapSource} src={mapSource}
onClick={openImageDialog} onClick={openImageDialog}
@ -119,7 +119,7 @@ function AddMapButton({ onMapChanged }) {
type="number" type="number"
name="rows" name="rows"
value={rows} value={rows}
onChange={e => setRows(e.target.value)} onChange={(e) => setRows(e.target.value)}
/> />
</Box> </Box>
<Box mb={2} ml={1} sx={{ flexGrow: 1 }}> <Box mb={2} ml={1} sx={{ flexGrow: 1 }}>
@ -128,7 +128,7 @@ function AddMapButton({ onMapChanged }) {
type="number" type="number"
name="columns" name="columns"
value={columns} value={columns}
onChange={e => setColumns(e.target.value)} onChange={(e) => setColumns(e.target.value)}
/> />
</Box> </Box>
</Flex> </Flex>
@ -139,7 +139,7 @@ function AddMapButton({ onMapChanged }) {
) : ( ) : (
<Button <Button
varient="primary" varient="primary"
onClick={e => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
openImageDialog(); openImageDialog();
}} }}

View File

@ -0,0 +1,93 @@
import React, { useState } from "react";
import { Text, Box, Input, Button, Label, IconButton } from "theme-ui";
import Modal from "./Modal";
function Nickname({ nickname, allowChanging, onChange }) {
const [isChangeModalOpen, setIsChangeModalOpen] = useState(false);
function openModal() {
setIsChangeModalOpen(true);
}
function closeModal() {
setIsChangeModalOpen(false);
}
const [changedNickname, setChangedNickname] = useState(nickname);
function handleChangeSubmit(event) {
event.preventDefault();
if (allowChanging) {
onChange(changedNickname);
closeModal();
}
}
function handleChange(event) {
setChangedNickname(event.target.value);
}
return (
<>
<Text
my={1}
variant="caption"
sx={{
fontSize: 10,
cursor: allowChanging ? "pointer" : "default",
":hover": allowChanging && {
color: "primary",
},
":active": allowChanging && {
color: "secondary",
},
position: "relative",
}}
onClick={() => allowChanging && openModal()}
>
{nickname}
{allowChanging && (
<IconButton
sx={{
width: "10px",
height: "10px",
padding: 0,
margin: "2px",
position: "absolute",
bottom: "-2px",
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
height="10"
viewBox="0 0 24 24"
width="10"
fill="currentcolor"
>
<path d="M0 0h24v24H0V0z" fill="none" />
<path d="M3 17.46v3.04c0 .28.22.5.5.5h3.04c.13 0 .26-.05.35-.15L17.81 9.94l-3.75-3.75L3.15 17.1c-.1.1-.15.22-.15.36zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" />
</svg>
</IconButton>
)}
</Text>
<Modal isOpen={isChangeModalOpen} onRequestClose={closeModal}>
<Box as="form" onSubmit={handleChangeSubmit}>
<Label htmlFor="nicknameChange">Change your nickname</Label>
<Input
id="nicknameChange"
value={changedNickname}
onChange={handleChange}
mt={1}
mb={3}
/>
<Button disabled={!changedNickname}>Change</Button>
</Box>
</Modal>
</>
);
}
Nickname.defaultProps = {
allowChanging: false,
onChange: () => {},
};
export default Nickname;

View File

@ -2,6 +2,7 @@ import React from "react";
import { Flex, Box, Text } from "theme-ui"; import { Flex, Box, Text } from "theme-ui";
import AddPartyMemberButton from "./AddPartyMemberButton"; import AddPartyMemberButton from "./AddPartyMemberButton";
import Nickname from "./Nickname";
function Party({ nickname, partyNicknames, gameId, onNicknameChange }) { function Party({ nickname, partyNicknames, gameId, onNicknameChange }) {
return ( return (
@ -31,13 +32,13 @@ function Party({ nickname, partyNicknames, gameId, onNicknameChange }) {
width: "100%", width: "100%",
}} }}
> >
<Text my={1} variant="caption" sx={{ fontSize: 10 }}> <Nickname
{nickname || ""} (you) nickname={nickname || ""}
</Text> allowChanging
onChange={onNicknameChange}
/>
{Object.entries(partyNicknames).map(([id, partyNickname]) => ( {Object.entries(partyNicknames).map(([id, partyNickname]) => (
<Text my={1} variant="caption" sx={{ fontSize: 10 }} key={id}> <Nickname nickname={partyNickname} key={id} />
{partyNickname}
</Text>
))} ))}
</Box> </Box>
<Box> <Box>

View File

@ -7,7 +7,7 @@ export default {
highlight: "hsl(260, 20%, 40%)", highlight: "hsl(260, 20%, 40%)",
purple: "hsl(290, 100%, 80%)", purple: "hsl(290, 100%, 80%)",
muted: "hsla(230, 20%, 0%, 20%)", muted: "hsla(230, 20%, 0%, 20%)",
gray: "hsl(0, 0%, 70%)" gray: "hsl(0, 0%, 70%)",
}, },
fonts: { fonts: {
body: "'Bree Serif', serif", body: "'Bree Serif', serif",
@ -15,83 +15,83 @@ export default {
"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif", "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif",
heading: "'Bree Serif', serif", heading: "'Bree Serif', serif",
monospace: "Menlo, monospace", monospace: "Menlo, monospace",
display: "'Pacifico', cursive" display: "'Pacifico', cursive",
}, },
fontSizes: [12, 14, 16, 20, 24, 32, 48, 64, 72], fontSizes: [12, 14, 16, 20, 24, 32, 48, 64, 72],
fontWeights: { fontWeights: {
caption: 200, caption: 200,
body: 300, body: 300,
heading: 400, heading: 400,
display: 400 display: 400,
}, },
lineHeights: { lineHeights: {
body: 1.1, body: 1.1,
heading: 1.25 heading: 1.25,
}, },
text: { text: {
heading: { heading: {
fontFamily: "heading", fontFamily: "heading",
fontWeight: "heading", fontWeight: "heading",
lineHeight: "heading", lineHeight: "heading",
fontSize: 1 fontSize: 1,
}, },
display: { display: {
variant: "textStyles.heading", variant: "textStyles.heading",
fontFamily: "display", fontFamily: "display",
fontSize: [5, 6], fontSize: [5, 6],
fontWeight: "display", fontWeight: "display",
mt: 3 mt: 3,
}, },
caption: { caption: {
fontFamily: "body2", fontFamily: "body2",
fontWeight: "caption", fontWeight: "caption",
fontSize: 10, fontSize: 10,
color: "gray" color: "gray",
}, },
body2: { body2: {
fontFamily: "body2", fontFamily: "body2",
fontSize: 1, fontSize: 1,
fontWeight: "body" fontWeight: "body",
} },
}, },
styles: { styles: {
Container: { Container: {
p: 3, p: 3,
maxWidth: 1024 maxWidth: 1024,
}, },
root: { root: {
fontFamily: "body", fontFamily: "body",
lineHeight: "body", lineHeight: "body",
fontWeight: "body" fontWeight: "body",
}, },
h1: { h1: {
variant: "textStyles.display" variant: "textStyles.display",
}, },
h2: { h2: {
variant: "textStyles.heading", variant: "textStyles.heading",
fontSize: 5 fontSize: 5,
}, },
h3: { h3: {
variant: "textStyles.heading", variant: "textStyles.heading",
fontSize: 4 fontSize: 4,
}, },
h4: { h4: {
variant: "textStyles.heading", variant: "textStyles.heading",
fontSize: 3 fontSize: 3,
}, },
h5: { h5: {
variant: "textStyles.heading", variant: "textStyles.heading",
fontSize: 2 fontSize: 2,
}, },
h6: { h6: {
variant: "textStyles.heading", variant: "textStyles.heading",
fontSize: 1 fontSize: 1,
}, },
a: { a: {
color: "primary", color: "primary",
"&:hover": { "&:hover": {
color: "secondary" color: "secondary",
} },
}, },
pre: { pre: {
variant: "prism", variant: "prism",
@ -102,18 +102,18 @@ export default {
bg: "muted", bg: "muted",
overflow: "auto", overflow: "auto",
code: { code: {
color: "inherit" color: "inherit",
} },
}, },
code: { code: {
fontFamily: "monospace", fontFamily: "monospace",
color: "secondary", color: "secondary",
fontSize: 1 fontSize: 1,
}, },
inlineCode: { inlineCode: {
fontFamily: "monospace", fontFamily: "monospace",
color: "secondary", color: "secondary",
bg: "muted" bg: "muted",
}, },
table: { table: {
width: "100%", width: "100%",
@ -126,52 +126,52 @@ export default {
pr: "4px", pr: "4px",
pl: 0, pl: 0,
borderColor: "muted", borderColor: "muted",
borderBottomStyle: "solid" borderBottomStyle: "solid",
} },
}, },
th: { th: {
verticalAlign: "bottom", verticalAlign: "bottom",
borderBottomWidth: "2px" borderBottomWidth: "2px",
}, },
td: { td: {
verticalAlign: "top", verticalAlign: "top",
borderBottomWidth: "1px" borderBottomWidth: "1px",
}, },
hr: { hr: {
border: 0, border: 0,
borderBottom: "1px solid", borderBottom: "1px solid",
borderColor: "muted" borderColor: "muted",
}, },
img: { img: {
maxWidth: "100%" maxWidth: "100%",
} },
}, },
prism: { prism: {
".comment,.prolog,.doctype,.cdata,.punctuation,.operator,.entity,.url": { ".comment,.prolog,.doctype,.cdata,.punctuation,.operator,.entity,.url": {
color: "gray" color: "gray",
}, },
".comment": { ".comment": {
fontStyle: "italic" fontStyle: "italic",
}, },
".property,.tag,.boolean,.number,.constant,.symbol,.deleted,.function,.class-name,.regex,.important,.variable": { ".property,.tag,.boolean,.number,.constant,.symbol,.deleted,.function,.class-name,.regex,.important,.variable": {
color: "purple" color: "purple",
}, },
".atrule,.attr-value,.keyword": { ".atrule,.attr-value,.keyword": {
color: "primary" color: "primary",
}, },
".selector,.attr-name,.string,.char,.bultin,.inserted": { ".selector,.attr-name,.string,.char,.bultin,.inserted": {
color: "secondary" color: "secondary",
} },
}, },
forms: { forms: {
label: { label: {
fontWeight: 400 fontWeight: 400,
}, },
input: { input: {
"&:focus": { "&:focus": {
outlineColor: "primary" outlineColor: "primary",
} },
} },
}, },
buttons: { buttons: {
primary: { primary: {
@ -182,15 +182,15 @@ export default {
borderColor: "text", borderColor: "text",
"&:hover": { "&:hover": {
borderColor: "highlight", borderColor: "highlight",
cursor: "pointer" cursor: "pointer",
}, },
fontFamily: "body", fontFamily: "body",
"&:focus": { "&:focus": {
outline: "none" outline: "none",
}, },
"&:active": { "&:active": {
borderColor: "primary" borderColor: "primary",
} },
}, },
secondary: { secondary: {
color: "secondary", color: "secondary",
@ -198,29 +198,31 @@ export default {
borderStyle: "solid", borderStyle: "solid",
borderWidth: "1px", borderWidth: "1px",
borderColor: "text", borderColor: "text",
fontFamily: "body" fontFamily: "body",
}, },
icon: { icon: {
"&:hover": { "&:hover": {
cursor: "pointer" cursor: "pointer",
color: "primary",
}, },
"&:focus": { "&:focus": {
outline: "none" outline: "none",
}, },
"&:active": { "&:active": {
color: "primary" color: "secondary",
} },
}, },
close: { close: {
"&:hover": { "&:hover": {
cursor: "pointer" cursor: "pointer",
color: "primary",
}, },
"&:focus": { "&:focus": {
outline: "none" outline: "none",
}, },
"&:active": { "&:active": {
color: "primary" color: "secondary",
} },
} },
} },
}; };