Skip to content

Commit ddd4a98

Browse files
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
1 parent 0dbfe05 commit ddd4a98

File tree

4 files changed

+97
-1
lines changed

4 files changed

+97
-1
lines changed

.prettierignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ src/assets/css/themes/*.css
44
src/assets/css/code-themes/*.css
55
stats.json
66
dist
7+
pnpm-lock.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { linkEvent, Component } from "inferno";
2+
import { I18NextService } from "../../services/I18NextService";
3+
4+
interface UrlListTextareaProps {
5+
urls: string[];
6+
onUpdate(urls: string[]): void;
7+
}
8+
9+
interface UrlListTextareaState {
10+
text: string;
11+
}
12+
13+
function handleTextChange(i: UrlListTextarea, event: any) {
14+
i.setState({ text: event.target.value });
15+
}
16+
17+
function handleTextBlur(i: UrlListTextarea, event: any) {
18+
const inputValue: string = event.currentTarget?.value ?? "";
19+
20+
const intermediateText = inputValue.replace(/\s+/g, "\n");
21+
const newUrls: string[] = [];
22+
23+
for (const str of intermediateText.split("\n")) {
24+
let url: string;
25+
26+
try {
27+
url = new URL(str).toString();
28+
} catch {
29+
try {
30+
url = new URL("https://" + str).toString();
31+
} catch {
32+
continue;
33+
}
34+
}
35+
36+
if (newUrls.every(u => u !== url)) {
37+
newUrls.push(url);
38+
}
39+
}
40+
41+
i.setState({ text: newUrls.join("\n") });
42+
i.props.onUpdate(newUrls);
43+
}
44+
45+
export default class UrlListTextarea extends Component<
46+
UrlListTextareaProps,
47+
UrlListTextareaState
48+
> {
49+
state: UrlListTextareaState = {
50+
text: "",
51+
};
52+
53+
render() {
54+
return (
55+
<div className="mb-3 row">
56+
<label
57+
className="col-12 col-form-label"
58+
htmlFor="create-site-block-urls"
59+
>
60+
{I18NextService.i18n.t("block_urls")}
61+
</label>
62+
63+
<div className="col-12">
64+
<textarea
65+
id="create-site-block-urls"
66+
className="form-control"
67+
placeholder={I18NextService.i18n.t("block_urls_placeholder")}
68+
value={this.state.text}
69+
onInput={linkEvent(this, handleTextChange)}
70+
onBlur={linkEvent(this, handleTextBlur)}
71+
rows={4}
72+
/>
73+
</div>
74+
</div>
75+
);
76+
}
77+
}

src/shared/components/home/site-form.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ImageUploadForm } from "../common/image-upload-form";
2121
import { LanguageSelect } from "../common/language-select";
2222
import { ListingTypeSelect } from "../common/listing-type-select";
2323
import { MarkdownTextArea } from "../common/markdown-textarea";
24+
import UrlListTextarea from "../common/url-list-textarea";
2425

2526
interface SiteFormProps {
2627
blockedInstances?: Instance[];
@@ -84,6 +85,7 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
8485
captcha_difficulty: ls.captcha_difficulty,
8586
allowed_instances: this.props.allowedInstances?.map(i => i.domain),
8687
blocked_instances: this.props.blockedInstances?.map(i => i.domain),
88+
blocked_urls: this.props.siteRes.blocked_urls.map(u => u.url),
8789
};
8890
}
8991

@@ -112,6 +114,8 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
112114

113115
this.handleInstanceEnterPress = this.handleInstanceEnterPress.bind(this);
114116
this.handleInstanceTextChange = this.handleInstanceTextChange.bind(this);
117+
118+
this.handleBlockedUrlsUpdate = this.handleBlockedUrlsUpdate.bind(this);
115119
}
116120

117121
render() {
@@ -500,6 +504,10 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
500504
onChange={this.handleDiscussionLanguageChange}
501505
showAll
502506
/>
507+
<UrlListTextarea
508+
urls={this.state.siteForm.blocked_urls ?? []}
509+
onUpdate={this.handleBlockedUrlsUpdate}
510+
/>
503511
<div className="mb-3 row">
504512
<label
505513
className="col-12 col-form-label"
@@ -994,4 +1002,14 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
9941002
handleDefaultPostListingTypeChange(val: ListingType) {
9951003
this.setState(s => ((s.siteForm.default_post_listing_type = val), s));
9961004
}
1005+
1006+
handleBlockedUrlsUpdate(newBlockedUrls: string[]) {
1007+
this.setState(prev => ({
1008+
...prev,
1009+
siteForm: {
1010+
...prev.siteForm,
1011+
blocked_urls: newBlockedUrls,
1012+
},
1013+
}));
1014+
}
9971015
}

0 commit comments

Comments
 (0)