diff --git a/web/source/settings-panel/components/form-fields.jsx b/web/source/settings-panel/components/form-fields.jsx index a3b19bc17..30f209f13 100644 --- a/web/source/settings-panel/components/form-fields.jsx +++ b/web/source/settings-panel/components/form-fields.jsx @@ -71,7 +71,7 @@ function get(state, id) { module.exports = { formFields: function formFields(setter, selector) { - function FormField({type, id, name, className="", placeHolder="", fileType="", children=null}) { + function FormField({type, id, name, className="", placeHolder="", fileType="", children=null, options={}}) { const dispatch = Redux.useDispatch(); let state = Redux.useSelector(selector); let { @@ -88,6 +88,12 @@ module.exports = { field = <textarea type="text" id={id} value={get(state, id)} placeholder={placeHolder} className={className} onChange={onTextChange(id)}/>; } else if (type == "checkbox") { field = <input type="checkbox" id={id} checked={get(state, id)} className={className} onChange={onCheckChange(id)}/>; + } else if (type == "select") { + field = ( + <select id={id} checked={get(state, id)} className={className} onChange={onTextChange(id)}> + {options} + </select> + ); } else if (type == "file") { defaultLabel = false; let file = get(state, `${id}File`); @@ -128,6 +134,10 @@ module.exports = { return <FormField type="checkbox" {...props} />; }, + Select: function(props) { + return <FormField type="select" {...props} />; + }, + File: function(props) { return <FormField type="file" {...props} />; }, diff --git a/web/source/settings-panel/lib/form-fields.js b/web/source/settings-panel/lib/form-fields.js deleted file mode 100644 index dfdd93086..000000000 --- a/web/source/settings-panel/lib/form-fields.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - GoToSocial - Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -"use strict"; - -const d = require("dotty"); - -module.exports = function(dispatch, setter, obj) { - return { - onTextChange: function (key) { - return function (e) { - dispatch(setter([key, e.target.value])); - }; - }, - - onCheckChange: function (key) { - return function (e) { - dispatch(setter([key, e.target.checked])); - }; - }, - - onFileChange: function (key) { - return function (e) { - let old = d.get(obj, key); - if (old != undefined) { - URL.revokeObjectURL(old); // no error revoking a non-Object URL as provided by instance - } - let file = e.target.files[0]; - let objectURL = URL.createObjectURL(file); - dispatch(setter([key, objectURL])); - dispatch(setter([`${key}File`, file])); - }; - } - }; -}; diff --git a/web/source/settings-panel/user/profile.js b/web/source/settings-panel/user/profile.js index 05a1249c5..e06d3cde1 100644 --- a/web/source/settings-panel/user/profile.js +++ b/web/source/settings-panel/user/profile.js @@ -43,8 +43,6 @@ module.exports = function UserProfile() { const allowCustomCSS = instance.configuration.accounts.allow_custom_css; - const { onTextChange, onCheckChange, onFileChange } = formFields(dispatch, user.setProfileVal, account); - const [errorMsg, setError] = React.useState(""); const [statusMsg, setStatus] = React.useState(""); diff --git a/web/source/settings-panel/user/security.js b/web/source/settings-panel/user/security.js deleted file mode 100644 index 0d9fe63c3..000000000 --- a/web/source/settings-panel/user/security.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - GoToSocial - Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -"use strict"; - -const React = require("react"); -const Promise = require("bluebird"); -const Redux = require("react-redux"); - -const Submit = require("../../lib/submit"); -const api = require("../../lib"); diff --git a/web/source/settings-panel/user/settings.js b/web/source/settings-panel/user/settings.js index ac023254e..48a8ff241 100644 --- a/web/source/settings-panel/user/settings.js +++ b/web/source/settings-panel/user/settings.js @@ -23,17 +23,18 @@ const React = require("react"); const Redux = require("react-redux"); const api = require("../lib/api"); -const formFields = require("../lib/form-fields"); const user = require("../redux/reducers/user").actions; const Languages = require("../components/languages"); const Submit = require("../components/submit"); +const { + Checkbox, + Select, +} = require("../components/form-fields").formFields(user.setProfileVal, (state) => state.user.profile); + module.exports = function UserSettings() { const dispatch = Redux.useDispatch(); - const account = Redux.useSelector(state => state.user.settings); - - const { onTextChange, onCheckChange } = formFields(dispatch, user.setSettingsVal, account); const [errorMsg, setError] = React.useState(""); const [statusMsg, setStatus] = React.useState(""); @@ -54,42 +55,39 @@ module.exports = function UserSettings() { return ( <div className="user-settings"> <h1>Post settings</h1> - <div className="labelselect"> - <label htmlFor="language">Default post language</label> - <select id="language" autoComplete="language" value={account.source.language.toUpperCase()} onChange={onTextChange("source.language")}> - <Languages /> - </select> - </div> - <div className="labelselect"> - <label htmlFor="privacy">Default post privacy</label> - <select id="privacy" value={account.source.privacy} onChange={onTextChange("source.privacy")}> + <Select id="language" name="Default post language"> + <Languages/> + </Select> + <Select id="privacy" name="Default post privacy" options={ + <> <option value="private">Private / followers-only)</option> <option value="unlisted">Unlisted</option> <option value="public">Public</option> - </select> + </> + }> <a href="https://docs.gotosocial.org/en/latest/user_guide/posts/#privacy-settings" target="_blank" className="moreinfolink" rel="noreferrer">Learn more about post privacy settings (opens in a new tab)</a> - </div> - <div className="labelselect"> - <label htmlFor="format">Default post format</label> - <select id="format" value={account.source.format} onChange={onTextChange("source.format")}> + </Select> + <Select id="format" name="Default post format" options={ + <> <option value="plain">Plain (default)</option> <option value="markdown">Markdown</option> - </select> + </> + }> <a href="https://docs.gotosocial.org/en/latest/user_guide/posts/#input-types" target="_blank" className="moreinfolink" rel="noreferrer">Learn more about post format settings (opens in a new tab)</a> - </div> - <div className="labelcheckbox"> - <label htmlFor="sensitive">Mark my posts as sensitive by default</label> - <input id="sensitive" type="checkbox" checked={account.source.sensitive} onChange={onCheckChange("source.sensitive")}/> - </div> - <Submit onClick={submit} label="Save post settings" errorMsg={errorMsg} statusMsg={statusMsg}/> + </Select> + <Checkbox + id="sensitive" + name="Mark my posts as sensitive by default" + /> + <Submit onClick={submit} label="Save post settings" errorMsg={errorMsg} statusMsg={statusMsg}/> <hr/> <PasswordChange/> </div> ); }; -function PasswordChange({oauth}) { +function PasswordChange() { const dispatch = Redux.useDispatch(); const [errorMsg, setError] = React.useState("");