mirror of
https://github.com/LemmyNet/lemmy-ui.git
synced 2024-11-22 04:11:12 +00:00
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:
parent
0dbfe050cf
commit
ddd4a98fd7
4 changed files with 97 additions and 1 deletions
|
@ -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
|
77
src/shared/components/common/url-list-textarea.tsx
Normal file
77
src/shared/components/common/url-list-textarea.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue