2020-07-22 08:53:29 +03:00
import * as React from "react" ;
import * as System from "~/components/system" ;
import * as Actions from "~/common/actions" ;
2020-08-25 21:08:42 +03:00
import * as Constants from "~/common/constants" ;
import * as Strings from "~/common/strings" ;
2020-07-23 11:57:44 +03:00
import * as Validations from "~/common/validations" ;
2020-08-20 08:29:33 +03:00
import * as FileUtilities from "~/common/file-utilities" ;
2020-04-09 00:29:13 +03:00
2020-07-22 08:53:29 +03:00
import { css } from "@emotion/react" ;
2020-09-12 01:25:33 +03:00
import { dispatchCustomEvent } from "~/common/custom-events" ;
2020-04-09 00:29:13 +03:00
2020-07-22 08:53:29 +03:00
import ScenePage from "~/components/core/ScenePage" ;
import Avatar from "~/components/core/Avatar" ;
2020-06-08 09:45:53 +03:00
const STYLES _FILE _HIDDEN = css `
height : 1 px ;
width : 1 px ;
opacity : 0 ;
visibility : hidden ;
position : fixed ;
top : - 1 px ;
left : - 1 px ;
` ;
2020-04-09 00:29:13 +03:00
2020-07-22 08:53:29 +03:00
const delay = ( time ) =>
new Promise ( ( resolve ) =>
setTimeout ( ( ) => {
resolve ( ) ;
} , time )
) ;
2020-04-09 00:29:13 +03:00
export default class SceneEditAccount extends React . Component {
2020-07-23 11:57:44 +03:00
state = {
username : this . props . viewer . username ,
password : "" ,
confirm : "" ,
2020-08-22 08:45:50 +03:00
body : this . props . viewer . data . body ,
photo : this . props . viewer . data . photo ,
2020-08-25 08:00:32 +03:00
name : this . props . viewer . data . name ,
2020-07-23 11:57:44 +03:00
deleting : false ,
2020-09-29 00:30:12 +03:00
allow _filecoin _directory _listing : this . props . viewer
. allow _filecoin _directory _listing ,
2020-09-27 02:40:44 +03:00
allow _automatic _data _storage : this . props . viewer
. allow _automatic _data _storage ,
allow _encrypted _data _storage : this . props . viewer
. allow _encrypted _data _storage ,
2020-07-23 11:57:44 +03:00
changingPassword : false ,
changingUsername : false ,
changingAvatar : false ,
2020-09-27 02:40:44 +03:00
changingFilecoin : false ,
2020-07-23 11:57:44 +03:00
} ;
2020-07-01 09:41:54 +03:00
2020-06-08 09:45:53 +03:00
_handleUpload = async ( e ) => {
2020-07-23 11:57:44 +03:00
this . setState ( { changingAvatar : true } ) ;
2020-06-08 09:45:53 +03:00
e . persist ( ) ;
let file = e . target . files [ 0 ] ;
if ( ! file ) {
2020-09-12 01:25:33 +03:00
dispatchCustomEvent ( {
name : "create-alert" ,
detail : {
alert : {
message : "Something went wrong with the upload. Please try again" ,
} ,
} ,
} ) ;
2020-08-02 09:00:04 +03:00
return ;
}
2020-09-08 08:08:10 +03:00
// NOTE(jim): Only allow images for account avatar.
2020-08-02 09:00:04 +03:00
if ( ! file . type . startsWith ( "image/" ) ) {
2020-09-12 01:25:33 +03:00
dispatchCustomEvent ( {
name : "create-alert" ,
detail : {
alert : { message : "Upload failed. Only images and gifs are allowed" } ,
} ,
} ) ;
2020-08-02 09:00:04 +03:00
return ;
2020-06-08 09:45:53 +03:00
}
2020-09-23 23:54:43 +03:00
const response = await FileUtilities . upload ( { file } ) ;
2020-07-22 13:51:40 +03:00
2020-09-23 23:54:43 +03:00
if ( ! response ) {
dispatchCustomEvent ( {
name : "create-alert" ,
detail : {
alert : { message : "We're having trouble connecting right now" } ,
} ,
} ) ;
this . setState ( { changingAvatar : false } ) ;
return ;
}
if ( response . error ) {
2020-09-12 01:25:33 +03:00
dispatchCustomEvent ( {
name : "create-alert" ,
detail : { alert : { decorator : json . decorator } } ,
} ) ;
2020-07-24 10:45:21 +03:00
this . setState ( { changingAvatar : false } ) ;
return ;
}
2020-09-23 23:54:43 +03:00
const { json } = response ;
2020-08-25 21:08:42 +03:00
const cid = json . data . ipfs . replace ( "/ipfs/" , "" ) ;
2020-09-03 03:58:56 +03:00
const url = Strings . getCIDGatewayURL ( cid ) ;
2020-07-22 13:51:40 +03:00
await Actions . updateViewer ( {
2020-08-22 08:45:50 +03:00
data : {
2020-08-25 21:08:42 +03:00
photo : Strings . getCIDGatewayURL ( cid ) ,
2020-08-22 08:45:50 +03:00
body : this . state . body ,
2020-08-25 08:00:32 +03:00
name : this . state . name ,
2020-08-22 08:45:50 +03:00
} ,
2020-07-22 13:51:40 +03:00
} ) ;
2020-07-23 11:57:44 +03:00
await this . props . onRehydrate ( ) ;
2020-09-03 03:58:56 +03:00
this . setState ( { changingAvatar : false , photo : url } ) ;
2020-06-08 09:45:53 +03:00
} ;
2020-08-22 08:45:50 +03:00
_handleSaveBio = async ( e ) => {
this . setState ( { changingBio : true } ) ;
await Actions . updateViewer ( {
data : {
photo : this . state . photo ,
body : this . state . body ,
2020-08-25 08:00:32 +03:00
name : this . state . name ,
2020-08-22 08:45:50 +03:00
} ,
} ) ;
await this . props . onRehydrate ( ) ;
this . setState ( { changingBio : false } ) ;
} ;
2020-09-27 02:40:44 +03:00
_handleSaveFilecoin = async ( e ) => {
this . setState ( { changingFilecoin : true } ) ;
await Actions . updateViewer ( {
data : {
photo : this . state . photo ,
body : this . state . body ,
name : this . state . name ,
2020-09-29 00:30:12 +03:00
allow _filecoin _directory _listing : this . state
. allow _filecoin _directory _listing ,
2020-09-27 02:40:44 +03:00
allow _automatic _data _storage : this . state . allow _automatic _data _storage ,
allow _encrypted _data _storage : this . state . allow _encrypted _data _storage ,
} ,
} ) ;
await this . props . onRehydrate ( ) ;
this . setState ( { changingFilecoin : false } ) ;
} ;
2020-07-01 09:41:54 +03:00
_handleSave = async ( e ) => {
2020-07-23 11:57:44 +03:00
this . setState ( { changingUsername : true } ) ;
if ( ! Validations . username ( this . state . username ) ) {
2020-09-12 01:25:33 +03:00
dispatchCustomEvent ( {
name : "create-alert" ,
detail : {
alert : {
message : "Please include only letters and numbers in your username" ,
} ,
} ,
} ) ;
2020-07-23 11:57:44 +03:00
this . setState ( { changingUsername : false } ) ;
return ;
}
2020-07-22 13:51:40 +03:00
await Actions . updateViewer ( {
username : this . state . username ,
2020-08-22 08:45:50 +03:00
data : {
photo : this . state . photo ,
body : this . state . body ,
2020-08-25 08:00:32 +03:00
name : this . state . name ,
2020-08-22 08:45:50 +03:00
} ,
2020-07-22 13:51:40 +03:00
} ) ;
2020-07-01 09:41:54 +03:00
2020-07-23 11:57:44 +03:00
await this . props . onRehydrate ( ) ;
this . setState ( { changingUsername : false } ) ;
} ;
2020-09-03 19:19:52 +03:00
_handleUsernameChange = ( e ) => {
e . persist ( ) ;
this . setState ( { [ e . target . name ] : e . target . value . toLowerCase ( ) } ) ;
} ;
2020-07-23 11:57:44 +03:00
_handleChangePassword = async ( e ) => {
this . setState ( { changingPassword : true } ) ;
if ( this . state . password !== this . state . confirm ) {
2020-09-12 01:25:33 +03:00
dispatchCustomEvent ( {
name : "create-alert" ,
detail : { alert : { message : "Passwords did not match" } } ,
} ) ;
2020-07-23 11:57:44 +03:00
this . setState ( { changingPassword : false } ) ;
return ;
}
if ( ! Validations . password ( this . state . password ) ) {
2020-09-12 01:25:33 +03:00
dispatchCustomEvent ( {
name : "create-alert" ,
detail : {
alert : { message : "Password length must be more than 8 characters" } ,
} ,
} ) ;
2020-07-23 11:57:44 +03:00
this . setState ( { changingPassword : false } ) ;
return ;
}
await Actions . updateViewer ( {
type : "CHANGE_PASSWORD" ,
password : this . state . password ,
} ) ;
this . setState ( { changingPassword : false , password : "" , confirm : "" } ) ;
2020-07-01 09:41:54 +03:00
} ;
2020-07-22 08:53:29 +03:00
_handleDelete = async ( e ) => {
this . setState ( { deleting : true } ) ;
await delay ( 100 ) ;
const response = await this . props . onDeleteYourself ( ) ;
2020-09-13 05:59:47 +03:00
this . setState ( { deleting : false } ) ;
2020-07-22 08:53:29 +03:00
} ;
2020-04-09 00:29:13 +03:00
_handleChange = ( e ) => {
2020-07-01 09:41:54 +03:00
e . persist ( ) ;
this . setState ( { [ e . target . name ] : e . target . value } ) ;
2020-04-09 00:29:13 +03:00
} ;
2020-09-27 02:40:44 +03:00
_handleCheckboxChange = ( e ) => {
this . setState ( { [ e . target . name ] : e . target . value } ) ;
} ;
2020-04-09 00:29:13 +03:00
render ( ) {
2020-08-07 02:06:54 +03:00
const profileURL = ` https://slate.host/ ${ this . state . username } ` ;
2020-09-27 02:40:44 +03:00
console . log ( this . props . viewer ) ;
2020-07-23 04:25:19 +03:00
2020-04-09 00:29:13 +03:00
return (
< ScenePage >
2020-09-13 04:12:56 +03:00
< System . H1 > Account settings < / S y s t e m . H 1 >
2020-04-09 00:29:13 +03:00
< System . DescriptionGroup
style = { { marginTop : 48 } }
label = "Avatar image"
description = "This image will appear in various lists."
/ >
2020-08-22 08:45:50 +03:00
< Avatar
style = { { marginTop : 24 } }
size = { 256 }
url = { this . props . viewer . data . photo }
/ >
2020-04-09 00:29:13 +03:00
< div style = { { marginTop : 24 } } >
2020-08-22 08:45:50 +03:00
< input
css = { STYLES _FILE _HIDDEN }
type = "file"
id = "file"
onChange = { this . _handleUpload }
/ >
2020-07-22 08:53:29 +03:00
< System . ButtonPrimary
style = { { margin : "0 16px 16px 0" } }
type = "label"
htmlFor = "file"
2020-08-22 08:45:50 +03:00
loading = { this . state . changingAvatar }
>
2020-09-13 03:00:58 +03:00
Pick avatar
2020-04-09 00:29:13 +03:00
< / S y s t e m . B u t t o n P r i m a r y >
< / d i v >
2020-09-27 02:40:44 +03:00
< System . DescriptionGroup
style = { { marginTop : 48 } }
label = "Allow Slate to make Filecoin archive storage deals on your behalf"
description = "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."
/ >
< System . CheckBox
style = { { marginTop : 48 } }
2020-09-29 00:30:12 +03:00
name = "allow_filecoin_directory_listing"
value = { this . state . allow _filecoin _directory _listing }
onChange = { this . _handleCheckboxChange }
>
Show your successful deals on a directory page where others can
retrieve them .
< / S y s t e m . C h e c k B o x >
< System . CheckBox
style = { { marginTop : 24 } }
2020-09-27 02:40:44 +03:00
name = "allow_automatic_data_storage"
value = { this . state . allow _automatic _data _storage }
onChange = { this . _handleCheckboxChange }
>
Allow Slate to make archive storage deals on your behalf to the
Filecoin Network . You will get a receipt in the Filecoin section .
< / S y s t e m . C h e c k B o x >
< System . CheckBox
style = { { marginTop : 24 } }
name = "allow_encrypted_data_storage"
value = { this . state . allow _encrypted _data _storage }
onChange = { this . _handleCheckboxChange }
>
Force encryption on archive storage deals ( only you can see retrieved
data from the Filecoin network ) .
< / S y s t e m . C h e c k B o x >
< div style = { { marginTop : 24 } } >
< System . ButtonPrimary
onClick = { this . _handleSaveFilecoin }
loading = { this . state . changingFilecoin }
>
Save archiving settings
< / S y s t e m . B u t t o n P r i m a r y >
< / d i v >
2020-04-09 00:29:13 +03:00
< System . Input
2020-09-27 02:40:44 +03:00
containerStyle = { { marginTop : 64 } }
2020-07-22 10:41:29 +03:00
label = "Username"
2020-07-23 04:25:19 +03:00
description = {
< React . Fragment >
2020-08-25 08:00:32 +03:00
This is your username on Slate . Your username is unique and used
for your profile URL { " " }
2020-07-23 04:25:19 +03:00
< a href = { profileURL } target = "_blank" >
{ profileURL }
< / a >
< / R e a c t . F r a g m e n t >
}
2020-07-22 10:41:29 +03:00
name = "username"
value = { this . state . username }
2020-08-25 08:00:32 +03:00
placeholder = "Username"
2020-09-03 19:19:52 +03:00
onChange = { this . _handleUsernameChange }
2020-04-09 00:29:13 +03:00
/ >
2020-07-01 09:41:54 +03:00
< div style = { { marginTop : 24 } } >
2020-08-22 08:45:50 +03:00
< System . ButtonPrimary
onClick = { this . _handleSave }
loading = { this . state . changingUsername }
>
2020-09-13 03:00:58 +03:00
Change username
2020-07-23 11:57:44 +03:00
< / S y s t e m . B u t t o n P r i m a r y >
< / d i v >
2020-08-25 08:00:32 +03:00
< System . Input
containerStyle = { { marginTop : 48 } }
label = "Name"
description = { ` This is how your name will be publicly shown. ` }
name = "name"
value = { this . state . name }
placeholder = "Your name"
onChange = { this . _handleChange }
/ >
< System . DescriptionGroup label = "Bio" style = { { marginTop : 24 } } / >
2020-08-22 08:45:50 +03:00
< System . Textarea
style = { { marginTop : 24 } }
label = "Bio"
name = "body"
value = { this . state . body }
placeholder = "A user on Slate."
onChange = { this . _handleChange }
/ >
< div style = { { marginTop : 24 } } >
< System . ButtonPrimary
onClick = { this . _handleSaveBio }
loading = { this . state . changingBio }
>
2020-09-13 03:00:58 +03:00
Update information
2020-08-22 08:45:50 +03:00
< / S y s t e m . B u t t o n P r i m a r y >
< / d i v >
2020-07-23 11:57:44 +03:00
< System . DescriptionGroup
style = { { marginTop : 48 } }
label = "Reset password"
2020-07-24 06:09:58 +03:00
description = "Your new password must be a minimum of eight characters."
2020-07-23 11:57:44 +03:00
/ >
< System . Input
containerStyle = { { marginTop : 24 } }
label = "New password"
name = "password"
type = "password"
value = { this . state . password }
placeholder = "Your new password"
onChange = { this . _handleChange }
/ >
< System . Input
containerStyle = { { marginTop : 24 } }
label = "Confirm password"
name = "confirm"
type = "password"
value = { this . state . confirm }
placeholder = "Confirm it!"
onChange = { this . _handleChange }
/ >
< div style = { { marginTop : 24 } } >
2020-08-22 08:45:50 +03:00
< System . ButtonPrimary
onClick = { this . _handleChangePassword }
loading = { this . state . changingPassword }
>
2020-09-13 03:00:58 +03:00
Change password
2020-07-22 08:53:29 +03:00
< / S y s t e m . B u t t o n P r i m a r y >
< / d i v >
< System . DescriptionGroup
style = { { marginTop : 48 } }
label = "Delete your account"
description = "If you choose to delete your account you will lose your Textile Hub and Powergate key. Make sure you back those up before deleting your account."
/ >
< div style = { { marginTop : 24 } } >
2020-08-22 08:45:50 +03:00
< System . ButtonPrimary
onClick = { this . _handleDelete }
loading = { this . state . deleting }
>
2020-09-13 03:00:58 +03:00
Delete my account
2020-07-22 08:53:29 +03:00
< / S y s t e m . B u t t o n P r i m a r y >
2020-07-01 09:41:54 +03:00
< / d i v >
2020-04-09 00:29:13 +03:00
< / S c e n e P a g e >
) ;
}
}