Skip to content

Commit

Permalink
feat: Check that URL is valid before allowing submission (#589)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fleker authored Oct 4, 2022
1 parent c8c4db8 commit 22c4183
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 14 deletions.
14 changes: 11 additions & 3 deletions client/src/BadgePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ import Form from 'react-bootstrap/esm/Form';
/**
* Image for previewing a badge with a custom icon, or placeholder text if no image is uploaded
*/
class BadgePreview extends React.Component<{ url: string, label: string }> {
static handleError = (event: React.SyntheticEvent<HTMLImageElement>) => {
class BadgePreview extends React.Component<{ url: string, label: string, onPreviewSuccessfulChange: (isSuccessful: boolean) => void }> {
handleSuccess = (event: React.SyntheticEvent<HTMLImageElement>) => {
const target = event.target as HTMLImageElement;
if (!target.src.includes("failed%20to%20load")) {
this.props.onPreviewSuccessfulChange(true)
}
}

handleError = (event: React.SyntheticEvent<HTMLImageElement>) => {
const target = event.target as HTMLImageElement;
if (!target.src.includes("critical")) {
this.props.onPreviewSuccessfulChange(false)
target.src = "https://custom-icon-badges.demolab.com/badge/failed%20to%20load-try%20compressing%20the%20image%20to%20make%20it%20smaller-critical?logo=x-circle-fill";
}
}
Expand All @@ -18,7 +26,7 @@ class BadgePreview extends React.Component<{ url: string, label: string }> {
return (
<Form.Group controlId="formFile" className="mb-3 d-flex align-items-center flex-column">
<h3>{label}</h3>
{url ? <img className="m-2" src={url} alt="badge preview" onError={BadgePreview.handleError} /> : <Card.Text className="text-muted m-2">Upload a file to see a preview</Card.Text>}
{url ? <img className="m-2" src={url} alt="badge preview" onLoad={this.handleSuccess} onError={this.handleError} /> : <Card.Text className="text-muted m-2">Upload a file to see a preview</Card.Text>}
</Form.Group>
);
}
Expand Down
6 changes: 3 additions & 3 deletions client/src/FileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Form from 'react-bootstrap/esm/Form';
/**
* Class for handling the file upload form group
*/
class FileUpload extends React.Component<{ label: string, onFileChange: (fileName: string, dataUrl: string) => void }> {
class FileUpload extends React.Component<{ label: string, secondaryLabel: string, onFileChange: (fileName: string, dataUrl: string) => void }> {
handleChange = (event: ChangeEvent<HTMLInputElement>) => {
event.preventDefault();
const target = event.target as HTMLInputElement;
Expand All @@ -26,10 +26,10 @@ class FileUpload extends React.Component<{ label: string, onFileChange: (fileNam
}

render = () => {
const { label } = this.props;
const { label, secondaryLabel } = this.props;
return (
<Form.Group controlId="formFile" className="mb-3">
<Form.Label>{label}</Form.Label>
<Form.Label>{label} <span className="text-muted">{secondaryLabel}</span></Form.Label>
<Form.Control
type="file"
onChange={this.handleChange}
Expand Down
6 changes: 3 additions & 3 deletions client/src/TextBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import Form from 'react-bootstrap/esm/Form';
/**
* Text box for handling the slug input
*/
class TextBox extends React.Component<{ label: string, required: boolean | undefined, value: string, onInputChange: (slug: string) => void }> {
class TextBox extends React.Component<{ label: string, secondaryLabel: string, required: boolean | undefined, value: string, onInputChange: (slug: string) => void }> {
handleChangeEvent = (event: ChangeEvent<HTMLInputElement>) => {
const { onInputChange } = this.props;
onInputChange(event.target.value);
}

render = () => {
const { label, required, value } = this.props;
const { label, secondaryLabel, required, value } = this.props;
return <Form.Group className="mb-3">
<Form.Label>{label}</Form.Label>
<Form.Label>{label} <span className="text-muted">{secondaryLabel}</span></Form.Label>
<Form.Control type="text"
value={value}
required={required}
Expand Down
17 changes: 12 additions & 5 deletions client/src/UploadForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "./UploadForm.scss";
/**
* Class for handling the upload form
*/
class UploadForm extends React.Component<{}, { slug: string, type: string, data: string, previewUrl: string, message: { type: string, content: JSX.Element }, isLoading: boolean }> { // skipcq: JS-0296
class UploadForm extends React.Component<{}, { slug: string, type: string, data: string, previewUrl: string, previewSuccessful: boolean, message: { type: string, content: JSX.Element }, isLoading: boolean }> { // skipcq: JS-0296
constructor(props = {}) {
super(props);
this.state = {
Expand All @@ -20,6 +20,7 @@ class UploadForm extends React.Component<{}, { slug: string, type: string, data:
previewUrl: "",
message: { type: "", content: <div /> },
isLoading: false,
previewSuccessful: false,
};
}

Expand Down Expand Up @@ -114,6 +115,10 @@ class UploadForm extends React.Component<{}, { slug: string, type: string, data:
this.setIsLoading(false);
});
};

handlePreviewSuccessChange = (isSuccessful: boolean) => {
this.setState({previewSuccessful: isSuccessful});
};

static buildShieldUrl = (
dataUrl: string = "",
Expand All @@ -129,20 +134,22 @@ class UploadForm extends React.Component<{}, { slug: string, type: string, data:
};

render = () => {
const { slug, previewUrl, message, isLoading } = this.state;
const { slug, previewUrl, previewSuccessful, message, isLoading } = this.state;
return <Form onSubmit={this.handleSubmit} className="Form">
<h3 className="d-flex justify-content-center">Add an icon</h3>
<FileUpload
label="Upload an image file"
secondaryLabel="(Maximum size: ≈9kB)"
onFileChange={this.updateFileData}
/>
<TextBox
label="Pick a slug (name of the logo)"
label="Pick a slug"
secondaryLabel="(Name of the logo)"
value={slug}
onInputChange={this.updateSlug}
required
/>
<BadgePreview label="Preview" url={previewUrl} />
<BadgePreview label="Preview" url={previewUrl} onPreviewSuccessfulChange={this.handlePreviewSuccessChange} />
{message.type ? (
<Alert variant={message.type || undefined}>
{message.content}
Expand All @@ -153,7 +160,7 @@ class UploadForm extends React.Component<{}, { slug: string, type: string, data:
type="submit"
size="lg"
className="submit-btn"
disabled={!previewUrl || isLoading}
disabled={!previewUrl || isLoading || !previewSuccessful}
>
<div className={isLoading ? "loading-icon" : ""} />
Submit
Expand Down

0 comments on commit 22c4183

Please sign in to comment.