Merge branch 'nicer-error-hnadling' of https://github.com/SleeplessOne1917/lemmy-ui into nicer-error-hnadling

This commit is contained in:
abias 2023-05-19 13:06:34 -04:00
commit cbee588484
3 changed files with 141 additions and 60 deletions

View file

@ -106,6 +106,9 @@
<symbol id="icon-refresh-cw" viewBox="0 0 24 24">
<path d="M4.453 9.334c0.737-2.083 2.247-3.669 4.096-4.552s4.032-1.059 6.114-0.322c1.186 0.42 2.206 1.088 2.983 1.88l2.83 2.66h-3.476c-0.552 0-1 0.448-1 1s0.448 1 1 1h5.997c0.005 0 0.009 0 0.014 0 0.137-0.001 0.268-0.031 0.386-0.082 0.119-0.051 0.229-0.126 0.324-0.225 0.012-0.013 0.024-0.026 0.036-0.039 0.075-0.087 0.133-0.183 0.173-0.285s0.064-0.211 0.069-0.326c0.001-0.015 0.001-0.029 0.001-0.043v-6c0-0.552-0.448-1-1-1s-1 0.448-1 1v3.689l-2.926-2.749c-0.992-1.010-2.271-1.843-3.743-2.364-2.603-0.921-5.335-0.699-7.643 0.402s-4.199 3.086-5.12 5.689c-0.185 0.52 0.088 1.091 0.608 1.276s1.092-0.088 1.276-0.609zM2 16.312l2.955 2.777c1.929 1.931 4.49 2.908 7.048 2.909s5.119-0.975 7.072-2.927c1.104-1.104 1.901-2.407 2.361-3.745 0.18-0.522-0.098-1.091-0.621-1.271s-1.091 0.098-1.271 0.621c-0.361 1.050-0.993 2.091-1.883 2.981-1.563 1.562-3.609 2.342-5.657 2.342s-4.094-0.782-5.679-2.366l-2.8-2.633h3.475c0.552 0 1-0.448 1-1s-0.448-1-1-1h-5.997c-0.005 0-0.009 0-0.014 0-0.137 0.001-0.268 0.031-0.386 0.082-0.119 0.051-0.229 0.126-0.324 0.225-0.012 0.013-0.024 0.026-0.036 0.039-0.075 0.087-0.133 0.183-0.173 0.285s-0.064 0.211-0.069 0.326c-0.001 0.015-0.001 0.029-0.001 0.043v6c0 0.552 0.448 1 1 1s1-0.448 1-1z"></path>
</symbol>
<symbol id="icon-add" viewBox="0 0 32 32" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<path d="M14.5,14.501l-10.502,0c-0.828,0 -1.5,0.673 -1.5,1.5c0,0.828 0.672,1.5 1.5,1.5l10.502,0l-0.001,10.502c0,0.828 0.672,1.5 1.5,1.501c0.828,-0 1.5,-0.673 1.5,-1.5l0.001,-10.503l10.502,0c0.828,0 1.5,-0.672 1.5,-1.5c0,-0.827 -0.672,-1.5 -1.5,-1.5l-10.502,0l0.001,-10.501c-0,-0.828 -0.672,-1.501 -1.5,-1.501c-0.828,0 -1.5,0.672 -1.5,1.5l-0.001,10.502Z"/>
</symbol>
<symbol id="icon-play" viewBox="0 0 24 24">
<path d="M5.541 2.159c-0.153-0.1-0.34-0.159-0.541-0.159-0.552 0-1 0.448-1 1v18c-0.001 0.182 0.050 0.372 0.159 0.541 0.299 0.465 0.917 0.599 1.382 0.3l14-9c0.114-0.072 0.219-0.174 0.3-0.3 0.299-0.465 0.164-1.083-0.3-1.382zM6 4.832l11.151 7.168-11.151 7.168z"></path>
</symbol>

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View file

