mirror of
https://codeberg.org/superseriousbusiness/gotosocial.git
synced 2024-12-18 07:01:49 +03:00
[frontend] Better autocapitalize/spellcheck settings on forms (#3077)
This commit is contained in:
parent
5769722c58
commit
bbbf6ebe37
20 changed files with 205 additions and 38 deletions
|
@ -22,9 +22,33 @@ import { TextInput } from "../../../../components/form/inputs";
|
||||||
import MutationButton from "../../../../components/form/mutation-button";
|
import MutationButton from "../../../../components/form/mutation-button";
|
||||||
import { useTextInput } from "../../../../lib/form";
|
import { useTextInput } from "../../../../lib/form";
|
||||||
import { useInstanceKeysExpireMutation } from "../../../../lib/query/admin/actions";
|
import { useInstanceKeysExpireMutation } from "../../../../lib/query/admin/actions";
|
||||||
|
import isValidDomain from "is-valid-domain";
|
||||||
|
|
||||||
export default function ExpireRemote({}) {
|
export default function ExpireRemote({}) {
|
||||||
const domainField = useTextInput("domain");
|
const domainField = useTextInput("domain", {
|
||||||
|
validator: (v: string) => {
|
||||||
|
if (v.length === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v[v.length-1] === ".") {
|
||||||
|
return "invalid domain";
|
||||||
|
}
|
||||||
|
|
||||||
|
const valid = isValidDomain(v, {
|
||||||
|
subdomain: true,
|
||||||
|
wildcard: false,
|
||||||
|
allowUnicode: true,
|
||||||
|
topLevel: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "invalid domain";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const [expire, expireResult] = useInstanceKeysExpireMutation();
|
const [expire, expireResult] = useInstanceKeysExpireMutation();
|
||||||
|
|
||||||
|
@ -52,11 +76,13 @@ export default function ExpireRemote({}) {
|
||||||
<TextInput
|
<TextInput
|
||||||
field={domainField}
|
field={domainField}
|
||||||
label="Domain"
|
label="Domain"
|
||||||
type="string"
|
type="text"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
placeholder="example.org"
|
placeholder="example.org"
|
||||||
/>
|
/>
|
||||||
<MutationButton
|
<MutationButton
|
||||||
disabled={!domainField.value}
|
disabled={!domainField.value || !domainField.valid}
|
||||||
label="Expire keys"
|
label="Expire keys"
|
||||||
result={expireResult}
|
result={expireResult}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -53,6 +53,9 @@ export default function ApURL() {
|
||||||
<TextInput
|
<TextInput
|
||||||
field={urlField}
|
field={urlField}
|
||||||
label="URL"
|
label="URL"
|
||||||
|
type="url"
|
||||||
|
pattern="(http|https):\/\/.+"
|
||||||
|
placeholder="https://example.org/users/someone"
|
||||||
/>
|
/>
|
||||||
<MutationButton
|
<MutationButton
|
||||||
disabled={!urlField.value}
|
disabled={!urlField.value}
|
||||||
|
|
|
@ -126,6 +126,8 @@ export function CategorySelect({ field, children }: PropsWithChildren<CategorySe
|
||||||
items={categoryItems}
|
items={categoryItems}
|
||||||
label="Category"
|
label="Category"
|
||||||
placeholder="e.g., reactions"
|
placeholder="e.g., reactions"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
|
|
@ -117,6 +117,8 @@ export default function NewEmojiForm() {
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.shortcode}
|
field={form.shortcode}
|
||||||
label="Shortcode, must be unique among the instance's local emoji"
|
label="Shortcode, must be unique among the instance's local emoji"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
{...{pattern: "^\\w{2,30}$"}}
|
{...{pattern: "^\\w{2,30}$"}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,8 @@ function EmojiList({ emoji }: EmojiListParams) {
|
||||||
field={filterField}
|
field={filterField}
|
||||||
name="emoji-shortcode"
|
name="emoji-shortcode"
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="entries scrolling">
|
<div className="entries scrolling">
|
||||||
|
|
|
@ -52,9 +52,10 @@ export default function StealThisLook({ emojiCodes }) {
|
||||||
</label>
|
</label>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<input
|
<input
|
||||||
type="text"
|
|
||||||
id="url"
|
id="url"
|
||||||
name="url"
|
name="url"
|
||||||
|
type="url"
|
||||||
|
pattern="(http|https):\/\/.+"
|
||||||
onChange={urlField.onChange}
|
onChange={urlField.onChange}
|
||||||
value={urlField.value}
|
value={urlField.value}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -100,7 +100,7 @@ export default function HeaderPermCreateForm({ permType }: { permType: PermType
|
||||||
field={form.header}
|
field={form.header}
|
||||||
label={
|
label={
|
||||||
<>
|
<>
|
||||||
HTTP Header Name
|
Header Name
|
||||||
<a
|
<a
|
||||||
href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers"
|
href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
@ -112,12 +112,15 @@ export default function HeaderPermCreateForm({ permType }: { permType: PermType
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
placeholder={"User-Agent"}
|
placeholder={"User-Agent"}
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
|
{...{className: "monospace"}}
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.regex}
|
field={form.regex}
|
||||||
label={
|
label={
|
||||||
<>
|
<>
|
||||||
HTTP Header Value RE2 Regex
|
Value Regex
|
||||||
<a
|
<a
|
||||||
href="https://github.com/google/re2/wiki/Syntax"
|
href="https://github.com/google/re2/wiki/Syntax"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
@ -129,6 +132,8 @@ export default function HeaderPermCreateForm({ permType }: { permType: PermType
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
placeholder={"^.*Some-User-Agent.*$"}
|
placeholder={"^.*Some-User-Agent.*$"}
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
{...{className: "monospace"}}
|
{...{className: "monospace"}}
|
||||||
/>
|
/>
|
||||||
<MutationButton
|
<MutationButton
|
||||||
|
|
|
@ -164,7 +164,7 @@ function PermDeets({
|
||||||
<dl className="info-list">
|
<dl className="info-list">
|
||||||
<div className="info-list-entry">
|
<div className="info-list-entry">
|
||||||
<dt>ID</dt>
|
<dt>ID</dt>
|
||||||
<dd>{perm.id}</dd>
|
<dd className="monospace">{perm.id}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div className="info-list-entry">
|
<div className="info-list-entry">
|
||||||
<dt>Created</dt>
|
<dt>Created</dt>
|
||||||
|
@ -176,10 +176,10 @@ function PermDeets({
|
||||||
</div>
|
</div>
|
||||||
<div className="info-list-entry">
|
<div className="info-list-entry">
|
||||||
<dt>Header Name</dt>
|
<dt>Header Name</dt>
|
||||||
<dd>{perm.header}</dd>
|
<dd className="monospace">{perm.header}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div className="info-list-entry">
|
<div className="info-list-entry">
|
||||||
<dt>Header Value Regex</dt>
|
<dt>Value Regex</dt>
|
||||||
<dd className="monospace">{perm.regex}</dd>
|
<dd className="monospace">{perm.regex}</dd>
|
||||||
</div>
|
</div>
|
||||||
<div className="info-list-entry">
|
<div className="info-list-entry">
|
||||||
|
|
|
@ -79,7 +79,10 @@ function InstanceSettingsForm({ data: instance }: InstanceSettingsFormProps) {
|
||||||
const [submitForm, result] = useFormSubmit(form, useUpdateInstanceMutation());
|
const [submitForm, result] = useFormSubmit(form, useUpdateInstanceMutation());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={submitForm}>
|
<form
|
||||||
|
onSubmit={submitForm}
|
||||||
|
autoComplete="none"
|
||||||
|
>
|
||||||
<h1>Instance Settings</h1>
|
<h1>Instance Settings</h1>
|
||||||
|
|
||||||
<div className="form-section-docs">
|
<div className="form-section-docs">
|
||||||
|
@ -97,7 +100,8 @@ function InstanceSettingsForm({ data: instance }: InstanceSettingsFormProps) {
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.title}
|
field={form.title}
|
||||||
label={`Instance title (max ${titleLimit} characters)`}
|
label={`Instance title (max ${titleLimit} characters)`}
|
||||||
placeholder="My GoToSocial instance"
|
autoCapitalize="words"
|
||||||
|
placeholder="My GoToSocial Instance"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="file-upload" aria-labelledby="avatar">
|
<div className="file-upload" aria-labelledby="avatar">
|
||||||
|
@ -117,6 +121,7 @@ function InstanceSettingsForm({ data: instance }: InstanceSettingsFormProps) {
|
||||||
field={form.thumbnailDesc}
|
field={form.thumbnailDesc}
|
||||||
label="Avatar image description"
|
label="Avatar image description"
|
||||||
placeholder="A cute drawing of a smiling sloth."
|
placeholder="A cute drawing of a smiling sloth."
|
||||||
|
autoCapitalize="sentences"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -139,6 +144,7 @@ function InstanceSettingsForm({ data: instance }: InstanceSettingsFormProps) {
|
||||||
field={form.shortDesc}
|
field={form.shortDesc}
|
||||||
label={`Short description (markdown accepted, max ${shortDescLimit} characters)`}
|
label={`Short description (markdown accepted, max ${shortDescLimit} characters)`}
|
||||||
placeholder="A small testing instance for the GoToSocial alpha software."
|
placeholder="A small testing instance for the GoToSocial alpha software."
|
||||||
|
autoCapitalize="sentences"
|
||||||
rows={6}
|
rows={6}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -146,6 +152,7 @@ function InstanceSettingsForm({ data: instance }: InstanceSettingsFormProps) {
|
||||||
field={form.description}
|
field={form.description}
|
||||||
label={`Full description (markdown accepted, max ${descLimit} characters)`}
|
label={`Full description (markdown accepted, max ${descLimit} characters)`}
|
||||||
placeholder="A small testing instance for the GoToSocial alpha software. Just trying it out, my main instance is https://example.com"
|
placeholder="A small testing instance for the GoToSocial alpha software. Just trying it out, my main instance is https://example.com"
|
||||||
|
autoCapitalize="sentences"
|
||||||
rows={6}
|
rows={6}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -153,6 +160,7 @@ function InstanceSettingsForm({ data: instance }: InstanceSettingsFormProps) {
|
||||||
field={form.terms}
|
field={form.terms}
|
||||||
label={`Terms & Conditions (markdown accepted, max ${termsLimit} characters)`}
|
label={`Terms & Conditions (markdown accepted, max ${termsLimit} characters)`}
|
||||||
placeholder="Terms and conditions of using this instance, data policy, imprint, GDPR stuff, yadda yadda."
|
placeholder="Terms and conditions of using this instance, data policy, imprint, GDPR stuff, yadda yadda."
|
||||||
|
autoCapitalize="sentences"
|
||||||
rows={6}
|
rows={6}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -172,12 +180,15 @@ function InstanceSettingsForm({ data: instance }: InstanceSettingsFormProps) {
|
||||||
field={form.contactUser}
|
field={form.contactUser}
|
||||||
label="Contact user (local account username)"
|
label="Contact user (local account username)"
|
||||||
placeholder="admin"
|
placeholder="admin"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.contactEmail}
|
field={form.contactEmail}
|
||||||
label="Contact email"
|
label="Contact email"
|
||||||
placeholder="admin@example.com"
|
placeholder="admin@example.com"
|
||||||
|
type="email"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<MutationButton label="Save" result={result} disabled={false} />
|
<MutationButton label="Save" result={result} disabled={false} />
|
||||||
|
|
|
@ -78,14 +78,21 @@ function ModerateAccount({ account }: { account: AdminAccount }) {
|
||||||
>
|
>
|
||||||
<h3 id="account-moderation-actions">Account Moderation Actions</h3>
|
<h3 id="account-moderation-actions">Account Moderation Actions</h3>
|
||||||
<div>
|
<div>
|
||||||
Currently only the "suspend" action is implemented.<br/>
|
Currently only the "suspend" action is implemented.
|
||||||
Suspending an account will delete it from your server, and remove all of its media, posts, relationships, etc.<br/>
|
<br/>
|
||||||
If the suspended account is local, suspending will also send out a "delete" message to other servers, requesting them to remove its data from their instance as well.<br/>
|
Suspending an account will delete it from your server,
|
||||||
|
and remove all of its media, posts, relationships, etc.
|
||||||
|
<br/>
|
||||||
|
If the suspended account is local, suspending will also
|
||||||
|
send out a "delete" message to other servers, requesting
|
||||||
|
them to remove its data from their instance as well.
|
||||||
|
<br/>
|
||||||
<b>Account suspension cannot be reversed.</b>
|
<b>Account suspension cannot be reversed.</b>
|
||||||
</div>
|
</div>
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.reason}
|
field={form.reason}
|
||||||
placeholder="Reason for this action"
|
placeholder="Reason for this action"
|
||||||
|
autoCapitalize="sentences"
|
||||||
/>
|
/>
|
||||||
<div className="action-buttons">
|
<div className="action-buttons">
|
||||||
<MutationButton
|
<MutationButton
|
||||||
|
|
|
@ -23,12 +23,16 @@ import { AccountSearchForm } from "./search";
|
||||||
export default function AccountsSearch({ }) {
|
export default function AccountsSearch({ }) {
|
||||||
return (
|
return (
|
||||||
<div className="accounts-view">
|
<div className="accounts-view">
|
||||||
|
<div className="form-section-docs">
|
||||||
<h1>Accounts Search</h1>
|
<h1>Accounts Search</h1>
|
||||||
<span>
|
<p>
|
||||||
You can perform actions on an account by clicking
|
You can perform actions on an account by clicking
|
||||||
its name in a report, or by searching for the account
|
its name in a report, or by searching for the account
|
||||||
using the form below and clicking on its name.
|
using the form below and clicking on its name.
|
||||||
</span>
|
<br/>
|
||||||
|
All fields in the below form are optional.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<AccountSearchForm />
|
<AccountSearchForm />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -44,7 +44,23 @@ export default function AccountsPending() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="accounts-view">
|
<div className="accounts-view">
|
||||||
|
<div className="form-section-docs">
|
||||||
<h1>Pending Accounts</h1>
|
<h1>Pending Accounts</h1>
|
||||||
|
<p>
|
||||||
|
You can see a list of pending account sign-ups below.
|
||||||
|
<br/>
|
||||||
|
To approve or reject a sign-up, click on the account's name in the
|
||||||
|
list, and use the controls at the bottom of the account detail view.
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href="https://docs.gotosocial.org/en/latest/admin/signups/"
|
||||||
|
target="_blank"
|
||||||
|
className="docslink"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
Learn more about account sign-ups (opens in a new tab)
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<PageableList
|
<PageableList
|
||||||
isLoading={searchRes.isLoading}
|
isLoading={searchRes.isLoading}
|
||||||
isFetching={searchRes.isFetching}
|
isFetching={searchRes.isFetching}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import MutationButton from "../../../../components/form/mutation-button";
|
||||||
import { useLocation, useSearch } from "wouter";
|
import { useLocation, useSearch } from "wouter";
|
||||||
import { AdminAccount } from "../../../../lib/types/account";
|
import { AdminAccount } from "../../../../lib/types/account";
|
||||||
import Username from "../../../../components/username";
|
import Username from "../../../../components/username";
|
||||||
|
import isValidDomain from "is-valid-domain";
|
||||||
|
|
||||||
export function AccountSearchForm() {
|
export function AccountSearchForm() {
|
||||||
const [ location, setLocation ] = useLocation();
|
const [ location, setLocation ] = useLocation();
|
||||||
|
@ -42,7 +43,31 @@ export function AccountSearchForm() {
|
||||||
permissions: useTextInput("permissions", { defaultValue: urlQueryParams.get("permissions") ?? ""}),
|
permissions: useTextInput("permissions", { defaultValue: urlQueryParams.get("permissions") ?? ""}),
|
||||||
username: useTextInput("username", { defaultValue: urlQueryParams.get("username") ?? ""}),
|
username: useTextInput("username", { defaultValue: urlQueryParams.get("username") ?? ""}),
|
||||||
display_name: useTextInput("display_name", { defaultValue: urlQueryParams.get("display_name") ?? ""}),
|
display_name: useTextInput("display_name", { defaultValue: urlQueryParams.get("display_name") ?? ""}),
|
||||||
by_domain: useTextInput("by_domain", { defaultValue: urlQueryParams.get("by_domain") ?? ""}),
|
by_domain: useTextInput("by_domain", {
|
||||||
|
defaultValue: urlQueryParams.get("by_domain") ?? "",
|
||||||
|
validator: (v: string) => {
|
||||||
|
if (v.length === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v[v.length-1] === ".") {
|
||||||
|
return "invalid domain";
|
||||||
|
}
|
||||||
|
|
||||||
|
const valid = isValidDomain(v, {
|
||||||
|
subdomain: true,
|
||||||
|
wildcard: false,
|
||||||
|
allowUnicode: true,
|
||||||
|
topLevel: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "invalid domain";
|
||||||
|
}
|
||||||
|
}),
|
||||||
email: useTextInput("email", { defaultValue: urlQueryParams.get("email") ?? ""}),
|
email: useTextInput("email", { defaultValue: urlQueryParams.get("email") ?? ""}),
|
||||||
ip: useTextInput("ip", { defaultValue: urlQueryParams.get("ip") ?? ""}),
|
ip: useTextInput("ip", { defaultValue: urlQueryParams.get("ip") ?? ""}),
|
||||||
limit: useTextInput("limit", { defaultValue: urlQueryParams.get("limit") ?? "50"})
|
limit: useTextInput("limit", { defaultValue: urlQueryParams.get("limit") ?? "50"})
|
||||||
|
@ -109,13 +134,17 @@ export function AccountSearchForm() {
|
||||||
>
|
>
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.username}
|
field={form.username}
|
||||||
label={"(Optional) username (without leading '@' symbol)"}
|
label={`Username (without "@" prefix) - case sensitive`}
|
||||||
placeholder="someone"
|
placeholder="someone"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.by_domain}
|
field={form.by_domain}
|
||||||
label={"(Optional) domain"}
|
label={`Domain (without "https://" prefix)`}
|
||||||
placeholder="example.org"
|
placeholder="example.org"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
field={form.origin}
|
field={form.origin}
|
||||||
|
@ -130,15 +159,18 @@ export function AccountSearchForm() {
|
||||||
></Select>
|
></Select>
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.email}
|
field={form.email}
|
||||||
label={"(Optional) email address (local accounts only)"}
|
label={"Email address (local accounts only)"}
|
||||||
placeholder={"someone@example.org"}
|
placeholder={"someone@example.org"}
|
||||||
// Get email validation for free.
|
// Get email validation for free.
|
||||||
{...{type: "email"}}
|
type="email"
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.ip}
|
field={form.ip}
|
||||||
label={"(Optional) IP address (local accounts only)"}
|
label={"IP address (local accounts only)"}
|
||||||
placeholder={"198.51.100.0"}
|
placeholder={"198.51.100.0"}
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
|
className="monospace"
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
field={form.status}
|
field={form.status}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import { NoArg } from "../../../lib/types/query";
|
||||||
import { Error } from "../../../components/error";
|
import { Error } from "../../../components/error";
|
||||||
import { useBaseUrl } from "../../../lib/navigation/util";
|
import { useBaseUrl } from "../../../lib/navigation/util";
|
||||||
import { PermType } from "../../../lib/types/perm";
|
import { PermType } from "../../../lib/types/perm";
|
||||||
|
import isValidDomain from "is-valid-domain";
|
||||||
|
|
||||||
export default function DomainPermDetail() {
|
export default function DomainPermDetail() {
|
||||||
const baseUrl = useBaseUrl();
|
const baseUrl = useBaseUrl();
|
||||||
|
@ -139,7 +140,32 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps)
|
||||||
};
|
};
|
||||||
|
|
||||||
const form = {
|
const form = {
|
||||||
domain: useTextInput("domain", { source: perm, defaultValue: defaultDomain }),
|
domain: useTextInput("domain", {
|
||||||
|
source: perm,
|
||||||
|
defaultValue: defaultDomain,
|
||||||
|
validator: (v: string) => {
|
||||||
|
if (v.length === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v[v.length-1] === ".") {
|
||||||
|
return "invalid domain";
|
||||||
|
}
|
||||||
|
|
||||||
|
const valid = isValidDomain(v, {
|
||||||
|
subdomain: true,
|
||||||
|
wildcard: false,
|
||||||
|
allowUnicode: true,
|
||||||
|
topLevel: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "invalid domain";
|
||||||
|
}
|
||||||
|
}),
|
||||||
obfuscate: useBoolInput("obfuscate", { source: perm }),
|
obfuscate: useBoolInput("obfuscate", { source: perm }),
|
||||||
commentPrivate: useTextInput("private_comment", { source: perm }),
|
commentPrivate: useTextInput("private_comment", { source: perm }),
|
||||||
commentPublic: useTextInput("public_comment", { source: perm })
|
commentPublic: useTextInput("public_comment", { source: perm })
|
||||||
|
@ -208,6 +234,8 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps)
|
||||||
field={form.domain}
|
field={form.domain}
|
||||||
label="Domain"
|
label="Domain"
|
||||||
placeholder="example.com"
|
placeholder="example.com"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
{...disabledForm}
|
{...disabledForm}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -220,6 +248,7 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps)
|
||||||
<TextArea
|
<TextArea
|
||||||
field={form.commentPrivate}
|
field={form.commentPrivate}
|
||||||
label="Private comment"
|
label="Private comment"
|
||||||
|
autoCapitalize="sentences"
|
||||||
rows={3}
|
rows={3}
|
||||||
{...disabledForm}
|
{...disabledForm}
|
||||||
/>
|
/>
|
||||||
|
@ -227,6 +256,7 @@ function DomainPermForm({ defaultDomain, perm, permType }: DomainPermFormProps)
|
||||||
<TextArea
|
<TextArea
|
||||||
field={form.commentPublic}
|
field={form.commentPublic}
|
||||||
label="Public comment"
|
label="Public comment"
|
||||||
|
autoCapitalize="sentences"
|
||||||
rows={3}
|
rows={3}
|
||||||
{...disabledForm}
|
{...disabledForm}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -80,9 +80,12 @@ export default function ImportExportForm({ form, submitParse, parseResult }: Imp
|
||||||
<div className="import-export">
|
<div className="import-export">
|
||||||
<TextArea
|
<TextArea
|
||||||
field={form.domains}
|
field={form.domains}
|
||||||
label="Domains"
|
label="Domains (newline-separated)"
|
||||||
placeholder={`google.com\nfacebook.com`}
|
placeholder={`google.com\nfacebook.com`}
|
||||||
rows={8}
|
rows={8}
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
|
className={"monospace"}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
|
|
|
@ -66,9 +66,11 @@ export default function DomainPermissionsOverview() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={`domain-${permType}`}>
|
||||||
|
<div className="form-section-docs">
|
||||||
<h1>Domain {permTypeUpper}s</h1>
|
<h1>Domain {permTypeUpper}s</h1>
|
||||||
{ permType == "block" ? <BlockHelperText/> : <AllowHelperText/> }
|
{ permType == "block" ? <BlockHelperText/> : <AllowHelperText/> }
|
||||||
|
</div>
|
||||||
<DomainPermsList
|
<DomainPermsList
|
||||||
data={data}
|
data={data}
|
||||||
permType={permType}
|
permType={permType}
|
||||||
|
@ -77,7 +79,7 @@ export default function DomainPermissionsOverview() {
|
||||||
<Link to={`~${baseUrl}/import-export`}>
|
<Link to={`~${baseUrl}/import-export`}>
|
||||||
Or use the bulk import/export interface
|
Or use the bulk import/export interface
|
||||||
</Link>
|
</Link>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -213,14 +213,18 @@ function ReportActionForm({ report }) {
|
||||||
This is useful for providing an explanation about what action was
|
This is useful for providing an explanation about what action was
|
||||||
taken (if any) before the report was marked as resolved.
|
taken (if any) before the report was marked as resolved.
|
||||||
<br />
|
<br />
|
||||||
|
<div className="info">
|
||||||
|
<i className="fa fa-fw fa-exclamation-triangle" aria-hidden="true"></i>
|
||||||
<b>
|
<b>
|
||||||
Any comment made here will be visible
|
If the report was created by a local account, then any
|
||||||
to the user that created the report!
|
comment made here will be emailed to that account's user!
|
||||||
</b>
|
</b>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
<TextArea
|
<TextArea
|
||||||
field={form.comment}
|
field={form.comment}
|
||||||
label="Comment"
|
label="Comment"
|
||||||
|
autoCapitalize="sentences"
|
||||||
/>
|
/>
|
||||||
<MutationButton
|
<MutationButton
|
||||||
disabled={false}
|
disabled={false}
|
||||||
|
|
|
@ -135,6 +135,8 @@ function AlsoKnownAsURI({ index, data }) {
|
||||||
label={`Alias #${index+1}`}
|
label={`Alias #${index+1}`}
|
||||||
field={form.alsoKnownAsURI}
|
field={form.alsoKnownAsURI}
|
||||||
placeholder={`https://example.org/users/my_other_account_${index+1}`}
|
placeholder={`https://example.org/users/my_other_account_${index+1}`}
|
||||||
|
type="url"
|
||||||
|
pattern="(http|https):\/\/.+"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -190,10 +192,13 @@ function MoveForm({ data: profile }) {
|
||||||
field={form.movedToURI}
|
field={form.movedToURI}
|
||||||
label="Move target URI"
|
label="Move target URI"
|
||||||
placeholder="https://example.org/users/my_new_account"
|
placeholder="https://example.org/users/my_new_account"
|
||||||
|
type="url"
|
||||||
|
pattern="(http|https):\/\/.+"
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
disabled={false}
|
disabled={false}
|
||||||
type="password"
|
type="password"
|
||||||
|
autoComplete="current-password"
|
||||||
name="password"
|
name="password"
|
||||||
field={form.password}
|
field={form.password}
|
||||||
label="Current account password"
|
label="Current account password"
|
||||||
|
|
|
@ -175,12 +175,15 @@ function UserProfileForm({ data: profile }) {
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.displayName}
|
field={form.displayName}
|
||||||
label="Display name"
|
label="Display name"
|
||||||
placeholder="A GoToSocial user"
|
placeholder="A GoToSocial User"
|
||||||
|
autoCapitalize="words"
|
||||||
|
spellCheck="false"
|
||||||
/>
|
/>
|
||||||
<TextArea
|
<TextArea
|
||||||
field={form.note}
|
field={form.note}
|
||||||
label="Bio"
|
label="Bio"
|
||||||
placeholder="Just trying out GoToSocial, my pronouns are they/them and I like sloths."
|
placeholder="Just trying out GoToSocial, my pronouns are they/them and I like sloths."
|
||||||
|
autoCapitalize="sentences"
|
||||||
rows={8}
|
rows={8}
|
||||||
/>
|
/>
|
||||||
<b>Profile fields</b>
|
<b>Profile fields</b>
|
||||||
|
@ -233,6 +236,8 @@ function UserProfileForm({ data: profile }) {
|
||||||
className="monospace"
|
className="monospace"
|
||||||
rows={8}
|
rows={8}
|
||||||
disabled={!instanceConfig.allowCustomCSS}
|
disabled={!instanceConfig.allowCustomCSS}
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
/>
|
/>
|
||||||
<MutationButton
|
<MutationButton
|
||||||
disabled={false}
|
disabled={false}
|
||||||
|
@ -270,10 +275,14 @@ function Field({ index, data }) {
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.name}
|
field={form.name}
|
||||||
placeholder="Name"
|
placeholder="Name"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
field={form.value}
|
field={form.value}
|
||||||
placeholder="Value"
|
placeholder="Value"
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -58,6 +58,8 @@
|
||||||
required
|
required
|
||||||
placeholder="Please enter your desired username"
|
placeholder="Please enter your desired username"
|
||||||
pattern="^[a-z0-9_]{1,64}$"
|
pattern="^[a-z0-9_]{1,64}$"
|
||||||
|
autocapitalize="off"
|
||||||
|
spellcheck="false"
|
||||||
title="lowercase a-z, numbers, and underscores; max 64 characters"
|
title="lowercase a-z, numbers, and underscores; max 64 characters"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,6 +77,7 @@
|
||||||
rows="8"
|
rows="8"
|
||||||
minlength="40"
|
minlength="40"
|
||||||
maxlength="500"
|
maxlength="500"
|
||||||
|
autocapitalize="sentences"
|
||||||
title="40-500 characters"
|
title="40-500 characters"
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue