import { Component, linkEvent } from "inferno"; import ISO6391 from "iso-639-1"; import { BlockCommunity, BlockCommunityResponse, BlockPerson, BlockPersonResponse, ChangePassword, CommunityBlockView, CommunityView, DeleteAccount, GetSiteResponse, ListingType, LoginResponse, PersonBlockView, PersonViewSafe, SaveUserSettings, SortType, UserOperation, } from "lemmy-js-client"; import { Subscription } from "rxjs"; import { i18n } from "../../i18next"; import { UserService, WebSocketService } from "../../services"; import { authField, capitalizeFirstLetter, choicesConfig, communitySelectName, communityToChoice, debounce, elementUrl, fetchCommunities, fetchUsers, getLanguage, isBrowser, languages, personSelectName, personToChoice, setIsoData, setTheme, setupTippy, showLocal, themes, toast, updateCommunityBlock, updatePersonBlock, wsClient, wsJsonToRes, wsSubscribe, wsUserOp, } from "../../utils"; import { HtmlTags } from "../common/html-tags"; import { Icon, Spinner } from "../common/icon"; import { ImageUploadForm } from "../common/image-upload-form"; import { ListingTypeSelect } from "../common/listing-type-select"; import { MarkdownTextArea } from "../common/markdown-textarea"; import { SortSelect } from "../common/sort-select"; import { CommunityLink } from "../community/community-link"; import { PersonListing } from "./person-listing"; var Choices: any; if (isBrowser()) { Choices = require("choices.js"); } interface SettingsState { saveUserSettingsForm: SaveUserSettings; changePasswordForm: ChangePassword; saveUserSettingsLoading: boolean; changePasswordLoading: boolean; deleteAccountLoading: boolean; deleteAccountShowConfirm: boolean; deleteAccountForm: DeleteAccount; personBlocks: PersonBlockView[]; blockPersonId: number; blockPerson?: PersonViewSafe; communityBlocks: CommunityBlockView[]; blockCommunityId: number; blockCommunity?: CommunityView; currentTab: string; siteRes: GetSiteResponse; } export class Settings extends Component { private isoData = setIsoData(this.context); private blockPersonChoices: any; private blockCommunityChoices: any; private subscription: Subscription; private emptyState: SettingsState = { saveUserSettingsForm: { auth: authField(false), }, changePasswordForm: { new_password: null, new_password_verify: null, old_password: null, auth: authField(false), }, saveUserSettingsLoading: null, changePasswordLoading: false, deleteAccountLoading: null, deleteAccountShowConfirm: false, deleteAccountForm: { password: null, auth: authField(false), }, personBlocks: [], blockPersonId: 0, communityBlocks: [], blockCommunityId: 0, currentTab: "settings", siteRes: this.isoData.site_res, }; constructor(props: any, context: any) { super(props, context); this.state = this.emptyState; this.handleSortTypeChange = this.handleSortTypeChange.bind(this); this.handleListingTypeChange = this.handleListingTypeChange.bind(this); this.handleBioChange = this.handleBioChange.bind(this); this.handleAvatarUpload = this.handleAvatarUpload.bind(this); this.handleAvatarRemove = this.handleAvatarRemove.bind(this); this.handleBannerUpload = this.handleBannerUpload.bind(this); this.handleBannerRemove = this.handleBannerRemove.bind(this); this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); this.setUserInfo(); setupTippy(); } componentWillUnmount() { this.subscription.unsubscribe(); } get documentTitle(): string { return i18n.t("settings"); } render() { return (
<> {this.state.currentTab == "settings" && this.userSettings()} {this.state.currentTab == "blocks" && this.blockCards()}
); } userSettings() { return (
{this.saveUserSettingsHtmlForm()}
{this.changePasswordHtmlForm()}
); } blockCards() { return (
{this.blockUserCard()}
{this.blockCommunityCard()}
); } changePasswordHtmlForm() { return ( <>
{i18n.t("change_password")}
); } blockUserCard() { return (
{this.blockUserForm()} {this.blockedUsersList()}
); } blockedUsersList() { return ( <>
{i18n.t("blocked_users")}
); } blockUserForm() { return (
); } blockCommunityCard() { return (
{this.blockCommunityForm()} {this.blockedCommunitiesList()}
); } blockedCommunitiesList() { return ( <>
{i18n.t("blocked_communities")}
); } blockCommunityForm() { return (
); } saveUserSettingsHtmlForm() { return ( <>
{i18n.t("settings")}
{this.state.siteRes.site_view.site.enable_nsfw && (
)}

{this.state.deleteAccountShowConfirm && ( <> )}
); } setupBlockPersonChoices() { if (isBrowser()) { let selectId: any = document.getElementById("block-person-filter"); if (selectId) { this.blockPersonChoices = new Choices(selectId, choicesConfig); this.blockPersonChoices.passedElement.element.addEventListener( "choice", (e: any) => { this.handleBlockPerson(Number(e.detail.choice.value)); }, false ); this.blockPersonChoices.passedElement.element.addEventListener( "search", debounce(async (e: any) => { let persons = (await fetchUsers(e.detail.value)).users; let choices = persons.map(pvs => personToChoice(pvs)); this.blockPersonChoices.setChoices(choices, "value", "label", true); }, 400), false ); } } } setupBlockCommunityChoices() { if (isBrowser()) { let selectId: any = document.getElementById("block-community-filter"); if (selectId) { this.blockCommunityChoices = new Choices(selectId, choicesConfig); this.blockCommunityChoices.passedElement.element.addEventListener( "choice", (e: any) => { this.handleBlockCommunity(Number(e.detail.choice.value)); }, false ); this.blockCommunityChoices.passedElement.element.addEventListener( "search", debounce(async (e: any) => { let communities = (await fetchCommunities(e.detail.value)) .communities; let choices = communities.map(cv => communityToChoice(cv)); this.blockCommunityChoices.setChoices( choices, "value", "label", true ); }, 400), false ); } } } handleBlockPerson(personId: number) { if (personId != 0) { let blockUserForm: BlockPerson = { person_id: personId, block: true, auth: authField(), }; WebSocketService.Instance.send(wsClient.blockPerson(blockUserForm)); } } handleUnblockPerson(i: { ctx: Settings; recipientId: number }) { let blockUserForm: BlockPerson = { person_id: i.recipientId, block: false, auth: authField(), }; WebSocketService.Instance.send(wsClient.blockPerson(blockUserForm)); } handleBlockCommunity(community_id: number) { if (community_id != 0) { let blockCommunityForm: BlockCommunity = { community_id, block: true, auth: authField(), }; WebSocketService.Instance.send( wsClient.blockCommunity(blockCommunityForm) ); } } handleUnblockCommunity(i: { ctx: Settings; communityId: number }) { let blockCommunityForm: BlockCommunity = { community_id: i.communityId, block: false, auth: authField(), }; WebSocketService.Instance.send(wsClient.blockCommunity(blockCommunityForm)); } handleShowNsfwChange(i: Settings, event: any) { i.state.saveUserSettingsForm.show_nsfw = event.target.checked; i.setState(i.state); } handleShowAvatarsChange(i: Settings, event: any) { i.state.saveUserSettingsForm.show_avatars = event.target.checked; UserService.Instance.myUserInfo.local_user_view.local_user.show_avatars = event.target.checked; // Just for instant updates i.setState(i.state); } handleBotAccount(i: Settings, event: any) { i.state.saveUserSettingsForm.bot_account = event.target.checked; i.setState(i.state); } handleShowBotAccounts(i: Settings, event: any) { i.state.saveUserSettingsForm.show_bot_accounts = event.target.checked; i.setState(i.state); } handleReadPosts(i: Settings, event: any) { i.state.saveUserSettingsForm.show_read_posts = event.target.checked; i.setState(i.state); } handleShowNewPostNotifs(i: Settings, event: any) { i.state.saveUserSettingsForm.show_new_post_notifs = event.target.checked; i.setState(i.state); } handleShowScoresChange(i: Settings, event: any) { i.state.saveUserSettingsForm.show_scores = event.target.checked; UserService.Instance.myUserInfo.local_user_view.local_user.show_scores = event.target.checked; // Just for instant updates i.setState(i.state); } handleSendNotificationsToEmailChange(i: Settings, event: any) { i.state.saveUserSettingsForm.send_notifications_to_email = event.target.checked; i.setState(i.state); } handleThemeChange(i: Settings, event: any) { i.state.saveUserSettingsForm.theme = event.target.value; setTheme(event.target.value, true); i.setState(i.state); } handleLangChange(i: Settings, event: any) { i.state.saveUserSettingsForm.lang = event.target.value; i18n.changeLanguage(getLanguage(i.state.saveUserSettingsForm.lang)); i.setState(i.state); } handleSortTypeChange(val: SortType) { this.state.saveUserSettingsForm.default_sort_type = Object.keys(SortType).indexOf(val); this.setState(this.state); } handleListingTypeChange(val: ListingType) { this.state.saveUserSettingsForm.default_listing_type = Object.keys(ListingType).indexOf(val); this.setState(this.state); } handleEmailChange(i: Settings, event: any) { i.state.saveUserSettingsForm.email = event.target.value; i.setState(i.state); } handleBioChange(val: string) { this.state.saveUserSettingsForm.bio = val; this.setState(this.state); } handleAvatarUpload(url: string) { this.state.saveUserSettingsForm.avatar = url; this.setState(this.state); } handleAvatarRemove() { this.state.saveUserSettingsForm.avatar = ""; this.setState(this.state); } handleBannerUpload(url: string) { this.state.saveUserSettingsForm.banner = url; this.setState(this.state); } handleBannerRemove() { this.state.saveUserSettingsForm.banner = ""; this.setState(this.state); } handleDisplayNameChange(i: Settings, event: any) { i.state.saveUserSettingsForm.display_name = event.target.value; i.setState(i.state); } handleMatrixUserIdChange(i: Settings, event: any) { i.state.saveUserSettingsForm.matrix_user_id = event.target.value; if ( i.state.saveUserSettingsForm.matrix_user_id == "" && !UserService.Instance.myUserInfo.local_user_view.person.matrix_user_id ) { i.state.saveUserSettingsForm.matrix_user_id = undefined; } i.setState(i.state); } handleNewPasswordChange(i: Settings, event: any) { i.state.changePasswordForm.new_password = event.target.value; if (i.state.changePasswordForm.new_password == "") { i.state.changePasswordForm.new_password = undefined; } i.setState(i.state); } handleNewPasswordVerifyChange(i: Settings, event: any) { i.state.changePasswordForm.new_password_verify = event.target.value; if (i.state.changePasswordForm.new_password_verify == "") { i.state.changePasswordForm.new_password_verify = undefined; } i.setState(i.state); } handleOldPasswordChange(i: Settings, event: any) { i.state.changePasswordForm.old_password = event.target.value; if (i.state.changePasswordForm.old_password == "") { i.state.changePasswordForm.old_password = undefined; } i.setState(i.state); } handleSaveSettingsSubmit(i: Settings, event: any) { event.preventDefault(); i.state.saveUserSettingsLoading = true; i.setState(i.state); WebSocketService.Instance.send( wsClient.saveUserSettings(i.state.saveUserSettingsForm) ); } handleChangePasswordSubmit(i: Settings, event: any) { event.preventDefault(); i.state.changePasswordLoading = true; i.setState(i.state); WebSocketService.Instance.send( wsClient.changePassword(i.state.changePasswordForm) ); } handleDeleteAccountShowConfirmToggle(i: Settings, event: any) { event.preventDefault(); i.state.deleteAccountShowConfirm = !i.state.deleteAccountShowConfirm; i.setState(i.state); } handleDeleteAccountPasswordChange(i: Settings, event: any) { i.state.deleteAccountForm.password = event.target.value; i.setState(i.state); } handleDeleteAccount(i: Settings, event: any) { event.preventDefault(); i.state.deleteAccountLoading = true; i.setState(i.state); WebSocketService.Instance.send( wsClient.deleteAccount(i.state.deleteAccountForm) ); } handleSwitchTab(i: { ctx: Settings; tab: string }) { i.ctx.setState({ currentTab: i.tab }); if (i.ctx.state.currentTab == "blocks") { i.ctx.setupBlockPersonChoices(); i.ctx.setupBlockCommunityChoices(); } } setUserInfo() { let luv = UserService.Instance.myUserInfo.local_user_view; this.state.saveUserSettingsForm.show_nsfw = luv.local_user.show_nsfw; this.state.saveUserSettingsForm.theme = luv.local_user.theme ? luv.local_user.theme : "browser"; this.state.saveUserSettingsForm.default_sort_type = luv.local_user.default_sort_type; this.state.saveUserSettingsForm.default_listing_type = luv.local_user.default_listing_type; this.state.saveUserSettingsForm.lang = luv.local_user.lang; this.state.saveUserSettingsForm.avatar = luv.person.avatar; this.state.saveUserSettingsForm.banner = luv.person.banner; this.state.saveUserSettingsForm.display_name = luv.person.display_name; this.state.saveUserSettingsForm.show_avatars = luv.local_user.show_avatars; this.state.saveUserSettingsForm.bot_account = luv.person.bot_account; this.state.saveUserSettingsForm.show_bot_accounts = luv.local_user.show_bot_accounts; this.state.saveUserSettingsForm.show_scores = luv.local_user.show_scores; this.state.saveUserSettingsForm.show_read_posts = luv.local_user.show_read_posts; this.state.saveUserSettingsForm.show_new_post_notifs = luv.local_user.show_new_post_notifs; this.state.saveUserSettingsForm.email = luv.local_user.email; this.state.saveUserSettingsForm.bio = luv.person.bio; this.state.saveUserSettingsForm.send_notifications_to_email = luv.local_user.send_notifications_to_email; this.state.saveUserSettingsForm.matrix_user_id = luv.person.matrix_user_id; this.state.personBlocks = UserService.Instance.myUserInfo.person_blocks; this.state.communityBlocks = UserService.Instance.myUserInfo.community_blocks; } parseMessage(msg: any) { let op = wsUserOp(msg); console.log(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); return; } else if (op == UserOperation.SaveUserSettings) { let data = wsJsonToRes(msg).data; UserService.Instance.login(data); this.state.saveUserSettingsLoading = false; this.setState(this.state); window.scrollTo(0, 0); } else if (op == UserOperation.ChangePassword) { let data = wsJsonToRes(msg).data; UserService.Instance.login(data); this.state.changePasswordLoading = false; this.setState(this.state); window.scrollTo(0, 0); toast(i18n.t("password_changed")); } else if (op == UserOperation.DeleteAccount) { this.setState({ deleteAccountLoading: false, deleteAccountShowConfirm: false, }); UserService.Instance.logout(); window.location.href = "/"; location.reload(); } else if (op == UserOperation.BlockPerson) { let data = wsJsonToRes(msg).data; this.setState({ personBlocks: updatePersonBlock(data) }); } else if (op == UserOperation.BlockCommunity) { let data = wsJsonToRes(msg).data; this.setState({ communityBlocks: updateCommunityBlock(data) }); } } }