1 import { Component, linkEvent } from "inferno";
2 import ISO6391 from "iso-639-1";
5 BlockCommunityResponse,
20 } from "lemmy-js-client";
21 import { Subscription } from "rxjs";
22 import { i18n } from "../../i18next";
23 import { UserService, WebSocketService } from "../../services";
26 capitalizeFirstLetter,
52 import { HtmlTags } from "../common/html-tags";
53 import { Icon, Spinner } from "../common/icon";
54 import { ImageUploadForm } from "../common/image-upload-form";
55 import { ListingTypeSelect } from "../common/listing-type-select";
56 import { MarkdownTextArea } from "../common/markdown-textarea";
57 import { SortSelect } from "../common/sort-select";
58 import { CommunityLink } from "../community/community-link";
59 import { PersonListing } from "./person-listing";
63 Choices = require("choices.js");
66 interface SettingsState {
67 saveUserSettingsForm: SaveUserSettings;
68 changePasswordForm: ChangePassword;
69 saveUserSettingsLoading: boolean;
70 changePasswordLoading: boolean;
71 deleteAccountLoading: boolean;
72 deleteAccountShowConfirm: boolean;
73 deleteAccountForm: DeleteAccount;
74 personBlocks: PersonBlockView[];
75 blockPersonId: number;
76 blockPerson?: PersonViewSafe;
77 communityBlocks: CommunityBlockView[];
78 blockCommunityId: number;
79 blockCommunity?: CommunityView;
81 siteRes: GetSiteResponse;
84 export class Settings extends Component<any, SettingsState> {
85 private isoData = setIsoData(this.context);
86 private blockPersonChoices: any;
87 private blockCommunityChoices: any;
88 private subscription: Subscription;
89 private emptyState: SettingsState = {
90 saveUserSettingsForm: {
91 auth: authField(false),
95 new_password_verify: null,
97 auth: authField(false),
99 saveUserSettingsLoading: null,
100 changePasswordLoading: false,
101 deleteAccountLoading: null,
102 deleteAccountShowConfirm: false,
105 auth: authField(false),
111 currentTab: "settings",
112 siteRes: this.isoData.site_res,
115 constructor(props: any, context: any) {
116 super(props, context);
118 this.state = this.emptyState;
119 this.handleSortTypeChange = this.handleSortTypeChange.bind(this);
120 this.handleListingTypeChange = this.handleListingTypeChange.bind(this);
121 this.handleBioChange = this.handleBioChange.bind(this);
123 this.handleAvatarUpload = this.handleAvatarUpload.bind(this);
124 this.handleAvatarRemove = this.handleAvatarRemove.bind(this);
126 this.handleBannerUpload = this.handleBannerUpload.bind(this);
127 this.handleBannerRemove = this.handleBannerRemove.bind(this);
129 this.parseMessage = this.parseMessage.bind(this);
130 this.subscription = wsSubscribe(this.parseMessage);
137 componentWillUnmount() {
138 this.subscription.unsubscribe();
141 get documentTitle(): string {
142 return i18n.t("settings");
147 <div class="container">
150 title={this.documentTitle}
151 path={this.context.router.route.match.url}
152 description={this.documentTitle}
153 image={this.state.saveUserSettingsForm.avatar}
155 <ul class="nav nav-tabs mb-2">
156 <li class="nav-item">
158 class={`nav-link btn ${
159 this.state.currentTab == "settings" && "active"
162 { ctx: this, tab: "settings" },
169 <li class="nav-item">
171 class={`nav-link btn ${
172 this.state.currentTab == "blocks" && "active"
175 { ctx: this, tab: "blocks" },
183 {this.state.currentTab == "settings" && this.userSettings()}
184 {this.state.currentTab == "blocks" && this.blockCards()}
193 <div class="col-12 col-md-6">
194 <div class="card border-secondary mb-3">
195 <div class="card-body">{this.saveUserSettingsHtmlForm()}</div>
198 <div class="col-12 col-md-6">
199 <div class="card border-secondary mb-3">
200 <div class="card-body">{this.changePasswordHtmlForm()}</div>
210 <div class="col-12 col-md-6">
211 <div class="card border-secondary mb-3">
212 <div class="card-body">{this.blockUserCard()}</div>
215 <div class="col-12 col-md-6">
216 <div class="card border-secondary mb-3">
217 <div class="card-body">{this.blockCommunityCard()}</div>
224 changePasswordHtmlForm() {
227 <h5>{i18n.t("change_password")}</h5>
228 <form onSubmit={linkEvent(this, this.handleChangePasswordSubmit)}>
229 <div class="form-group row">
230 <label class="col-sm-5 col-form-label" htmlFor="user-password">
231 {i18n.t("new_password")}
233 <div class="col-sm-7">
238 value={this.state.changePasswordForm.new_password}
239 autoComplete="new-password"
241 onInput={linkEvent(this, this.handleNewPasswordChange)}
245 <div class="form-group row">
247 class="col-sm-5 col-form-label"
248 htmlFor="user-verify-password"
250 {i18n.t("verify_password")}
252 <div class="col-sm-7">
255 id="user-verify-password"
257 value={this.state.changePasswordForm.new_password_verify}
258 autoComplete="new-password"
260 onInput={linkEvent(this, this.handleNewPasswordVerifyChange)}
264 <div class="form-group row">
265 <label class="col-sm-5 col-form-label" htmlFor="user-old-password">
266 {i18n.t("old_password")}
268 <div class="col-sm-7">
271 id="user-old-password"
273 value={this.state.changePasswordForm.old_password}
274 autoComplete="new-password"
276 onInput={linkEvent(this, this.handleOldPasswordChange)}
280 <div class="form-group">
281 <button type="submit" class="btn btn-block btn-secondary mr-4">
282 {this.state.changePasswordLoading ? (
285 capitalizeFirstLetter(i18n.t("save"))
297 {this.blockUserForm()}
298 {this.blockedUsersList()}
306 <h5>{i18n.t("blocked_users")}</h5>
307 <ul class="list-unstyled mb-0">
308 {this.state.personBlocks.map(pb => (
311 <PersonListing person={pb.target} />
313 className="btn btn-sm"
315 { ctx: this, recipientId: pb.target.id },
316 this.handleUnblockPerson
318 data-tippy-content={i18n.t("unblock_user")}
320 <Icon icon="x" classes="icon-inline" />
332 <div class="form-group row">
333 <label class="col-md-4 col-form-label" htmlFor="block-person-filter">
334 {i18n.t("block_user")}
336 <div class="col-md-8">
339 id="block-person-filter"
340 value={this.state.blockPersonId}
342 <option value="0">—</option>
343 {this.state.blockPerson && (
344 <option value={this.state.blockPerson.person.id}>
345 {personSelectName(this.state.blockPerson)}
354 blockCommunityCard() {
357 {this.blockCommunityForm()}
358 {this.blockedCommunitiesList()}
363 blockedCommunitiesList() {
366 <h5>{i18n.t("blocked_communities")}</h5>
367 <ul class="list-unstyled mb-0">
368 {this.state.communityBlocks.map(cb => (
371 <CommunityLink community={cb.community} />
373 className="btn btn-sm"
375 { ctx: this, communityId: cb.community.id },
376 this.handleUnblockCommunity
378 data-tippy-content={i18n.t("unblock_community")}
380 <Icon icon="x" classes="icon-inline" />
390 blockCommunityForm() {
392 <div class="form-group row">
393 <label class="col-md-4 col-form-label" htmlFor="block-community-filter">
394 {i18n.t("block_community")}
396 <div class="col-md-8">
399 id="block-community-filter"
400 value={this.state.blockCommunityId}
402 <option value="0">—</option>
403 {this.state.blockCommunity && (
404 <option value={this.state.blockCommunity.community.id}>
405 {communitySelectName(this.state.blockCommunity)}
414 saveUserSettingsHtmlForm() {
417 <h5>{i18n.t("settings")}</h5>
418 <form onSubmit={linkEvent(this, this.handleSaveSettingsSubmit)}>
419 <div class="form-group row">
420 <label class="col-sm-5 col-form-label" htmlFor="display-name">
421 {i18n.t("display_name")}
423 <div class="col-sm-7">
428 placeholder={i18n.t("optional")}
429 value={this.state.saveUserSettingsForm.display_name}
430 onInput={linkEvent(this, this.handleDisplayNameChange)}
431 pattern="^(?!@)(.+)$"
436 <div class="form-group row">
437 <label class="col-sm-3 col-form-label" htmlFor="user-bio">
440 <div class="col-sm-9">
442 initialContent={this.state.saveUserSettingsForm.bio}
443 onContentChange={this.handleBioChange}
445 hideNavigationWarnings
449 <div class="form-group row">
450 <label class="col-sm-3 col-form-label" htmlFor="user-email">
453 <div class="col-sm-9">
458 placeholder={i18n.t("optional")}
459 value={this.state.saveUserSettingsForm.email}
460 onInput={linkEvent(this, this.handleEmailChange)}
465 <div class="form-group row">
466 <label class="col-sm-5 col-form-label" htmlFor="matrix-user-id">
467 <a href={elementUrl} rel="noopener">
468 {i18n.t("matrix_user_id")}
471 <div class="col-sm-7">
476 placeholder="@user:example.com"
477 value={this.state.saveUserSettingsForm.matrix_user_id}
478 onInput={linkEvent(this, this.handleMatrixUserIdChange)}
479 pattern="^@[A-Za-z0-9._=-]+:[A-Za-z0-9.-]+\.[A-Za-z]{2,}$"
483 <div class="form-group row">
484 <label class="col-sm-3">{i18n.t("avatar")}</label>
485 <div class="col-sm-9">
487 uploadTitle={i18n.t("upload_avatar")}
488 imageSrc={this.state.saveUserSettingsForm.avatar}
489 onUpload={this.handleAvatarUpload}
490 onRemove={this.handleAvatarRemove}
495 <div class="form-group row">
496 <label class="col-sm-3">{i18n.t("banner")}</label>
497 <div class="col-sm-9">
499 uploadTitle={i18n.t("upload_banner")}
500 imageSrc={this.state.saveUserSettingsForm.banner}
501 onUpload={this.handleBannerUpload}
502 onRemove={this.handleBannerRemove}
506 <div class="form-group row">
507 <label class="col-sm-3" htmlFor="user-language">
510 <div class="col-sm-9">
513 value={this.state.saveUserSettingsForm.lang}
514 onChange={linkEvent(this, this.handleLangChange)}
515 class="custom-select w-auto"
517 <option disabled aria-hidden="true">
520 <option value="browser">{i18n.t("browser_default")}</option>
521 <option disabled aria-hidden="true">
524 {languages.sort().map(lang => (
525 <option value={lang.code}>
526 {ISO6391.getNativeName(lang.code) || lang.code}
532 <div class="form-group row">
533 <label class="col-sm-3" htmlFor="user-theme">
536 <div class="col-sm-9">
539 value={this.state.saveUserSettingsForm.theme}
540 onChange={linkEvent(this, this.handleThemeChange)}
541 class="custom-select w-auto"
543 <option disabled aria-hidden="true">
546 <option value="browser">{i18n.t("browser_default")}</option>
547 {themes.map(theme => (
548 <option value={theme}>{theme}</option>
553 <form className="form-group row">
554 <label class="col-sm-3">{i18n.t("type")}</label>
555 <div class="col-sm-9">
558 Object.values(ListingType)[
559 this.state.saveUserSettingsForm.default_listing_type
562 showLocal={showLocal(this.isoData)}
563 onChange={this.handleListingTypeChange}
567 <form className="form-group row">
568 <label class="col-sm-3">{i18n.t("sort_type")}</label>
569 <div class="col-sm-9">
572 Object.values(SortType)[
573 this.state.saveUserSettingsForm.default_sort_type
576 onChange={this.handleSortTypeChange}
580 {this.state.siteRes.site_view.site.enable_nsfw && (
581 <div class="form-group">
582 <div class="form-check">
584 class="form-check-input"
587 checked={this.state.saveUserSettingsForm.show_nsfw}
588 onChange={linkEvent(this, this.handleShowNsfwChange)}
590 <label class="form-check-label" htmlFor="user-show-nsfw">
591 {i18n.t("show_nsfw")}
596 <div class="form-group">
597 <div class="form-check">
599 class="form-check-input"
600 id="user-show-scores"
602 checked={this.state.saveUserSettingsForm.show_scores}
603 onChange={linkEvent(this, this.handleShowScoresChange)}
605 <label class="form-check-label" htmlFor="user-show-scores">
606 {i18n.t("show_scores")}
610 <div class="form-group">
611 <div class="form-check">
613 class="form-check-input"
614 id="user-show-avatars"
616 checked={this.state.saveUserSettingsForm.show_avatars}
617 onChange={linkEvent(this, this.handleShowAvatarsChange)}
619 <label class="form-check-label" htmlFor="user-show-avatars">
620 {i18n.t("show_avatars")}
624 <div class="form-group">
625 <div class="form-check">
627 class="form-check-input"
628 id="user-bot-account"
630 checked={this.state.saveUserSettingsForm.bot_account}
631 onChange={linkEvent(this, this.handleBotAccount)}
633 <label class="form-check-label" htmlFor="user-bot-account">
634 {i18n.t("bot_account")}
638 <div class="form-group">
639 <div class="form-check">
641 class="form-check-input"
642 id="user-show-bot-accounts"
644 checked={this.state.saveUserSettingsForm.show_bot_accounts}
645 onChange={linkEvent(this, this.handleShowBotAccounts)}
647 <label class="form-check-label" htmlFor="user-show-bot-accounts">
648 {i18n.t("show_bot_accounts")}
652 <div class="form-group">
653 <div class="form-check">
655 class="form-check-input"
656 id="user-show-read-posts"
658 checked={this.state.saveUserSettingsForm.show_read_posts}
659 onChange={linkEvent(this, this.handleReadPosts)}
661 <label class="form-check-label" htmlFor="user-show-read-posts">
662 {i18n.t("show_read_posts")}
666 <div class="form-group">
667 <div class="form-check">
669 class="form-check-input"
670 id="user-show-new-post-notifs"
672 checked={this.state.saveUserSettingsForm.show_new_post_notifs}
673 onChange={linkEvent(this, this.handleShowNewPostNotifs)}
676 class="form-check-label"
677 htmlFor="user-show-new-post-notifs"
679 {i18n.t("show_new_post_notifs")}
683 <div class="form-group">
684 <div class="form-check">
686 class="form-check-input"
687 id="user-send-notifications-to-email"
689 disabled={!this.state.saveUserSettingsForm.email}
691 this.state.saveUserSettingsForm.send_notifications_to_email
695 this.handleSendNotificationsToEmailChange
699 class="form-check-label"
700 htmlFor="user-send-notifications-to-email"
702 {i18n.t("send_notifications_to_email")}
706 <div class="form-group">
707 <button type="submit" class="btn btn-block btn-secondary mr-4">
708 {this.state.saveUserSettingsLoading ? (
711 capitalizeFirstLetter(i18n.t("save"))
716 <div class="form-group">
718 class="btn btn-block btn-danger"
721 this.handleDeleteAccountShowConfirmToggle
724 {i18n.t("delete_account")}
726 {this.state.deleteAccountShowConfirm && (
728 <div class="my-2 alert alert-danger" role="alert">
729 {i18n.t("delete_account_confirm")}
733 value={this.state.deleteAccountForm.password}
734 autoComplete="new-password"
738 this.handleDeleteAccountPasswordChange
740 class="form-control my-2"
743 class="btn btn-danger mr-4"
744 disabled={!this.state.deleteAccountForm.password}
745 onClick={linkEvent(this, this.handleDeleteAccount)}
747 {this.state.deleteAccountLoading ? (
750 capitalizeFirstLetter(i18n.t("delete"))
754 class="btn btn-secondary"
757 this.handleDeleteAccountShowConfirmToggle
770 setupBlockPersonChoices() {
772 let selectId: any = document.getElementById("block-person-filter");
774 this.blockPersonChoices = new Choices(selectId, choicesConfig);
775 this.blockPersonChoices.passedElement.element.addEventListener(
778 this.handleBlockPerson(Number(e.detail.choice.value));
782 this.blockPersonChoices.passedElement.element.addEventListener(
784 debounce(async (e: any) => {
785 let persons = (await fetchUsers(e.detail.value)).users;
786 let choices = persons.map(pvs => personToChoice(pvs));
787 this.blockPersonChoices.setChoices(choices, "value", "label", true);
795 setupBlockCommunityChoices() {
797 let selectId: any = document.getElementById("block-community-filter");
799 this.blockCommunityChoices = new Choices(selectId, choicesConfig);
800 this.blockCommunityChoices.passedElement.element.addEventListener(
803 this.handleBlockCommunity(Number(e.detail.choice.value));
807 this.blockCommunityChoices.passedElement.element.addEventListener(
809 debounce(async (e: any) => {
810 let communities = (await fetchCommunities(e.detail.value))
812 let choices = communities.map(cv => communityToChoice(cv));
813 this.blockCommunityChoices.setChoices(
826 handleBlockPerson(personId: number) {
828 let blockUserForm: BlockPerson = {
833 WebSocketService.Instance.send(wsClient.blockPerson(blockUserForm));
837 handleUnblockPerson(i: { ctx: Settings; recipientId: number }) {
838 let blockUserForm: BlockPerson = {
839 person_id: i.recipientId,
843 WebSocketService.Instance.send(wsClient.blockPerson(blockUserForm));
846 handleBlockCommunity(community_id: number) {
847 if (community_id != 0) {
848 let blockCommunityForm: BlockCommunity = {
853 WebSocketService.Instance.send(
854 wsClient.blockCommunity(blockCommunityForm)
859 handleUnblockCommunity(i: { ctx: Settings; communityId: number }) {
860 let blockCommunityForm: BlockCommunity = {
861 community_id: i.communityId,
865 WebSocketService.Instance.send(wsClient.blockCommunity(blockCommunityForm));
868 handleShowNsfwChange(i: Settings, event: any) {
869 i.state.saveUserSettingsForm.show_nsfw = event.target.checked;
873 handleShowAvatarsChange(i: Settings, event: any) {
874 i.state.saveUserSettingsForm.show_avatars = event.target.checked;
875 UserService.Instance.myUserInfo.local_user_view.local_user.show_avatars =
876 event.target.checked; // Just for instant updates
880 handleBotAccount(i: Settings, event: any) {
881 i.state.saveUserSettingsForm.bot_account = event.target.checked;
885 handleShowBotAccounts(i: Settings, event: any) {
886 i.state.saveUserSettingsForm.show_bot_accounts = event.target.checked;
890 handleReadPosts(i: Settings, event: any) {
891 i.state.saveUserSettingsForm.show_read_posts = event.target.checked;
895 handleShowNewPostNotifs(i: Settings, event: any) {
896 i.state.saveUserSettingsForm.show_new_post_notifs = event.target.checked;
900 handleShowScoresChange(i: Settings, event: any) {
901 i.state.saveUserSettingsForm.show_scores = event.target.checked;
902 UserService.Instance.myUserInfo.local_user_view.local_user.show_scores =
903 event.target.checked; // Just for instant updates
907 handleSendNotificationsToEmailChange(i: Settings, event: any) {
908 i.state.saveUserSettingsForm.send_notifications_to_email =
909 event.target.checked;
913 handleThemeChange(i: Settings, event: any) {
914 i.state.saveUserSettingsForm.theme = event.target.value;
915 setTheme(event.target.value, true);
919 handleLangChange(i: Settings, event: any) {
920 i.state.saveUserSettingsForm.lang = event.target.value;
921 i18n.changeLanguage(getLanguage(i.state.saveUserSettingsForm.lang));
925 handleSortTypeChange(val: SortType) {
926 this.state.saveUserSettingsForm.default_sort_type =
927 Object.keys(SortType).indexOf(val);
928 this.setState(this.state);
931 handleListingTypeChange(val: ListingType) {
932 this.state.saveUserSettingsForm.default_listing_type =
933 Object.keys(ListingType).indexOf(val);
934 this.setState(this.state);
937 handleEmailChange(i: Settings, event: any) {
938 i.state.saveUserSettingsForm.email = event.target.value;
942 handleBioChange(val: string) {
943 this.state.saveUserSettingsForm.bio = val;
944 this.setState(this.state);
947 handleAvatarUpload(url: string) {
948 this.state.saveUserSettingsForm.avatar = url;
949 this.setState(this.state);
952 handleAvatarRemove() {
953 this.state.saveUserSettingsForm.avatar = "";
954 this.setState(this.state);
957 handleBannerUpload(url: string) {
958 this.state.saveUserSettingsForm.banner = url;
959 this.setState(this.state);
962 handleBannerRemove() {
963 this.state.saveUserSettingsForm.banner = "";
964 this.setState(this.state);
967 handleDisplayNameChange(i: Settings, event: any) {
968 i.state.saveUserSettingsForm.display_name = event.target.value;
972 handleMatrixUserIdChange(i: Settings, event: any) {
973 i.state.saveUserSettingsForm.matrix_user_id = event.target.value;
975 i.state.saveUserSettingsForm.matrix_user_id == "" &&
976 !UserService.Instance.myUserInfo.local_user_view.person.matrix_user_id
978 i.state.saveUserSettingsForm.matrix_user_id = undefined;
983 handleNewPasswordChange(i: Settings, event: any) {
984 i.state.changePasswordForm.new_password = event.target.value;
985 if (i.state.changePasswordForm.new_password == "") {
986 i.state.changePasswordForm.new_password = undefined;
991 handleNewPasswordVerifyChange(i: Settings, event: any) {
992 i.state.changePasswordForm.new_password_verify = event.target.value;
993 if (i.state.changePasswordForm.new_password_verify == "") {
994 i.state.changePasswordForm.new_password_verify = undefined;
999 handleOldPasswordChange(i: Settings, event: any) {
1000 i.state.changePasswordForm.old_password = event.target.value;
1001 if (i.state.changePasswordForm.old_password == "") {
1002 i.state.changePasswordForm.old_password = undefined;
1004 i.setState(i.state);
1007 handleSaveSettingsSubmit(i: Settings, event: any) {
1008 event.preventDefault();
1009 i.state.saveUserSettingsLoading = true;
1010 i.setState(i.state);
1012 WebSocketService.Instance.send(
1013 wsClient.saveUserSettings(i.state.saveUserSettingsForm)
1017 handleChangePasswordSubmit(i: Settings, event: any) {
1018 event.preventDefault();
1019 i.state.changePasswordLoading = true;
1020 i.setState(i.state);
1022 WebSocketService.Instance.send(
1023 wsClient.changePassword(i.state.changePasswordForm)
1027 handleDeleteAccountShowConfirmToggle(i: Settings, event: any) {
1028 event.preventDefault();
1029 i.state.deleteAccountShowConfirm = !i.state.deleteAccountShowConfirm;
1030 i.setState(i.state);
1033 handleDeleteAccountPasswordChange(i: Settings, event: any) {
1034 i.state.deleteAccountForm.password = event.target.value;
1035 i.setState(i.state);
1038 handleLogoutClick(_i: Settings) {
1039 UserService.Instance.logout();
1040 window.location.href = "/";
1044 handleDeleteAccount(i: Settings, event: any) {
1045 event.preventDefault();
1046 i.state.deleteAccountLoading = true;
1047 i.setState(i.state);
1049 WebSocketService.Instance.send(
1050 wsClient.deleteAccount(i.state.deleteAccountForm)
1054 handleSwitchTab(i: { ctx: Settings; tab: string }) {
1055 i.ctx.setState({ currentTab: i.tab });
1057 if (i.ctx.state.currentTab == "blocks") {
1058 i.ctx.setupBlockPersonChoices();
1059 i.ctx.setupBlockCommunityChoices();
1064 let luv = UserService.Instance.myUserInfo.local_user_view;
1065 this.state.saveUserSettingsForm.show_nsfw = luv.local_user.show_nsfw;
1066 this.state.saveUserSettingsForm.theme = luv.local_user.theme
1067 ? luv.local_user.theme
1069 this.state.saveUserSettingsForm.default_sort_type =
1070 luv.local_user.default_sort_type;
1071 this.state.saveUserSettingsForm.default_listing_type =
1072 luv.local_user.default_listing_type;
1073 this.state.saveUserSettingsForm.lang = luv.local_user.lang;
1074 this.state.saveUserSettingsForm.avatar = luv.person.avatar;
1075 this.state.saveUserSettingsForm.banner = luv.person.banner;
1076 this.state.saveUserSettingsForm.display_name = luv.person.display_name;
1077 this.state.saveUserSettingsForm.show_avatars = luv.local_user.show_avatars;
1078 this.state.saveUserSettingsForm.bot_account = luv.person.bot_account;
1079 this.state.saveUserSettingsForm.show_bot_accounts =
1080 luv.local_user.show_bot_accounts;
1081 this.state.saveUserSettingsForm.show_scores = luv.local_user.show_scores;
1082 this.state.saveUserSettingsForm.show_read_posts =
1083 luv.local_user.show_read_posts;
1084 this.state.saveUserSettingsForm.show_new_post_notifs =
1085 luv.local_user.show_new_post_notifs;
1086 this.state.saveUserSettingsForm.email = luv.local_user.email;
1087 this.state.saveUserSettingsForm.bio = luv.person.bio;
1088 this.state.saveUserSettingsForm.send_notifications_to_email =
1089 luv.local_user.send_notifications_to_email;
1090 this.state.saveUserSettingsForm.matrix_user_id = luv.person.matrix_user_id;
1091 this.state.personBlocks = UserService.Instance.myUserInfo.person_blocks;
1092 this.state.communityBlocks =
1093 UserService.Instance.myUserInfo.community_blocks;
1096 parseMessage(msg: any) {
1097 let op = wsUserOp(msg);
1100 toast(i18n.t(msg.error), "danger");
1102 } else if (op == UserOperation.SaveUserSettings) {
1103 let data = wsJsonToRes<LoginResponse>(msg).data;
1104 UserService.Instance.login(data);
1105 this.state.saveUserSettingsLoading = false;
1106 this.setState(this.state);
1108 window.scrollTo(0, 0);
1109 } else if (op == UserOperation.ChangePassword) {
1110 let data = wsJsonToRes<LoginResponse>(msg).data;
1111 UserService.Instance.login(data);
1112 this.state.changePasswordLoading = false;
1113 this.setState(this.state);
1114 window.scrollTo(0, 0);
1115 toast(i18n.t("password_changed"));
1116 } else if (op == UserOperation.DeleteAccount) {
1118 deleteAccountLoading: false,
1119 deleteAccountShowConfirm: false,
1121 UserService.Instance.logout();
1122 window.location.href = "/";
1124 } else if (op == UserOperation.BlockPerson) {
1125 let data = wsJsonToRes<BlockPersonResponse>(msg).data;
1126 this.setState({ personBlocks: updatePersonBlock(data) });
1127 } else if (op == UserOperation.BlockCommunity) {
1128 let data = wsJsonToRes<BlockCommunityResponse>(msg).data;
1129 this.setState({ communityBlocks: updateCommunityBlock(data) });