mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-12 06:17:28 -06:00
[frogend] Settings refactor (#1318)
* yakshave new form field structure * fully refactor user profile settings form * use rtk query api for profile settings * refactor user post settings * refactor password change form * refactor admin settings * FormWithData structure for user forms * admin actions refactor * whitespace * fix user settings data prop * remove superfluous logging * cleanup old code * refactor federation/suspend (overview, detail) * mostly abstracted (emoji) checkbox list * refactor parse-from-toot * refactor custom-emoji, progress on federation bulk * loading icon styling to prevent big spinny * refactor federation import-export interface * cleanup old files * [chore] Update/add license headers for 2023 * redux fixes * text-field exports * appease the linter * refactor authentication with RTK Query * fix login/logout state transition weirdness * fixes/cleanup * small linter-related fixes * add eslint license header check, fix existing files * remove old code, clarify comment * clarify suspend on subdomains * collapse if/else * fa-fw width info comment
This commit is contained in:
parent
974ec80a20
commit
9b139b6320
69 changed files with 3129 additions and 2663 deletions
|
|
@ -18,101 +18,61 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const Promise = require('bluebird');
|
||||
const React = require("react");
|
||||
|
||||
const FakeToot = require("../../../components/fake-toot");
|
||||
const MutateButton = require("../../../components/mutation-button");
|
||||
const query = require("../../../lib/query");
|
||||
|
||||
const {
|
||||
useTextInput,
|
||||
useFileInput,
|
||||
useComboBoxInput
|
||||
} = require("../../../components/form");
|
||||
} = require("../../../lib/form");
|
||||
const useShortcode = require("./use-shortcode");
|
||||
|
||||
const useFormSubmit = require("../../../lib/form/submit");
|
||||
|
||||
const {
|
||||
TextInput, FileInput
|
||||
} = require("../../../components/form/inputs");
|
||||
|
||||
const query = require("../../../lib/query");
|
||||
const { CategorySelect } = require('../category-select');
|
||||
const FakeToot = require("../../../components/fake-toot");
|
||||
const MutationButton = require("../../../components/form/mutation-button");
|
||||
|
||||
const shortcodeRegex = /^[a-z0-9_]+$/;
|
||||
module.exports = function NewEmojiForm() {
|
||||
const shortcode = useShortcode();
|
||||
|
||||
module.exports = function NewEmojiForm({ emoji }) {
|
||||
const emojiCodes = React.useMemo(() => {
|
||||
return new Set(emoji.map((e) => e.shortcode));
|
||||
}, [emoji]);
|
||||
|
||||
const [addEmoji, result] = query.useAddEmojiMutation();
|
||||
|
||||
const [onFileChange, resetFile, { image, imageURL, imageInfo }] = useFileInput("image", {
|
||||
const image = useFileInput("image", {
|
||||
withPreview: true,
|
||||
maxSize: 50 * 1024
|
||||
maxSize: 50 * 1024 // TODO: get from instance api?
|
||||
});
|
||||
|
||||
const [onShortcodeChange, resetShortcode, { shortcode, setShortcode, shortcodeRef }] = useTextInput("shortcode", {
|
||||
validator: function validateShortcode(code) {
|
||||
// technically invalid, but hacky fix to prevent validation error on page load
|
||||
if (shortcode == "") {return "";}
|
||||
const category = useComboBoxInput("category");
|
||||
|
||||
if (emojiCodes.has(code)) {
|
||||
return "Shortcode already in use";
|
||||
}
|
||||
|
||||
if (code.length < 2 || code.length > 30) {
|
||||
return "Shortcode must be between 2 and 30 characters";
|
||||
}
|
||||
|
||||
if (code.toLowerCase() != code) {
|
||||
return "Shortcode must be lowercase";
|
||||
}
|
||||
|
||||
if (!shortcodeRegex.test(code)) {
|
||||
return "Shortcode must only contain lowercase letters, numbers, and underscores";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
const [categoryState, resetCategory, { category }] = useComboBoxInput("category");
|
||||
const [submitForm, result] = useFormSubmit({
|
||||
shortcode, image, category
|
||||
}, query.useAddEmojiMutation());
|
||||
|
||||
React.useEffect(() => {
|
||||
if (shortcode.length == 0) {
|
||||
if (image != undefined) {
|
||||
let [name, _ext] = image.name.split(".");
|
||||
setShortcode(name);
|
||||
if (shortcode.value.length == 0) {
|
||||
if (image.value != undefined) {
|
||||
let [name, _ext] = image.value.name.split(".");
|
||||
shortcode.setter(name);
|
||||
}
|
||||
}
|
||||
// we explicitly don't want to add 'shortcode' as a dependency here
|
||||
// because we only want this to update to the filename if the field is empty
|
||||
// at the moment the file is selected, not some time after when the field is emptied
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [image]);
|
||||
|
||||
function uploadEmoji(e) {
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
/* We explicitly don't want to have 'shortcode' as a dependency here
|
||||
because we only want to change the shortcode to the filename if the field is empty
|
||||
at the moment the file is selected, not some time after when the field is emptied
|
||||
*/
|
||||
/* eslint-disable-next-line react-hooks/exhaustive-deps */
|
||||
}, [image.value]);
|
||||
|
||||
Promise.try(() => {
|
||||
return addEmoji({
|
||||
image,
|
||||
shortcode,
|
||||
category
|
||||
}).unwrap();
|
||||
}).then(() => {
|
||||
resetFile();
|
||||
resetShortcode();
|
||||
resetCategory();
|
||||
}).catch((e) => {
|
||||
console.error("Emoji upload error:", e);
|
||||
});
|
||||
}
|
||||
let emojiOrShortcode = `:${shortcode.value}:`;
|
||||
|
||||
let emojiOrShortcode = `:${shortcode}:`;
|
||||
|
||||
if (imageURL != undefined) {
|
||||
if (image.previewValue != undefined) {
|
||||
emojiOrShortcode = <img
|
||||
className="emoji"
|
||||
src={imageURL}
|
||||
src={image.previewValue}
|
||||
title={`:${shortcode}:`}
|
||||
alt={shortcode}
|
||||
/>;
|
||||
|
|
@ -126,42 +86,22 @@ module.exports = function NewEmojiForm({ emoji }) {
|
|||
Look at this new custom emoji {emojiOrShortcode} isn't it cool?
|
||||
</FakeToot>
|
||||
|
||||
<form onSubmit={uploadEmoji} className="form-flex">
|
||||
<div className="form-field file">
|
||||
<label className="file-input button" htmlFor="image">
|
||||
Browse
|
||||
</label>
|
||||
{imageInfo}
|
||||
<input
|
||||
className="hidden"
|
||||
type="file"
|
||||
id="image"
|
||||
name="Image"
|
||||
accept="image/png,image/gif"
|
||||
onChange={onFileChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-field text">
|
||||
<label htmlFor="shortcode">
|
||||
Shortcode, must be unique among the instance's local emoji
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="shortcode"
|
||||
name="Shortcode"
|
||||
ref={shortcodeRef}
|
||||
onChange={onShortcodeChange}
|
||||
value={shortcode}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CategorySelect
|
||||
value={category}
|
||||
categoryState={categoryState}
|
||||
<form onSubmit={submitForm} className="form-flex">
|
||||
<FileInput
|
||||
field={image}
|
||||
accept="image/png,image/gif"
|
||||
/>
|
||||
|
||||
<MutateButton text="Upload emoji" result={result} />
|
||||
<TextInput
|
||||
field={shortcode}
|
||||
label="Shortcode, must be unique among the instance's local emoji"
|
||||
/>
|
||||
|
||||
<CategorySelect
|
||||
field={category}
|
||||
/>
|
||||
|
||||
<MutationButton label="Upload emoji" result={result} />
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue