import * as React from "react"; import * as System from "~/components/system"; import * as Actions from "~/common/actions"; import * as Strings from "~/common/strings"; import * as Validations from "~/common/validations"; import * as Window from "~/common/window"; import * as Constants from "~/common/constants"; import * as FileUtilities from "~/common/file-utilities"; import * as UserBehaviors from "~/common/user-behaviors"; import * as Events from "~/common/custom-events"; import * as SVG from "~/common/svg"; import { css } from "@emotion/react"; import { SecondaryTabGroup } from "~/components/core/TabGroup"; import { ConfirmationModal } from "~/components/core/ConfirmationModal"; import WebsitePrototypeWrapper from "~/components/core/WebsitePrototypeWrapper"; import ScenePage from "~/components/core/ScenePage"; import ScenePageHeader from "~/components/core/ScenePageHeader"; import ProfilePhoto from "~/components/core/ProfilePhoto"; const STYLES_FILE_HIDDEN = css` height: 1px; width: 1px; opacity: 0; visibility: hidden; position: fixed; top: -1px; left: -1px; `; const STYLES_COPY_INPUT = css` pointer-events: none; position: absolute; opacity: 0; `; const STYLES_HEADER = css` font-family: ${Constants.font.semiBold}; margin-top: 32px; margin-bottom: 16px; `; export default class SceneEditAccount extends React.Component { state = { username: this.props.viewer.username, password: "", confirm: "", body: this.props.viewer.body, photo: this.props.viewer.photo, name: this.props.viewer.name, deleting: false, allowAutomaticDataStorage: this.props.viewer.allowAutomaticDataStorage, allowEncryptedDataStorage: this.props.viewer.allowEncryptedDataStorage, changingPassword: false, changingAvatar: false, savingNameBio: false, changingFilecoin: false, modalShow: false, showPassword: false, }; _handleUpload = async (e) => { this.setState({ changingAvatar: true }); let file = await UserBehaviors.uploadImage(e.target.files[0]); if (!file) { this.setState({ changingAvatar: false }); return; } const cid = file.cid; const url = Strings.getURLfromCID(cid); let updateResponse = await Actions.updateViewer({ user: { photo: Strings.getURLfromCID(cid), }, }); Events.hasError(updateResponse); this.setState({ changingAvatar: false, photo: url }); }; _handleSaveFilecoin = async (e) => { this.setState({ changingFilecoin: true }); let response = await Actions.updateViewer({ user: { allowAutomaticDataStorage: this.state.allowAutomaticDataStorage, allowEncryptedDataStorage: this.state.allowEncryptedDataStorage, }, }); Events.hasError(response); this.setState({ changingFilecoin: false }); }; _handleSave = async (e) => { if (!Validations.username(this.state.username)) { Events.dispatchMessage({ message: "Please include only letters and numbers in your username", }); return; } this.props.onAction({ type: "UPDATE_VIEWER", viewer: { username: this.state.username, name: this.state.name, body: this.state.body }, }); this.setState({ savingNameBio: true }); let response = await Actions.updateViewer({ user: { username: this.state.username, photo: this.state.photo, body: this.state.body, name: this.state.name, }, }); Events.hasError(response); this.setState({ savingNameBio: false }); }; _handleUsernameChange = (e) => { this.setState({ [e.target.name]: e.target.value.toLowerCase() }); }; _handleChangePassword = async (e) => { if (!Validations.password(this.state.password)) { Events.dispatchMessage({ message: "Password does not meet requirements", }); return; } this.setState({ changingPassword: true }); let response = await Actions.updateViewer({ type: "CHANGE_PASSWORD", user: { password: this.state.password }, }); if (Events.hasError(response)) { this.setState({ changingPassword: false }); return; } this.setState({ changingPassword: false, password: "", confirm: "" }); }; _handleDelete = async (res) => { if (!res) { this.setState({ modalShow: false }); return; } this.setState({ deleting: true }); this.setState({ modalShow: false }); await Window.delay(100); await UserBehaviors.deleteMe({ viewer: this.props.viewer }); window.location.replace("/_/auth"); this.setState({ deleting: false }); }; _handleChange = (e) => { this.setState({ [e.target.name]: e.target.value }); }; render() { let tab = this.props.page.params?.tab || "profile"; return ( {tab === "profile" ? (
Your Avatar
Upload avatar
Display name
Bio
Save
) : null} {tab === "storage" ? (
Allow Slate to make Filecoin archive storage deals on your behalf
If this box is checked, then we will make Filecoin archive storage deals on your behalf. By default these storage deals are not encrypted and anyone can retrieve them from the Filecoin Network.
Allow Slate to make archive storage deals on your behalf to the Filecoin Network. You will get a receipt in the Filecoin section. Force encryption on archive storage deals (only you can see retrieved data from the Filecoin network).
Save
) : null} {tab === "security" ? (
Change password
Passwords should be at least 8 characters long, contain a mix of upper and lowercase letters, and have at least 1 number and 1 symbol
this.setState({ showPassword: !this.state.showPassword })} icon={this.state.showPassword ? SVG.EyeOff : SVG.Eye} />
Change password
) : null} {tab === "account" ? (
Change username
Username must be unique.
Changing your username will make any links to your profile or slates that you previously shared invalid.
Change my username
Delete your account
If you choose to delete your account you will lose your Textile Hub and Powergate key.
this.setState({ modalShow: true })} loading={this.state.deleting} style={{ width: "200px" }} > Delete my account
) : null} { this._ref = c; }} value={this.state.copyValue} tabIndex="-1" css={STYLES_COPY_INPUT} />{" "} {this.state.modalShow && ( )}
); } }