refactor user post settings

This commit is contained in:
f0x 2023-01-04 20:12:28 +00:00
parent 0898aa28eb
commit f6369ccae1
8 changed files with 101 additions and 48 deletions

View file

@ -90,12 +90,30 @@ function Checkbox({label, field, ...inputProps}) {
</label>
</div>
);
}
function Select({label, field, options, ...inputProps}) {
const {onChange, value} = field;
return (
<div className="form-field select">
<label>
{label}
<select
{...{onChange, value}}
{...inputProps}
>
{options}
</select>
</label>
</div>
);
}
module.exports = {
TextInput,
TextArea,
FileInput,
Checkbox
Checkbox,
Select
};

View file

@ -23,6 +23,8 @@ const React = require("react");
module.exports = function useBoolInput({name, Name}, {defaultValue=false} = {}) {
const [value, setValue] = React.useState(defaultValue);
console.log("bool", name, value, defaultValue);
function onChange(e) {
setValue(e.target.checked);
}
@ -40,6 +42,7 @@ module.exports = function useBoolInput({name, Name}, {defaultValue=false} = {})
[`set${Name}`]: setValue
}
], {
name,
onChange,
reset,
value,

View file

@ -20,7 +20,7 @@
const { useComboboxState } = require("ariakit/combobox");
module.exports = function useComboBoxInput({name, Name}, {validator, defaultValue} = {}) {
module.exports = function useComboBoxInput({name, Name}, {defaultValue} = {}) {
const state = useComboboxState({
defaultValue,
gutter: 0,
@ -31,11 +31,16 @@ module.exports = function useComboBoxInput({name, Name}, {validator, defaultValu
state.setValue("");
}
return [
return Object.assign([
state,
reset,
name,
{
[name]: state.value,
}
];
], {
name,
value: state.value,
reset
});
};

View file

@ -82,6 +82,7 @@ module.exports = function useFileInput({name, _Name}, {
], {
onChange,
reset,
name,
value: file,
previewValue: imageURL,
hasChanged: () => file != undefined,

View file

@ -29,11 +29,11 @@ module.exports = function useFormSubmit(form, [mutationQuery, result]) {
// transform the field definitions into an object with just their values
let updatedFields = [];
const mutationData = syncpipe(form, [
(_) => Object.entries(_),
(_) => _.map(([key, field]) => {
(_) => Object.values(_),
(_) => _.map((field) => {
if (field.hasChanged()) {
updatedFields.push(field);
return [key, field.value];
return [field.name, field.value];
} else {
return null;
}

View file

@ -56,6 +56,7 @@ module.exports = function useTextInput({name, Name}, {validator, defaultValue=""
], {
onChange,
reset,
name,
value: text,
ref: textRef,
setter: setText,

View file

@ -43,10 +43,16 @@ const MutationButton = require("../components/form/mutation-button");
const Loading = require("../components/loading");
module.exports = function UserProfile() {
const allowCustomCSS = Redux.useSelector(state => state.instances.current.configuration.accounts.allow_custom_css);
// const profile = Redux.useSelector(state => state.user.profile);
const {data: profile = {}, isLoading} = query.useVerifyCredentialsQuery();
if (isLoading) {
return <Loading/>;
} else {
return <UserProfileForm profile={profile} />;
}
};
function UserProfileForm({profile}) {
/*
User profile update form keys
- bool bot
@ -55,10 +61,6 @@ module.exports = function UserProfile() {
- string note
- file avatar
- file header
- string source[privacy]
- bool source[sensitive]
- string source[language]
- string source[status_format]
- bool enable_rss
- string custom_css (if enabled)
*/
@ -66,21 +68,17 @@ module.exports = function UserProfile() {
const form = {
avatar: useFileInput("avatar", {withPreview: true, }),
header: useFileInput("header", {withPreview: true, }),
display_name: useTextInput("displayName", {defaultValue: profile.display_name}),
displayName: useTextInput("display_name", {defaultValue: profile.display_name}),
note: useTextInput("note", {defaultValue: profile.source?.note}),
custom_css: useTextInput("customCSS", {defaultValue: profile.custom_css}),
bot: useBoolInput("isBot", {defaultValue: profile.bot}),
locked: useBoolInput("isLocked", {defaultValue: profile.locked}),
enable_rss: useBoolInput("enableRSS", {defaultValue: profile.enable_rss}),
"source[sensitive]": useBoolInput("isSensitive", {defaultValue: profile.source?.sensitive}),
customCSS: useTextInput("custom_css", {defaultValue: profile.custom_css}),
bot: useBoolInput("bot", {defaultValue: profile.bot}),
locked: useBoolInput("locked", {defaultValue: profile.locked}),
enableRSS: useBoolInput("enable_rss", {defaultValue: profile.enable_rss}),
};
const allowCustomCSS = Redux.useSelector(state => state.instances.current.configuration.accounts.allow_custom_css);
const [result, submitForm] = useFormSubmit(form, query.useUpdateCredentialsMutation());
if (isLoading) {
return <Loading/>;
}
return (
<form className="user-profile" onSubmit={submitForm}>
<h1>Profile</h1>
@ -88,7 +86,7 @@ module.exports = function UserProfile() {
<FakeProfile
avatar={form.avatar.previewValue ?? profile.avatar}
header={form.header.previewValue ?? profile.header}
display_name={form.display_name.value ?? profile.username}
display_name={form.displayName.value ?? profile.username}
username={profile.username}
role={profile.role}
/>
@ -110,7 +108,7 @@ module.exports = function UserProfile() {
</div>
</div>
<TextInput
field={form.display_name}
field={form.displayName}
label="Name"
placeholder="A GoToSocial user"
/>
@ -125,12 +123,12 @@ module.exports = function UserProfile() {
label="Manually approve follow requests"
/>
<Checkbox
field={form.enable_rss}
field={form.enableRSS}
label="Enable RSS feed of Public posts"
/>
{ !allowCustomCSS ? null :
<TextArea
field={form.custom_css}
field={form.customCSS}
label="Custom CSS"
className="monospace"
rows={8}
@ -141,4 +139,4 @@ module.exports = function UserProfile() {
<MutationButton text="Save profile info" result={result}/>
</form>
);
};
}

View file

@ -23,37 +23,64 @@ const React = require("react");
const Redux = require("react-redux");
const api = require("../lib/api");
const user = require("../redux/reducers/user").actions;
const submit = require("../lib/submit");
const Languages = require("../components/languages");
const Submit = require("../components/submit");
const query = require("../lib/query");
const {
useTextInput,
useBoolInput
} = require("../lib/form");
const useFormSubmit = require("../lib/form/submit");
const {
Checkbox,
Select,
} = require("../components/form-fields").formFields(user.setSettingsVal, (state) => state.user.settings);
TextInput,
Checkbox
} = require("../components/form/inputs");
const MutationButton = require("../components/form/mutation-button");
const Loading = require("../components/loading");
module.exports = function UserSettings() {
const dispatch = Redux.useDispatch();
const {data: profile, isLoading} = query.useVerifyCredentialsQuery();
const [errorMsg, setError] = React.useState("");
const [statusMsg, setStatus] = React.useState("");
if (isLoading) {
return <Loading/>;
} else {
return <UserSettingsForm source={profile.source} />;
}
};
const updateSettings = submit(
() => dispatch(api.user.updateSettings()),
{setStatus, setError}
);
function UserSettingsForm({source}) {
/* form keys
- string source[privacy]
- bool source[sensitive]
- string source[language]
- string source[status_format]
*/
const form = {
defaultPrivacy: useTextInput("source[privacy]", {defaultValue: source.privacy ?? "unlisted"}),
isSensitive: useBoolInput("source[sensitive]", {defaultValue: source.sensitive}),
language: useTextInput("source[language]", {defaultValue: source.language ?? "EN"}),
format: useTextInput("source[status_format]", {defaultValue: source.status_format ?? "plain"}),
};
const [result, submitForm] = useFormSubmit(form, query.useUpdateCredentialsMutation());
return (
<>
<div className="user-settings">
<form className="user-settings" onSubmit={submitForm}>
<h1>Post settings</h1>
<Select id="source.language" name="Default post language" options={
<Select field={form.language} label="Default post language" options={
<Languages/>
}>
</Select>
<Select id="source.privacy" name="Default post privacy" options={
<Select field={form.defaultPrivacy} label="Default post privacy" options={
<>
<option value="private">Private / followers-only</option>
<option value="unlisted">Unlisted</option>
@ -62,7 +89,7 @@ module.exports = function UserSettings() {
}>
<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>
</Select>
<Select id="source.status_format" name="Default post (and bio) format" options={
<Select field={form.format} label="Default post (and bio) format" options={
<>
<option value="plain">Plain (default)</option>
<option value="markdown">Markdown</option>
@ -71,18 +98,18 @@ module.exports = function UserSettings() {
<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>
</Select>
<Checkbox
id="source.sensitive"
name="Mark my posts as sensitive by default"
field={form.isSensitive}
label="Mark my posts as sensitive by default"
/>
<Submit onClick={updateSettings} label="Save post settings" errorMsg={errorMsg} statusMsg={statusMsg}/>
</div>
<MutationButton text="Save settings" result={result}/>
</form>
<div>
<PasswordChange/>
</div>
</>
);
};
}
function PasswordChange() {
const dispatch = Redux.useDispatch();