@ -1,4 +1,9 @@
import { Component, InfernoMouseEvent, linkEvent } from "inferno";
import {
Component,
InfernoKeyboardEvent,
InfernoMouseEvent,
linkEvent,
} from "inferno";
import { Prompt } from "inferno-router";
import {
CreateSite,
@ -15,7 +20,7 @@ import {
myAuth,
wsClient,
} from "../../utils";
import { Spinner } from "../common/icon";
import { Icon, Spinner } from "../common/icon";
import { ImageUploadForm } from "../common/image-upload-form";
import { LanguageSelect } from "../common/language-select";
import { ListingTypeSelect } from "../common/listing-type-select";
@ -31,14 +36,24 @@ interface SiteFormState {
siteForm: EditSite;
loading: boolean;
themeList?: string[];
instance_select: {
allowed_instances: string;
blocked_instances: string;
};
}
type InstanceKey = "allowed_instances" | "blocked_instances";
export class SiteForm extends Component<SiteFormProps, SiteFormState> {
state: SiteFormState = {
siteForm: {
auth: "TODO",
},
loading: false,
instance_select: {
allowed_instances: "",
blocked_instances: "",
},
};
constructor(props: any, context: any) {
@ -554,44 +569,8 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
{this.state.siteForm.federation_enabled && (
<>
<div className="form-group row">
<label
className="col-12 col-form-label"
htmlFor="create-site-allowed-instances"
>
{i18n.t("allowed_instances")}
</label>
<div className="col-12">
<input
type="text"
placeholder="instance1.tld,instance2.tld"
id="create-site-allowed-instances"
className="form-control"
value={this.instancesToString(
this.state.siteForm.allowed_instances
)}
onInput={linkEvent(this, this.handleSiteAllowedInstances)}
/>
</div>
</div>
<div className="form-group row">
<label
className="col-12 col-form-label"
htmlFor="create-site-blocked-instances"
>
{i18n.t("blocked_instances")}
</label>
<div className="col-12">
<input
type="text"
placeholder="instance1.tld,instance2.tld"
id="create-site-blocked-instances"
className="form-control"
value={this.instancesToString(
this.state.siteForm.blocked_instances
)}
onInput={linkEvent(this, this.handleSiteBlockedInstances)}
/>
</div>
{this.federatedInstanceSelect("allowed_instances")}
{this.federatedInstanceSelect("blocked_instances")}
</div>
<div className="form-group row">
<div className="col-12">
@ -930,6 +909,86 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
);
}
federatedInstanceSelect(key: InstanceKey) {
const id = `create_site_${key}`;
const value = this.state.instance_select[key];
const selectedInstances = this.state.siteForm[key];
return (
<div className="col-12 col-md-6">
<label className="col-form-label" htmlFor={id}>
{i18n.t(key)}
</label>
<div className="d-flex justify-content-between align-items-center">
<input
type="text"
placeholder="instance.tld"
id={id}
className="form-control"
value={value}
onInput={linkEvent(key, this.handleInstanceTextChange)}
onKeyUp={linkEvent(key, this.handleInstanceEnterPress)}
/>
<button
type="button"
className="btn btn-sm bg-success ml-2"
onClick={linkEvent(key, this.handleAddInstance)}
tabIndex={
-1 /* Making this untabble because handling enter key in text input makes keyboard support for this button redundant */
}
>
<Icon icon="add" classes="icon-inline text-light m-auto" />
</button>
</div>
{selectedInstances && selectedInstances.length > 0 && (
<ul className="mt-3 list-unstyled w-100 d-flex flex-column justify-content-around align-items-center">
{selectedInstances.map(instance => (
<li
key={instance}
className="my-1 w-100 w-md-75 d-flex align-items-center justify-content-between"
>
<label className="d-block m-0 w-100 " htmlFor={instance}>
<strong>{instance}</strong>
</label>
<button
id={instance}
type="button"
className="btn btn-sm bg-danger"
onClick={linkEvent(
{ key, instance },
this.handleRemoveInstance
)}
>
<Icon icon="x" classes="icon-inline text-light m-auto" />
</button>
</li>
))}
</ul>
)}
</div>
);
}
handleInstanceTextChange(type: InstanceKey, event: any) {
this.setState(s => ({
...s,
instance_select: {
...s.instance_select,
[type]: event.target.value,
},
}));
}
handleInstanceEnterPress(
key: InstanceKey,
event: InfernoKeyboardEvent<HTMLInputElement>
) {
if (event.code.toLowerCase() === "enter") {
event.preventDefault();
this.handleAddInstance(key);
}
}
handleCreateSiteSubmit(i: SiteForm, event: any) {
event.preventDefault();
i.setState({ loading: true });
@ -986,18 +1045,43 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
i.setState(i.state);
}
instancesToString(opt?: string[]): string {
return opt ? opt.join(",") : "";
handleAddInstance(key: InstanceKey) {
const instance = this.state.instance_select[key].trim();
if (!this.state.siteForm[key]?.includes(instance)) {
this.setState(s => ({
...s,
siteForm: {
...s.siteForm,
[key]: [...(s.siteForm[key] ?? []), instance],
},
instance_select: {
...s.instance_select,
[key]: "",
},
}));
const oppositeKey: InstanceKey =
key === "allowed_instances" ? "blocked_instances" : "allowed_instances";
if (this.state.siteForm[oppositeKey]?.includes(instance)) {
this.handleRemoveInstance({ key: oppositeKey, instance });
}
}
}
handleSiteAllowedInstances(i: SiteForm, event: any) {
let list = splitToList(event.target.value);
i.setState(s => ((s.siteForm.allowed_instances = list), s));
}
handleSiteBlockedInstances(i: SiteForm, event: any) {
let list = splitToList(event.target.value);
i.setState(s => ((s.siteForm.blocked_instances = list), s));
handleRemoveInstance({
key,
instance,
}: {
key: InstanceKey;
instance: string;
}) {
this.setState(s => ({
...s,
siteForm: {
...s.siteForm,
[key]: s.siteForm[key]?.filter(i => i !== instance),
},
}));
}
handleSiteNameChange(i: SiteForm, event: any) {
@ -1259,12 +1343,3 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
this.setState(s => ((s.siteForm.default_post_listing_type = val), s));
}
}
function splitToList(commaList: string): string[] {
if (commaList !== "") {
let list = commaList.trim().split(",");
return list;
} else {
return [];
}
}

View file

@ -123,9 +123,12 @@ const createClientConfig = (_env, mode) => {
urlPattern: ({ url: { pathname, host }, sameOrigin }) =>
(sameOrigin || host.includes("localhost")) &&
pathname.includes("static"),
handler: "CacheFirst",
handler: mode === "development" ? "NetworkFirst" : "CacheFirst",
options: {
cacheName: "static-cache",
expiration: {
maxAgeSeconds: 60 * 60 * 24,
},
},
},
{