1 import { None, Option, Some } from "@sniptt/monads";
2 import { Component, linkEvent } from "inferno";
5 BlockCommunityResponse,
23 } from "lemmy-js-client";
24 import { Subscription } from "rxjs";
25 import { i18n, languages } from "../../i18next";
26 import { UserService, WebSocketService } from "../../services";
29 capitalizeFirstLetter,
54 import { HtmlTags } from "../common/html-tags";
55 import { Icon, Spinner } from "../common/icon";
56 import { ImageUploadForm } from "../common/image-upload-form";
57 import { LanguageSelect } from "../common/language-select";
58 import { ListingTypeSelect } from "../common/listing-type-select";
59 import { MarkdownTextArea } from "../common/markdown-textarea";
60 import { SortSelect } from "../common/sort-select";
61 import { CommunityLink } from "../community/community-link";
62 import { PersonListing } from "./person-listing";
66 Choices = require("choices.js");
69 interface SettingsState {
70 saveUserSettingsForm: SaveUserSettings;
71 changePasswordForm: ChangePassword;
72 deleteAccountForm: DeleteAccount;
73 personBlocks: PersonBlockView[];
74 blockPerson: Option<PersonViewSafe>;
75 communityBlocks: CommunityBlockView[];
76 blockCommunityId: number;
77 blockCommunity?: CommunityView;
80 saveUserSettingsLoading: boolean;
81 changePasswordLoading: boolean;
82 deleteAccountLoading: boolean;
83 deleteAccountShowConfirm: boolean;
84 siteRes: GetSiteResponse;
87 export class Settings extends Component<any, SettingsState> {
88 private isoData = setIsoData(this.context);
89 private blockPersonChoices: any;
90 private blockCommunityChoices: any;
91 private subscription: Subscription;
92 private emptyState: SettingsState = {
93 saveUserSettingsForm: new SaveUserSettings({
97 show_read_posts: None,
98 show_bot_accounts: None,
99 show_new_post_notifs: None,
100 default_sort_type: None,
101 default_listing_type: None,
103 interface_language: None,
104 discussion_languages: None,
110 matrix_user_id: None,
111 send_notifications_to_email: None,
115 changePasswordForm: new ChangePassword({
116 new_password: undefined,
117 new_password_verify: undefined,
118 old_password: undefined,
121 saveUserSettingsLoading: false,
122 changePasswordLoading: false,
123 deleteAccountLoading: false,
124 deleteAccountShowConfirm: false,
125 deleteAccountForm: new DeleteAccount({
133 currentTab: "settings",
134 siteRes: this.isoData.site_res,
138 constructor(props: any, context: any) {
139 super(props, context);
141 this.state = this.emptyState;
142 this.handleSortTypeChange = this.handleSortTypeChange.bind(this);
143 this.handleListingTypeChange = this.handleListingTypeChange.bind(this);
144 this.handleBioChange = this.handleBioChange.bind(this);
145 this.handleDiscussionLanguageChange =
146 this.handleDiscussionLanguageChange.bind(this);
148 this.handleAvatarUpload = this.handleAvatarUpload.bind(this);
149 this.handleAvatarRemove = this.handleAvatarRemove.bind(this);
151 this.handleBannerUpload = this.handleBannerUpload.bind(this);
152 this.handleBannerRemove = this.handleBannerRemove.bind(this);
154 this.parseMessage = this.parseMessage.bind(this);
155 this.subscription = wsSubscribe(this.parseMessage);
157 if (UserService.Instance.myUserInfo.isSome()) {
158 let mui = UserService.Instance.myUserInfo.unwrap();
159 let luv = mui.local_user_view;
162 personBlocks: mui.person_blocks,
163 communityBlocks: mui.community_blocks,
164 saveUserSettingsForm: {
165 ...this.state.saveUserSettingsForm,
166 show_nsfw: Some(luv.local_user.show_nsfw),
167 theme: Some(luv.local_user.theme ? luv.local_user.theme : "browser"),
168 default_sort_type: Some(luv.local_user.default_sort_type),
169 default_listing_type: Some(luv.local_user.default_listing_type),
170 interface_language: Some(luv.local_user.interface_language),
171 avatar: luv.person.avatar,
172 banner: luv.person.banner,
173 display_name: luv.person.display_name,
174 show_avatars: Some(luv.local_user.show_avatars),
175 bot_account: Some(luv.person.bot_account),
176 show_bot_accounts: Some(luv.local_user.show_bot_accounts),
177 show_scores: Some(luv.local_user.show_scores),
178 show_read_posts: Some(luv.local_user.show_read_posts),
179 show_new_post_notifs: Some(luv.local_user.show_new_post_notifs),
180 email: luv.local_user.email,
182 send_notifications_to_email: Some(
183 luv.local_user.send_notifications_to_email
185 matrix_user_id: luv.person.matrix_user_id,
191 async componentDidMount() {
193 this.setState({ themeList: await fetchThemeList() });
196 componentWillUnmount() {
197 this.subscription.unsubscribe();
200 get documentTitle(): string {
201 return i18n.t("settings");
206 <div className="container">
209 title={this.documentTitle}
210 path={this.context.router.route.match.url}
211 description={Some(this.documentTitle)}
212 image={this.state.saveUserSettingsForm.avatar}
214 <ul className="nav nav-tabs mb-2">
215 <li className="nav-item">
217 className={`nav-link btn ${
218 this.state.currentTab == "settings" && "active"
221 { ctx: this, tab: "settings" },
228 <li className="nav-item">
230 className={`nav-link btn ${
231 this.state.currentTab == "blocks" && "active"
234 { ctx: this, tab: "blocks" },
242 {this.state.currentTab == "settings" && this.userSettings()}
243 {this.state.currentTab == "blocks" && this.blockCards()}
251 <div className="row">
252 <div className="col-12 col-md-6">
253 <div className="card border-secondary mb-3">
254 <div className="card-body">{this.saveUserSettingsHtmlForm()}</div>
257 <div className="col-12 col-md-6">
258 <div className="card border-secondary mb-3">
259 <div className="card-body">{this.changePasswordHtmlForm()}</div>
268 <div className="row">
269 <div className="col-12 col-md-6">
270 <div className="card border-secondary mb-3">
271 <div className="card-body">{this.blockUserCard()}</div>
274 <div className="col-12 col-md-6">
275 <div className="card border-secondary mb-3">
276 <div className="card-body">{this.blockCommunityCard()}</div>
283 changePasswordHtmlForm() {
286 <h5>{i18n.t("change_password")}</h5>
287 <form onSubmit={linkEvent(this, this.handleChangePasswordSubmit)}>
288 <div className="form-group row">
289 <label className="col-sm-5 col-form-label" htmlFor="user-password">
290 {i18n.t("new_password")}
292 <div className="col-sm-7">
296 className="form-control"
297 value={this.state.changePasswordForm.new_password}
298 autoComplete="new-password"
300 onInput={linkEvent(this, this.handleNewPasswordChange)}
304 <div className="form-group row">
306 className="col-sm-5 col-form-label"
307 htmlFor="user-verify-password"
309 {i18n.t("verify_password")}
311 <div className="col-sm-7">
314 id="user-verify-password"
315 className="form-control"
316 value={this.state.changePasswordForm.new_password_verify}
317 autoComplete="new-password"
319 onInput={linkEvent(this, this.handleNewPasswordVerifyChange)}
323 <div className="form-group row">
325 className="col-sm-5 col-form-label"
326 htmlFor="user-old-password"
328 {i18n.t("old_password")}
330 <div className="col-sm-7">
333 id="user-old-password"
334 className="form-control"
335 value={this.state.changePasswordForm.old_password}
336 autoComplete="new-password"
338 onInput={linkEvent(this, this.handleOldPasswordChange)}
342 <div className="form-group">
343 <button type="submit" className="btn btn-block btn-secondary mr-4">
344 {this.state.changePasswordLoading ? (
347 capitalizeFirstLetter(i18n.t("save"))
359 {this.blockUserForm()}
360 {this.blockedUsersList()}
368 <h5>{i18n.t("blocked_users")}</h5>
369 <ul className="list-unstyled mb-0">
370 {this.state.personBlocks.map(pb => (
371 <li key={pb.target.id}>
373 <PersonListing person={pb.target} />
375 className="btn btn-sm"
377 { ctx: this, recipientId: pb.target.id },
378 this.handleUnblockPerson
380 data-tippy-content={i18n.t("unblock_user")}
382 <Icon icon="x" classes="icon-inline" />
394 <div className="form-group row">
396 className="col-md-4 col-form-label"
397 htmlFor="block-person-filter"
399 {i18n.t("block_user")}
401 <div className="col-md-8">
403 className="form-control"
404 id="block-person-filter"
405 value={this.state.blockPerson.map(p => p.person.id).unwrapOr(0)}
407 <option value="0">—</option>
408 {this.state.blockPerson.match({
409 some: personView => (
410 <option value={personView.person.id}>
411 {personSelectName(personView)}
422 blockCommunityCard() {
425 {this.blockCommunityForm()}
426 {this.blockedCommunitiesList()}
431 blockedCommunitiesList() {
434 <h5>{i18n.t("blocked_communities")}</h5>
435 <ul className="list-unstyled mb-0">
436 {this.state.communityBlocks.map(cb => (
437 <li key={cb.community.id}>
439 <CommunityLink community={cb.community} />
441 className="btn btn-sm"
443 { ctx: this, communityId: cb.community.id },
444 this.handleUnblockCommunity
446 data-tippy-content={i18n.t("unblock_community")}
448 <Icon icon="x" classes="icon-inline" />
458 blockCommunityForm() {
460 <div className="form-group row">
462 className="col-md-4 col-form-label"
463 htmlFor="block-community-filter"
465 {i18n.t("block_community")}
467 <div className="col-md-8">
469 className="form-control"
470 id="block-community-filter"
471 value={this.state.blockCommunityId}
473 <option value="0">—</option>
474 {this.state.blockCommunity && (
475 <option value={this.state.blockCommunity.community.id}>
476 {communitySelectName(this.state.blockCommunity)}
485 saveUserSettingsHtmlForm() {
486 let selectedLangs = this.state.saveUserSettingsForm.discussion_languages;
490 <h5>{i18n.t("settings")}</h5>
491 <form onSubmit={linkEvent(this, this.handleSaveSettingsSubmit)}>
492 <div className="form-group row">
493 <label className="col-sm-5 col-form-label" htmlFor="display-name">
494 {i18n.t("display_name")}
496 <div className="col-sm-7">
500 className="form-control"
501 placeholder={i18n.t("optional")}
503 this.state.saveUserSettingsForm.display_name
505 onInput={linkEvent(this, this.handleDisplayNameChange)}
506 pattern="^(?!@)(.+)$"
511 <div className="form-group row">
512 <label className="col-sm-3 col-form-label" htmlFor="user-bio">
515 <div className="col-sm-9">
517 initialContent={this.state.saveUserSettingsForm.bio}
518 initialLanguageId={None}
519 onContentChange={this.handleBioChange}
520 maxLength={Some(300)}
523 hideNavigationWarnings
524 allLanguages={this.state.siteRes.all_languages}
528 <div className="form-group row">
529 <label className="col-sm-3 col-form-label" htmlFor="user-email">
532 <div className="col-sm-9">
536 className="form-control"
537 placeholder={i18n.t("optional")}
538 value={toUndefined(this.state.saveUserSettingsForm.email)}
539 onInput={linkEvent(this, this.handleEmailChange)}
544 <div className="form-group row">
545 <label className="col-sm-5 col-form-label" htmlFor="matrix-user-id">
546 <a href={elementUrl} rel={relTags}>
547 {i18n.t("matrix_user_id")}
550 <div className="col-sm-7">
554 className="form-control"
555 placeholder="@user:example.com"
557 this.state.saveUserSettingsForm.matrix_user_id
559 onInput={linkEvent(this, this.handleMatrixUserIdChange)}
560 pattern="^@[A-Za-z0-9._=-]+:[A-Za-z0-9.-]+\.[A-Za-z]{2,}$"
564 <div className="form-group row">
565 <label className="col-sm-3">{i18n.t("avatar")}</label>
566 <div className="col-sm-9">
568 uploadTitle={i18n.t("upload_avatar")}
569 imageSrc={this.state.saveUserSettingsForm.avatar}
570 onUpload={this.handleAvatarUpload}
571 onRemove={this.handleAvatarRemove}
576 <div className="form-group row">
577 <label className="col-sm-3">{i18n.t("banner")}</label>
578 <div className="col-sm-9">
580 uploadTitle={i18n.t("upload_banner")}
581 imageSrc={this.state.saveUserSettingsForm.banner}
582 onUpload={this.handleBannerUpload}
583 onRemove={this.handleBannerRemove}
587 <div className="form-group row">
588 <label className="col-sm-3" htmlFor="user-language">
589 {i18n.t("interface_language")}
591 <div className="col-sm-9">
595 this.state.saveUserSettingsForm.interface_language
597 onChange={linkEvent(this, this.handleInterfaceLangChange)}
598 className="custom-select w-auto"
600 <option disabled aria-hidden="true">
601 {i18n.t("interface_language")}
603 <option value="browser">{i18n.t("browser_default")}</option>
604 <option disabled aria-hidden="true">
608 .sort((a, b) => a.code.localeCompare(b.code))
610 <option key={lang.code} value={lang.code}>
618 allLanguages={this.state.siteRes.all_languages}
619 selectedLanguageIds={selectedLangs}
621 onChange={this.handleDiscussionLanguageChange}
623 <div className="form-group row">
624 <label className="col-sm-3" htmlFor="user-theme">
627 <div className="col-sm-9">
630 value={toUndefined(this.state.saveUserSettingsForm.theme)}
631 onChange={linkEvent(this, this.handleThemeChange)}
632 className="custom-select w-auto"
634 <option disabled aria-hidden="true">
637 <option value="browser">{i18n.t("browser_default")}</option>
638 {this.state.themeList.map(theme => (
639 <option key={theme} value={theme}>
646 <form className="form-group row">
647 <label className="col-sm-3">{i18n.t("type")}</label>
648 <div className="col-sm-9">
651 Object.values(ListingType)[
652 this.state.saveUserSettingsForm.default_listing_type.unwrapOr(
657 showLocal={showLocal(this.isoData)}
659 onChange={this.handleListingTypeChange}
663 <form className="form-group row">
664 <label className="col-sm-3">{i18n.t("sort_type")}</label>
665 <div className="col-sm-9">
668 Object.values(SortType)[
669 this.state.saveUserSettingsForm.default_sort_type.unwrapOr(
674 onChange={this.handleSortTypeChange}
678 {enableNsfw(this.state.siteRes) && (
679 <div className="form-group">
680 <div className="form-check">
682 className="form-check-input"
685 checked={toUndefined(
686 this.state.saveUserSettingsForm.show_nsfw
688 onChange={linkEvent(this, this.handleShowNsfwChange)}
690 <label className="form-check-label" htmlFor="user-show-nsfw">
691 {i18n.t("show_nsfw")}
696 <div className="form-group">
697 <div className="form-check">
699 className="form-check-input"
700 id="user-show-scores"
702 checked={toUndefined(
703 this.state.saveUserSettingsForm.show_scores
705 onChange={linkEvent(this, this.handleShowScoresChange)}
707 <label className="form-check-label" htmlFor="user-show-scores">
708 {i18n.t("show_scores")}
712 <div className="form-group">
713 <div className="form-check">
715 className="form-check-input"
716 id="user-show-avatars"
718 checked={toUndefined(
719 this.state.saveUserSettingsForm.show_avatars
721 onChange={linkEvent(this, this.handleShowAvatarsChange)}
723 <label className="form-check-label" htmlFor="user-show-avatars">
724 {i18n.t("show_avatars")}
728 <div className="form-group">
729 <div className="form-check">
731 className="form-check-input"
732 id="user-bot-account"
734 checked={toUndefined(
735 this.state.saveUserSettingsForm.bot_account
737 onChange={linkEvent(this, this.handleBotAccount)}
739 <label className="form-check-label" htmlFor="user-bot-account">
740 {i18n.t("bot_account")}
744 <div className="form-group">
745 <div className="form-check">
747 className="form-check-input"
748 id="user-show-bot-accounts"
750 checked={toUndefined(
751 this.state.saveUserSettingsForm.show_bot_accounts
753 onChange={linkEvent(this, this.handleShowBotAccounts)}
756 className="form-check-label"
757 htmlFor="user-show-bot-accounts"
759 {i18n.t("show_bot_accounts")}
763 <div className="form-group">
764 <div className="form-check">
766 className="form-check-input"
767 id="user-show-read-posts"
769 checked={toUndefined(
770 this.state.saveUserSettingsForm.show_read_posts
772 onChange={linkEvent(this, this.handleReadPosts)}
775 className="form-check-label"
776 htmlFor="user-show-read-posts"
778 {i18n.t("show_read_posts")}
782 <div className="form-group">
783 <div className="form-check">
785 className="form-check-input"
786 id="user-show-new-post-notifs"
788 checked={toUndefined(
789 this.state.saveUserSettingsForm.show_new_post_notifs
791 onChange={linkEvent(this, this.handleShowNewPostNotifs)}
794 className="form-check-label"
795 htmlFor="user-show-new-post-notifs"
797 {i18n.t("show_new_post_notifs")}
801 <div className="form-group">
802 <div className="form-check">
804 className="form-check-input"
805 id="user-send-notifications-to-email"
807 disabled={!this.state.saveUserSettingsForm.email}
808 checked={toUndefined(
809 this.state.saveUserSettingsForm.send_notifications_to_email
813 this.handleSendNotificationsToEmailChange
817 className="form-check-label"
818 htmlFor="user-send-notifications-to-email"
820 {i18n.t("send_notifications_to_email")}
824 <div className="form-group">
825 <button type="submit" className="btn btn-block btn-secondary mr-4">
826 {this.state.saveUserSettingsLoading ? (
829 capitalizeFirstLetter(i18n.t("save"))
834 <div className="form-group">
836 className="btn btn-block btn-danger"
839 this.handleDeleteAccountShowConfirmToggle
842 {i18n.t("delete_account")}
844 {this.state.deleteAccountShowConfirm && (
846 <div className="my-2 alert alert-danger" role="alert">
847 {i18n.t("delete_account_confirm")}
851 value={this.state.deleteAccountForm.password}
852 autoComplete="new-password"
856 this.handleDeleteAccountPasswordChange
858 className="form-control my-2"
861 className="btn btn-danger mr-4"
862 disabled={!this.state.deleteAccountForm.password}
863 onClick={linkEvent(this, this.handleDeleteAccount)}
865 {this.state.deleteAccountLoading ? (
868 capitalizeFirstLetter(i18n.t("delete"))
872 className="btn btn-secondary"
875 this.handleDeleteAccountShowConfirmToggle
888 setupBlockPersonChoices() {
890 let selectId: any = document.getElementById("block-person-filter");
892 this.blockPersonChoices = new Choices(selectId, choicesConfig);
893 this.blockPersonChoices.passedElement.element.addEventListener(
896 this.handleBlockPerson(Number(e.detail.choice.value));
900 this.blockPersonChoices.passedElement.element.addEventListener(
902 debounce(async (e: any) => {
904 let persons = (await fetchUsers(e.detail.value)).users;
905 let choices = persons.map(pvs => personToChoice(pvs));
906 this.blockPersonChoices.setChoices(
922 setupBlockCommunityChoices() {
924 let selectId: any = document.getElementById("block-community-filter");
926 this.blockCommunityChoices = new Choices(selectId, choicesConfig);
927 this.blockCommunityChoices.passedElement.element.addEventListener(
930 this.handleBlockCommunity(Number(e.detail.choice.value));
934 this.blockCommunityChoices.passedElement.element.addEventListener(
936 debounce(async (e: any) => {
938 let communities = (await fetchCommunities(e.detail.value))
940 let choices = communities.map(cv => communityToChoice(cv));
941 this.blockCommunityChoices.setChoices(
957 handleBlockPerson(personId: number) {
959 let blockUserForm = new BlockPerson({
962 auth: auth().unwrap(),
964 WebSocketService.Instance.send(wsClient.blockPerson(blockUserForm));
968 handleUnblockPerson(i: { ctx: Settings; recipientId: number }) {
969 let blockUserForm = new BlockPerson({
970 person_id: i.recipientId,
972 auth: auth().unwrap(),
974 WebSocketService.Instance.send(wsClient.blockPerson(blockUserForm));
977 handleBlockCommunity(community_id: number) {
978 if (community_id != 0) {
979 let blockCommunityForm = new BlockCommunity({
982 auth: auth().unwrap(),
984 WebSocketService.Instance.send(
985 wsClient.blockCommunity(blockCommunityForm)
990 handleUnblockCommunity(i: { ctx: Settings; communityId: number }) {
991 let blockCommunityForm = new BlockCommunity({
992 community_id: i.communityId,
994 auth: auth().unwrap(),
996 WebSocketService.Instance.send(wsClient.blockCommunity(blockCommunityForm));
999 handleShowNsfwChange(i: Settings, event: any) {
1000 i.state.saveUserSettingsForm.show_nsfw = Some(event.target.checked);
1001 i.setState(i.state);
1004 handleShowAvatarsChange(i: Settings, event: any) {
1005 i.state.saveUserSettingsForm.show_avatars = Some(event.target.checked);
1006 UserService.Instance.myUserInfo.match({
1008 (mui.local_user_view.local_user.show_avatars = event.target.checked),
1011 i.setState(i.state);
1014 handleBotAccount(i: Settings, event: any) {
1015 i.state.saveUserSettingsForm.bot_account = Some(event.target.checked);
1016 i.setState(i.state);
1019 handleShowBotAccounts(i: Settings, event: any) {
1020 i.state.saveUserSettingsForm.show_bot_accounts = Some(event.target.checked);
1021 i.setState(i.state);
1024 handleReadPosts(i: Settings, event: any) {
1025 i.state.saveUserSettingsForm.show_read_posts = Some(event.target.checked);
1026 i.setState(i.state);
1029 handleShowNewPostNotifs(i: Settings, event: any) {
1030 i.state.saveUserSettingsForm.show_new_post_notifs = Some(
1031 event.target.checked
1033 i.setState(i.state);
1036 handleShowScoresChange(i: Settings, event: any) {
1037 i.state.saveUserSettingsForm.show_scores = Some(event.target.checked);
1038 UserService.Instance.myUserInfo.match({
1040 (mui.local_user_view.local_user.show_scores = event.target.checked),
1043 i.setState(i.state);
1046 handleSendNotificationsToEmailChange(i: Settings, event: any) {
1047 i.state.saveUserSettingsForm.send_notifications_to_email = Some(
1048 event.target.checked
1050 i.setState(i.state);
1053 handleThemeChange(i: Settings, event: any) {
1054 i.state.saveUserSettingsForm.theme = Some(event.target.value);
1055 setTheme(event.target.value, true);
1056 i.setState(i.state);
1059 handleInterfaceLangChange(i: Settings, event: any) {
1060 i.state.saveUserSettingsForm.interface_language = Some(event.target.value);
1061 i18n.changeLanguage(
1062 getLanguages(i.state.saveUserSettingsForm.interface_language.unwrap())[0]
1064 i.setState(i.state);
1067 handleDiscussionLanguageChange(val: number[]) {
1069 s => ((s.saveUserSettingsForm.discussion_languages = Some(val)), s)
1073 handleSortTypeChange(val: SortType) {
1076 (s.saveUserSettingsForm.default_sort_type = Some(
1077 Object.keys(SortType).indexOf(val)
1084 handleListingTypeChange(val: ListingType) {
1087 (s.saveUserSettingsForm.default_listing_type = Some(
1088 Object.keys(ListingType).indexOf(val)
1095 handleEmailChange(i: Settings, event: any) {
1096 i.state.saveUserSettingsForm.email = Some(event.target.value);
1097 i.setState(i.state);
1100 handleBioChange(val: string) {
1101 this.setState(s => ((s.saveUserSettingsForm.bio = Some(val)), s));
1104 handleAvatarUpload(url: string) {
1105 this.setState(s => ((s.saveUserSettingsForm.avatar = Some(url)), s));
1108 handleAvatarRemove() {
1109 this.setState(s => ((s.saveUserSettingsForm.avatar = Some("")), s));
1112 handleBannerUpload(url: string) {
1113 this.setState(s => ((s.saveUserSettingsForm.banner = Some(url)), s));
1116 handleBannerRemove() {
1117 this.setState(s => ((s.saveUserSettingsForm.banner = Some("")), s));
1120 handleDisplayNameChange(i: Settings, event: any) {
1121 i.state.saveUserSettingsForm.display_name = Some(event.target.value);
1122 i.setState(i.state);
1125 handleMatrixUserIdChange(i: Settings, event: any) {
1126 i.state.saveUserSettingsForm.matrix_user_id = Some(event.target.value);
1127 i.setState(i.state);
1130 handleNewPasswordChange(i: Settings, event: any) {
1131 i.state.changePasswordForm.new_password = event.target.value;
1132 if (i.state.changePasswordForm.new_password == "") {
1133 i.state.changePasswordForm.new_password = undefined;
1135 i.setState(i.state);
1138 handleNewPasswordVerifyChange(i: Settings, event: any) {
1139 i.state.changePasswordForm.new_password_verify = event.target.value;
1140 if (i.state.changePasswordForm.new_password_verify == "") {
1141 i.state.changePasswordForm.new_password_verify = undefined;
1143 i.setState(i.state);
1146 handleOldPasswordChange(i: Settings, event: any) {
1147 i.state.changePasswordForm.old_password = event.target.value;
1148 if (i.state.changePasswordForm.old_password == "") {
1149 i.state.changePasswordForm.old_password = undefined;
1151 i.setState(i.state);
1154 handleSaveSettingsSubmit(i: Settings, event: any) {
1155 event.preventDefault();
1156 i.setState({ saveUserSettingsLoading: true });
1157 i.setState(s => ((s.saveUserSettingsForm.auth = auth().unwrap()), s));
1159 let form = new SaveUserSettings({ ...i.state.saveUserSettingsForm });
1160 WebSocketService.Instance.send(wsClient.saveUserSettings(form));
1163 handleChangePasswordSubmit(i: Settings, event: any) {
1164 event.preventDefault();
1165 i.setState({ changePasswordLoading: true });
1166 i.setState(s => ((s.changePasswordForm.auth = auth().unwrap()), s));
1168 let form = new ChangePassword({ ...i.state.changePasswordForm });
1170 WebSocketService.Instance.send(wsClient.changePassword(form));
1173 handleDeleteAccountShowConfirmToggle(i: Settings, event: any) {
1174 event.preventDefault();
1175 i.setState({ deleteAccountShowConfirm: !i.state.deleteAccountShowConfirm });
1178 handleDeleteAccountPasswordChange(i: Settings, event: any) {
1179 i.state.deleteAccountForm.password = event.target.value;
1180 i.setState(i.state);
1183 handleDeleteAccount(i: Settings, event: any) {
1184 event.preventDefault();
1185 i.setState({ deleteAccountLoading: true });
1186 i.setState(s => ((s.deleteAccountForm.auth = auth().unwrap()), s));
1188 let form = new DeleteAccount({ ...i.state.deleteAccountForm });
1190 WebSocketService.Instance.send(wsClient.deleteAccount(form));
1193 handleSwitchTab(i: { ctx: Settings; tab: string }) {
1194 i.ctx.setState({ currentTab: i.tab });
1196 if (i.ctx.state.currentTab == "blocks") {
1197 i.ctx.setupBlockPersonChoices();
1198 i.ctx.setupBlockCommunityChoices();
1202 parseMessage(msg: any) {
1203 let op = wsUserOp(msg);
1207 saveUserSettingsLoading: false,
1208 changePasswordLoading: false,
1209 deleteAccountLoading: false,
1211 toast(i18n.t(msg.error), "danger");
1213 } else if (op == UserOperation.SaveUserSettings) {
1214 let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
1215 UserService.Instance.login(data);
1216 this.setState({ saveUserSettingsLoading: false });
1217 toast(i18n.t("saved"));
1218 window.scrollTo(0, 0);
1219 } else if (op == UserOperation.ChangePassword) {
1220 let data = wsJsonToRes<LoginResponse>(msg, LoginResponse);
1221 UserService.Instance.login(data);
1222 this.setState({ changePasswordLoading: false });
1223 window.scrollTo(0, 0);
1224 toast(i18n.t("password_changed"));
1225 } else if (op == UserOperation.DeleteAccount) {
1227 deleteAccountLoading: false,
1228 deleteAccountShowConfirm: false,
1230 UserService.Instance.logout();
1231 window.location.href = "/";
1232 } else if (op == UserOperation.BlockPerson) {
1233 let data = wsJsonToRes<BlockPersonResponse>(msg, BlockPersonResponse);
1234 updatePersonBlock(data).match({
1235 some: blocks => this.setState({ personBlocks: blocks }),
1238 } else if (op == UserOperation.BlockCommunity) {
1239 let data = wsJsonToRes<BlockCommunityResponse>(
1241 BlockCommunityResponse
1243 updateCommunityBlock(data).match({
1244 some: blocks => this.setState({ communityBlocks: blocks }),