From 3a75eb12265ac83b9d88549b1b7f593905e5912d Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 10 May 2021 14:39:10 +0100 Subject: [PATCH] Fix handling of enter/return in space creation menu --- .../views/spaces/SpaceBasicSettings.tsx | 50 ++++++++------- .../views/spaces/SpaceCreateMenu.tsx | 61 ++++++++++++++++--- src/i18n/strings/en_EN.json | 1 + 3 files changed, 83 insertions(+), 29 deletions(-) diff --git a/src/components/views/spaces/SpaceBasicSettings.tsx b/src/components/views/spaces/SpaceBasicSettings.tsx index bc378ab956..ec40f7bed8 100644 --- a/src/components/views/spaces/SpaceBasicSettings.tsx +++ b/src/components/views/spaces/SpaceBasicSettings.tsx @@ -32,17 +32,11 @@ interface IProps { setTopic(topic: string): void; } -const SpaceBasicSettings = ({ +export const SpaceAvatar = ({ avatarUrl, avatarDisabled = false, setAvatar, - name = "", - nameDisabled = false, - setName, - topic = "", - topicDisabled = false, - setTopic, -}: IProps) => { +}: Pick) => { const avatarUploadRef = useRef(); const [avatar, setAvatarDataUrl] = useState(avatarUrl); // avatar data url cache @@ -81,20 +75,34 @@ const SpaceBasicSettings = ({ } } + return
+ { avatarSection } + { + if (!e.target.files?.length) return; + const file = e.target.files[0]; + setAvatar(file); + const reader = new FileReader(); + reader.onload = (ev) => { + setAvatarDataUrl(ev.target.result as string); + }; + reader.readAsDataURL(file); + }} accept="image/*" /> +
; +}; + +const SpaceBasicSettings = ({ + avatarUrl, + avatarDisabled = false, + setAvatar, + name = "", + nameDisabled = false, + setName, + topic = "", + topicDisabled = false, + setTopic, +}: IProps) => { return
-
- { avatarSection } - { - if (!e.target.files?.length) return; - const file = e.target.files[0]; - setAvatar(file); - const reader = new FileReader(); - reader.onload = (ev) => { - setAvatarDataUrl(ev.target.result as string); - }; - reader.readAsDataURL(file); - }} accept="image/*" /> -
+ { return ( @@ -41,17 +43,39 @@ enum Visibility { Private, } +const spaceNameValidator = withValidation({ + rules: [ + { + key: "required", + test: async ({ value }) => !!value, + invalid: () => _t("Please enter a name for the space"), + }, + ], +}); + const SpaceCreateMenu = ({ onFinished }) => { const cli = useContext(MatrixClientContext); const [visibility, setVisibility] = useState(null); - const [name, setName] = useState(""); - const [avatar, setAvatar] = useState(null); - const [topic, setTopic] = useState(""); const [busy, setBusy] = useState(false); - const onSpaceCreateClick = async () => { + const [name, setName] = useState(""); + const spaceNameField = useRef(); + const [avatar, setAvatar] = useState(null); + const [topic, setTopic] = useState(""); + + const onSpaceCreateClick = async (e) => { + e.preventDefault(); if (busy) return; + setBusy(true); + // require & validate the space name field + if (!await spaceNameField.current.validate({ allowEmpty: false })) { + spaceNameField.current.focus(); + spaceNameField.current.validate({ allowEmpty: false, focused: true }); + setBusy(false); + return; + } + const initialState: IStateEvent[] = [ { type: EventType.RoomHistoryVisibility, @@ -146,9 +170,30 @@ const SpaceCreateMenu = ({ onFinished }) => { }

- +
+ - + setName(ev.target.value)} + ref={spaceNameField} + onValidate={spaceNameValidator} + /> + + setTopic(ev.target.value)} + rows={3} + /> + + + { busy ? _t("Creating...") : _t("Create") } ; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index dcad970300..26275c4325 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -996,6 +996,7 @@ "Upload": "Upload", "Name": "Name", "Description": "Description", + "Please enter a name for the space": "Please enter a name for the space", "Create a space": "Create a space", "Spaces are new ways to group rooms and people. To join an existing space you'll need an invite.": "Spaces are new ways to group rooms and people. To join an existing space you'll need an invite.", "Public": "Public",