Block urls (#2409)

* Add markup

* Make textarea reactive

* Fix bug mixing up urls and instances

* Tweak url enforcement logic

* Extract url list textarea to component

* Add translations

* Add pnpm lock to prettier ignore
This commit is contained in:
SleeplessOne1917 2024-04-11 12:56:56 +00:00 committed by GitHub
parent 0dbfe050cf
commit ddd4a98fd7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 97 additions and 1 deletions

View file

@ -4,3 +4,4 @@ src/assets/css/themes/*.css
src/assets/css/code-themes/*.css src/assets/css/code-themes/*.css
stats.json stats.json
dist dist
pnpm-lock.yaml

@ -1 +1 @@
Subproject commit 9a8a86ea2edbd0ebed98f649805e69431b692dab Subproject commit b0dab329ce23cfaec4a3a034ea2fee210888922e

View file

@ -0,0 +1,77 @@
import { linkEvent, Component } from "inferno";
import { I18NextService } from "../../services/I18NextService";
interface UrlListTextareaProps {
urls: string[];
onUpdate(urls: string[]): void;
}
interface UrlListTextareaState {
text: string;
}
function handleTextChange(i: UrlListTextarea, event: any) {
i.setState({ text: event.target.value });
}
function handleTextBlur(i: UrlListTextarea, event: any) {
const inputValue: string = event.currentTarget?.value ?? "";
const intermediateText = inputValue.replace(/\s+/g, "\n");
const newUrls: string[] = [];
for (const str of intermediateText.split("\n")) {
let url: string;
try {
url = new URL(str).toString();
} catch {
try {
url = new URL("https://" + str).toString();
} catch {
continue;
}
}
if (newUrls.every(u => u !== url)) {
newUrls.push(url);
}
}
i.setState({ text: newUrls.join("\n") });
i.props.onUpdate(newUrls);
}
export default class UrlListTextarea extends Component<
UrlListTextareaProps,
UrlListTextareaState
> {
state: UrlListTextareaState = {
text: "",
};
render() {
return (
<div className="mb-3 row">
<label
className="col-12 col-form-label"
htmlFor="create-site-block-urls"
>
{I18NextService.i18n.t("block_urls")}
</label>
<div className="col-12">
<textarea
id="create-site-block-urls"
className="form-control"
placeholder={I18NextService.i18n.t("block_urls_placeholder")}
value={this.state.text}
onInput={linkEvent(this, handleTextChange)}
onBlur={linkEvent(this, handleTextBlur)}
rows={4}
/>
</div>
</div>
);
}
}

View file

@ -21,6 +21,7 @@ import { ImageUploadForm } from "../common/image-upload-form";
import { LanguageSelect } from "../common/language-select"; import { LanguageSelect } from "../common/language-select";
import { ListingTypeSelect } from "../common/listing-type-select"; import { ListingTypeSelect } from "../common/listing-type-select";
import { MarkdownTextArea } from "../common/markdown-textarea"; import { MarkdownTextArea } from "../common/markdown-textarea";
import UrlListTextarea from "../common/url-list-textarea";
interface SiteFormProps { interface SiteFormProps {
blockedInstances?: Instance[]; blockedInstances?: Instance[];
@ -84,6 +85,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
captcha_difficulty: ls.captcha_difficulty, captcha_difficulty: ls.captcha_difficulty,
allowed_instances: this.props.allowedInstances?.map(i => i.domain), allowed_instances: this.props.allowedInstances?.map(i => i.domain),
blocked_instances: this.props.blockedInstances?.map(i => i.domain), blocked_instances: this.props.blockedInstances?.map(i => i.domain),
blocked_urls: this.props.siteRes.blocked_urls.map(u => u.url),
}; };
} }
@ -112,6 +114,8 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
this.handleInstanceEnterPress = this.handleInstanceEnterPress.bind(this); this.handleInstanceEnterPress = this.handleInstanceEnterPress.bind(this);
this.handleInstanceTextChange = this.handleInstanceTextChange.bind(this); this.handleInstanceTextChange = this.handleInstanceTextChange.bind(this);
this.handleBlockedUrlsUpdate = this.handleBlockedUrlsUpdate.bind(this);
} }
render() { render() {
@ -500,6 +504,10 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
onChange={this.handleDiscussionLanguageChange} onChange={this.handleDiscussionLanguageChange}
showAll showAll
/> />
<UrlListTextarea
urls={this.state.siteForm.blocked_urls ?? []}
onUpdate={this.handleBlockedUrlsUpdate}
/>
<div className="mb-3 row"> <div className="mb-3 row">
<label <label
className="col-12 col-form-label" className="col-12 col-form-label"
@ -994,4 +1002,14 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
handleDefaultPostListingTypeChange(val: ListingType) { handleDefaultPostListingTypeChange(val: ListingType) {
this.setState(s => ((s.siteForm.default_post_listing_type = val), s)); this.setState(s => ((s.siteForm.default_post_listing_type = val), s));
} }
handleBlockedUrlsUpdate(newBlockedUrls: string[]) {
this.setState(prev => ({
...prev,
siteForm: {
...prev.siteForm,
blocked_urls: newBlockedUrls,
},
}));
}
} }