2015-06-14 23:53:32 -08:00
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
var UserStore = require ( '../stores/user_store.jsx' ) ;
var SettingItemMin = require ( './setting_item_min.jsx' ) ;
var SettingItemMax = require ( './setting_item_max.jsx' ) ;
var SettingPicture = require ( './setting_picture.jsx' ) ;
2015-07-01 18:40:20 -07:00
var AccessHistoryModal = require ( './access_history_modal.jsx' ) ;
var ActivityLogModal = require ( './activity_log_modal.jsx' ) ;
2015-06-14 23:53:32 -08:00
var client = require ( '../utils/client.jsx' ) ;
var AsyncClient = require ( '../utils/async_client.jsx' ) ;
var utils = require ( '../utils/utils.jsx' ) ;
var Constants = require ( '../utils/constants.jsx' ) ;
2015-07-23 09:20:37 -07:00
var assign = require ( 'object-assign' ) ;
2015-06-14 23:53:32 -08:00
function getNotificationsStateFromStores ( ) {
var user = UserStore . getCurrentUser ( ) ;
var sound = ( ! user . notify _props || user . notify _props . desktop _sound == undefined ) ? "true" : user . notify _props . desktop _sound ;
var desktop = ( ! user . notify _props || user . notify _props . desktop == undefined ) ? "all" : user . notify _props . desktop ;
var email = ( ! user . notify _props || user . notify _props . email == undefined ) ? "true" : user . notify _props . email ;
var username _key = false ;
var mention _key = false ;
var custom _keys = "" ;
var first _name _key = false ;
2015-06-29 14:37:59 -04:00
var all _key = false ;
var channel _key = false ;
2015-06-14 23:53:32 -08:00
2015-06-29 14:37:59 -04:00
if ( user . notify _props ) {
2015-06-14 23:53:32 -08:00
if ( user . notify _props . mention _keys !== undefined ) {
var keys = user . notify _props . mention _keys . split ( ',' ) ;
if ( keys . indexOf ( user . username ) !== - 1 ) {
username _key = true ;
keys . splice ( keys . indexOf ( user . username ) , 1 ) ;
} else {
username _key = false ;
}
if ( keys . indexOf ( '@' + user . username ) !== - 1 ) {
mention _key = true ;
keys . splice ( keys . indexOf ( '@' + user . username ) , 1 ) ;
} else {
mention _key = false ;
}
custom _keys = keys . join ( ',' ) ;
}
if ( user . notify _props . first _name !== undefined ) {
first _name _key = user . notify _props . first _name === "true" ;
}
2015-06-29 14:37:59 -04:00
if ( user . notify _props . all !== undefined ) {
all _key = user . notify _props . all === "true" ;
}
if ( user . notify _props . channel !== undefined ) {
channel _key = user . notify _props . channel === "true" ;
}
2015-06-14 23:53:32 -08:00
}
2015-06-29 14:37:59 -04:00
return { notify _level : desktop , enable _email : email , enable _sound : sound , username _key : username _key , mention _key : mention _key , custom _keys : custom _keys , custom _keys _checked : custom _keys . length > 0 , first _name _key : first _name _key , all _key : all _key , channel _key : channel _key } ;
2015-06-14 23:53:32 -08:00
}
var NotificationsTab = React . createClass ( {
handleSubmit : function ( ) {
data = { }
data [ "user_id" ] = this . props . user . id ;
data [ "email" ] = this . state . enable _email ;
data [ "desktop_sound" ] = this . state . enable _sound ;
data [ "desktop" ] = this . state . notify _level ;
var mention _keys = [ ] ;
if ( this . state . username _key ) mention _keys . push ( this . props . user . username ) ;
if ( this . state . mention _key ) mention _keys . push ( '@' + this . props . user . username ) ;
var string _keys = mention _keys . join ( ',' ) ;
if ( this . state . custom _keys . length > 0 && this . state . custom _keys _checked ) {
string _keys += ',' + this . state . custom _keys ;
}
data [ "mention_keys" ] = string _keys ;
data [ "first_name" ] = this . state . first _name _key ? "true" : "false" ;
2015-06-29 14:37:59 -04:00
data [ "all" ] = this . state . all _key ? "true" : "false" ;
data [ "channel" ] = this . state . channel _key ? "true" : "false" ;
2015-06-14 23:53:32 -08:00
client . updateUserNotifyProps ( data ,
function ( data ) {
this . props . updateSection ( "" ) ;
AsyncClient . getMe ( ) ;
} . bind ( this ) ,
function ( err ) {
this . setState ( { server _error : err . message } ) ;
} . bind ( this )
) ;
} ,
2015-07-17 14:44:13 -07:00
handleClose : function ( ) {
2015-07-23 09:20:37 -07:00
$ ( this . getDOMNode ( ) ) . find ( ".form-control" ) . each ( function ( ) {
this . value = "" ;
} ) ;
this . setState ( assign ( { } , getNotificationsStateFromStores ( ) , { server _error : null } ) ) ;
2015-07-17 14:44:13 -07:00
} ,
2015-06-14 23:53:32 -08:00
componentDidMount : function ( ) {
UserStore . addChangeListener ( this . _onChange ) ;
2015-07-17 14:44:13 -07:00
$ ( '#user_settings1' ) . on ( 'hidden.bs.modal' , this . handleClose ) ;
2015-06-14 23:53:32 -08:00
} ,
componentWillUnmount : function ( ) {
UserStore . removeChangeListener ( this . _onChange ) ;
2015-07-17 14:44:13 -07:00
$ ( '#user_settings1' ) . off ( 'hidden.bs.modal' , this . handleClose ) ;
2015-06-14 23:53:32 -08:00
} ,
_onChange : function ( ) {
var newState = getNotificationsStateFromStores ( ) ;
if ( ! utils . areStatesEqual ( newState , this . state ) ) {
this . setState ( newState ) ;
}
} ,
getInitialState : function ( ) {
return getNotificationsStateFromStores ( ) ;
} ,
handleNotifyRadio : function ( notifyLevel ) {
this . setState ( { notify _level : notifyLevel } ) ;
this . refs . wrapper . getDOMNode ( ) . focus ( ) ;
} ,
handleEmailRadio : function ( enableEmail ) {
this . setState ( { enable _email : enableEmail } ) ;
this . refs . wrapper . getDOMNode ( ) . focus ( ) ;
} ,
handleSoundRadio : function ( enableSound ) {
this . setState ( { enable _sound : enableSound } ) ;
this . refs . wrapper . getDOMNode ( ) . focus ( ) ;
} ,
updateUsernameKey : function ( val ) {
this . setState ( { username _key : val } ) ;
} ,
updateMentionKey : function ( val ) {
this . setState ( { mention _key : val } ) ;
} ,
updateFirstNameKey : function ( val ) {
this . setState ( { first _name _key : val } ) ;
} ,
2015-06-29 14:37:59 -04:00
updateAllKey : function ( val ) {
this . setState ( { all _key : val } ) ;
} ,
updateChannelKey : function ( val ) {
this . setState ( { channel _key : val } ) ;
} ,
2015-06-14 23:53:32 -08:00
updateCustomMentionKeys : function ( ) {
var checked = this . refs . customcheck . getDOMNode ( ) . checked ;
if ( checked ) {
var text = this . refs . custommentions . getDOMNode ( ) . value ;
// remove all spaces and split string into individual keys
this . setState ( { custom _keys : text . replace ( / /g , '' ) , custom _keys _checked : true } ) ;
} else {
this . setState ( { custom _keys : "" , custom _keys _checked : false } ) ;
}
} ,
onCustomChange : function ( ) {
this . refs . customcheck . getDOMNode ( ) . checked = true ;
this . updateCustomMentionKeys ( ) ;
} ,
render : function ( ) {
var server _error = this . state . server _error ? this . state . server _error : null ;
var self = this ;
2015-07-13 15:39:53 -04:00
var user = this . props . user ;
2015-06-14 23:53:32 -08:00
var desktopSection ;
if ( this . props . activeSection === 'desktop' ) {
var notifyActive = [ false , false , false ] ;
if ( this . state . notify _level === "mention" ) {
notifyActive [ 1 ] = true ;
} else if ( this . state . notify _level === "none" ) {
notifyActive [ 2 ] = true ;
} else {
notifyActive [ 0 ] = true ;
}
var inputs = [ ] ;
inputs . push (
2015-06-28 04:18:24 +05:00
< div >
2015-06-14 23:53:32 -08:00
< div className = "radio" >
< label >
< input type = "radio" checked = { notifyActive [ 0 ] } onClick = { function ( ) { self . handleNotifyRadio ( "all" ) } } > For all activity < / input >
< / label >
< br / >
< / div >
< div className = "radio" >
< label >
2015-07-01 09:48:39 -07:00
< input type = "radio" checked = { notifyActive [ 1 ] } onClick = { function ( ) { self . handleNotifyRadio ( "mention" ) } } > Only for mentions and private messages < / input >
2015-06-14 23:53:32 -08:00
< / label >
< br / >
< / div >
< div className = "radio" >
< label >
< input type = "radio" checked = { notifyActive [ 2 ] } onClick = { function ( ) { self . handleNotifyRadio ( "none" ) } } > Never < / input >
< / label >
< / div >
< / div >
) ;
desktopSection = (
< SettingItemMax
title = "Send desktop notifications"
inputs = { inputs }
submit = { this . handleSubmit }
server _error = { server _error }
updateSection = { function ( e ) { self . props . updateSection ( "" ) ; e . preventDefault ( ) ; } }
/ >
) ;
} else {
var describe = "" ;
if ( this . state . notify _level === "mention" ) {
2015-07-01 09:48:39 -07:00
describe = "Only for mentions and private messages" ;
2015-06-14 23:53:32 -08:00
} else if ( this . state . notify _level === "none" ) {
describe = "Never" ;
} else {
describe = "For all activity" ;
}
desktopSection = (
< SettingItemMin
title = "Send desktop notifications"
describe = { describe }
updateSection = { function ( ) { self . props . updateSection ( "desktop" ) ; } }
/ >
) ;
}
var soundSection ;
if ( this . props . activeSection === 'sound' ) {
var soundActive = [ "" , "" ] ;
if ( this . state . enable _sound === "false" ) {
soundActive [ 1 ] = "active" ;
} else {
soundActive [ 0 ] = "active" ;
}
var inputs = [ ] ;
inputs . push (
2015-06-28 04:18:24 +05:00
< div >
2015-06-14 23:53:32 -08:00
< div className = "btn-group" data - toggle = "buttons-radio" >
< button className = { "btn btn-default " + soundActive [ 0 ] } onClick = { function ( ) { self . handleSoundRadio ( "true" ) } } > On < / button >
< button className = { "btn btn-default " + soundActive [ 1 ] } onClick = { function ( ) { self . handleSoundRadio ( "false" ) } } > Off < / button >
< / div >
< / div >
) ;
soundSection = (
< SettingItemMax
title = "Desktop notification sounds"
inputs = { inputs }
submit = { this . handleSubmit }
server _error = { server _error }
updateSection = { function ( e ) { self . props . updateSection ( "" ) ; e . preventDefault ( ) ; } }
/ >
) ;
} else {
var describe = "" ;
if ( this . state . enable _sound === "false" ) {
describe = "Off" ;
} else {
describe = "On" ;
}
soundSection = (
< SettingItemMin
title = "Desktop notification sounds"
describe = { describe }
updateSection = { function ( ) { self . props . updateSection ( "sound" ) ; } }
/ >
) ;
}
var emailSection ;
if ( this . props . activeSection === 'email' ) {
var emailActive = [ "" , "" ] ;
if ( this . state . enable _email === "false" ) {
emailActive [ 1 ] = "active" ;
} else {
emailActive [ 0 ] = "active" ;
}
var inputs = [ ] ;
inputs . push (
2015-06-28 04:18:24 +05:00
< div >
2015-06-14 23:53:32 -08:00
< div className = "btn-group" data - toggle = "buttons-radio" >
< button className = { "btn btn-default " + emailActive [ 0 ] } onClick = { function ( ) { self . handleEmailRadio ( "true" ) } } > On < / button >
< button className = { "btn btn-default " + emailActive [ 1 ] } onClick = { function ( ) { self . handleEmailRadio ( "false" ) } } > Off < / button >
< / div >
2015-07-01 09:48:39 -07:00
< div > < br / > { "Email notifications are sent for mentions and private messages after you have been away from " + config . SiteName + " for 5 minutes." } < / div >
2015-06-14 23:53:32 -08:00
< / div >
) ;
emailSection = (
< SettingItemMax
title = "Email notifications"
inputs = { inputs }
submit = { this . handleSubmit }
server _error = { server _error }
updateSection = { function ( e ) { self . props . updateSection ( "" ) ; e . preventDefault ( ) ; } }
/ >
) ;
} else {
var describe = "" ;
if ( this . state . enable _email === "false" ) {
describe = "Off" ;
} else {
describe = "On" ;
}
emailSection = (
< SettingItemMin
title = "Email notifications"
describe = { describe }
updateSection = { function ( ) { self . props . updateSection ( "email" ) ; } }
/ >
) ;
}
var keysSection ;
if ( this . props . activeSection === 'keys' ) {
var inputs = [ ] ;
2015-07-13 15:39:53 -04:00
if ( user . first _name ) {
2015-06-14 23:53:32 -08:00
inputs . push (
2015-06-28 04:18:24 +05:00
< div >
2015-06-14 23:53:32 -08:00
< div className = "checkbox" >
< label >
2015-07-13 15:39:53 -04:00
< input type = "checkbox" checked = { this . state . first _name _key } onChange = { function ( e ) { self . updateFirstNameKey ( e . target . checked ) ; } } > { 'Your case sensitive first name "' + user . first _name + '"' } < / input >
2015-06-14 23:53:32 -08:00
< / label >
< / div >
< / div >
) ;
}
inputs . push (
2015-06-28 04:18:24 +05:00
< div >
2015-06-14 23:53:32 -08:00
< div className = "checkbox" >
< label >
< input type = "checkbox" checked = { this . state . username _key } onChange = { function ( e ) { self . updateUsernameKey ( e . target . checked ) ; } } > { 'Your non-case sensitive username "' + user . username + '"' } < / input >
< / label >
< / div >
< / div >
) ;
inputs . push (
2015-06-28 04:18:24 +05:00
< div >
2015-06-14 23:53:32 -08:00
< div className = "checkbox" >
< label >
< input type = "checkbox" checked = { this . state . mention _key } onChange = { function ( e ) { self . updateMentionKey ( e . target . checked ) ; } } > { 'Your username mentioned "@' + user . username + '"' } < / input >
< / label >
< / div >
< / div >
) ;
2015-06-29 14:37:59 -04:00
inputs . push (
< div >
< div className = "checkbox" >
< label >
< input type = "checkbox" checked = { this . state . all _key } onChange = { function ( e ) { self . updateAllKey ( e . target . checked ) ; } } > { 'Team-wide mentions "@all"' } < / input >
< / label >
< / div >
< / div >
) ;
inputs . push (
< div >
< div className = "checkbox" >
< label >
< input type = "checkbox" checked = { this . state . channel _key } onChange = { function ( e ) { self . updateChannelKey ( e . target . checked ) ; } } > { 'Channel-wide mentions "@channel"' } < / input >
< / label >
< / div >
< / div >
) ;
2015-06-14 23:53:32 -08:00
inputs . push (
2015-06-28 04:18:24 +05:00
< div >
2015-06-14 23:53:32 -08:00
< div className = "checkbox" >
< label >
< input ref = "customcheck" type = "checkbox" checked = { this . state . custom _keys _checked } onChange = { this . updateCustomMentionKeys } > { 'Other non-case sensitive words, separated by commas:' } < / input >
< / label >
< / div >
< input ref = "custommentions" className = "form-control mentions-input" type = "text" defaultValue = { this . state . custom _keys } onChange = { this . onCustomChange } / >
< / div >
) ;
keysSection = (
< SettingItemMax
title = "Words that trigger mentions"
inputs = { inputs }
submit = { this . handleSubmit }
server _error = { server _error }
updateSection = { function ( e ) { self . props . updateSection ( "" ) ; e . preventDefault ( ) ; } }
/ >
) ;
} else {
var keys = [ ] ;
2015-07-13 15:39:53 -04:00
if ( this . state . first _name _key ) keys . push ( user . first _name ) ;
if ( this . state . username _key ) keys . push ( user . username ) ;
if ( this . state . mention _key ) keys . push ( '@' + user . username ) ;
2015-06-29 14:37:59 -04:00
if ( this . state . all _key ) keys . push ( '@all' ) ;
if ( this . state . channel _key ) keys . push ( '@channel' ) ;
2015-06-14 23:53:32 -08:00
if ( this . state . custom _keys . length > 0 ) keys = keys . concat ( this . state . custom _keys . split ( ',' ) ) ;
var describe = "" ;
for ( var i = 0 ; i < keys . length ; i ++ ) {
describe += '"' + keys [ i ] + '", ' ;
}
if ( describe . length > 0 ) {
describe = describe . substring ( 0 , describe . length - 2 ) ;
} else {
describe = "No words configured" ;
}
keysSection = (
< SettingItemMin
title = "Words that trigger mentions"
describe = { describe }
updateSection = { function ( ) { self . props . updateSection ( "keys" ) ; } }
/ >
) ;
}
return (
< div >
< div className = "modal-header" >
< button type = "button" className = "close" data - dismiss = "modal" aria - label = "Close" > < span aria - hidden = "true" > & times ; < / span > < / button >
< h4 className = "modal-title" ref = "title" > < i className = "modal-back" > < / i > Notifications < / h4 >
< / div >
< div ref = "wrapper" className = "user-settings" >
< h3 className = "tab-header" > Notifications < / h3 >
< div className = "divider-dark first" / >
{ desktopSection }
< div className = "divider-light" / >
{ soundSection }
< div className = "divider-light" / >
{ emailSection }
< div className = "divider-light" / >
{ keysSection }
< div className = "divider-dark" / >
< / div >
< / div >
) ;
}
} ) ;
var SecurityTab = React . createClass ( {
submitPassword : function ( e ) {
e . preventDefault ( ) ;
2015-07-15 17:50:07 -04:00
var user = this . props . user ;
2015-06-14 23:53:32 -08:00
var currentPassword = this . state . current _password ;
var newPassword = this . state . new _password ;
var confirmPassword = this . state . confirm _password ;
if ( currentPassword === '' ) {
this . setState ( { password _error : "Please enter your current password" } ) ;
return ;
}
if ( newPassword . length < 5 ) {
this . setState ( { password _error : "New passwords must be at least 5 characters" } ) ;
return ;
}
if ( newPassword != confirmPassword ) {
this . setState ( { password _error : "The new passwords you entered do not match" } ) ;
return ;
}
var data = { } ;
data . user _id = user . id ;
data . current _password = currentPassword ;
data . new _password = newPassword ;
client . updatePassword ( data ,
function ( data ) {
2015-07-15 08:45:17 -07:00
this . props . updateSection ( "" ) ;
2015-06-14 23:53:32 -08:00
AsyncClient . getMe ( ) ;
this . setState ( { current _password : '' , new _password : '' , confirm _password : '' } ) ;
} . bind ( this ) ,
function ( err ) {
state = this . getInitialState ( ) ;
state . server _error = err ;
this . setState ( state ) ;
} . bind ( this )
) ;
} ,
updateCurrentPassword : function ( e ) {
this . setState ( { current _password : e . target . value } ) ;
} ,
updateNewPassword : function ( e ) {
this . setState ( { new _password : e . target . value } ) ;
} ,
updateConfirmPassword : function ( e ) {
this . setState ( { confirm _password : e . target . value } ) ;
} ,
2015-07-01 18:40:20 -07:00
handleHistoryOpen : function ( ) {
$ ( "#user_settings1" ) . modal ( 'hide' ) ;
} ,
handleDevicesOpen : function ( ) {
$ ( "#user_settings1" ) . modal ( 'hide' ) ;
} ,
2015-07-17 14:44:13 -07:00
handleClose : function ( ) {
2015-07-23 09:20:37 -07:00
$ ( this . getDOMNode ( ) ) . find ( ".form-control" ) . each ( function ( ) {
this . value = "" ;
} ) ;
this . setState ( { current _password : '' , new _password : '' , confirm _password : '' , server _error : null , password _error : null } ) ;
2015-07-17 14:44:13 -07:00
} ,
componentDidMount : function ( ) {
$ ( '#user_settings1' ) . on ( 'hidden.bs.modal' , this . handleClose ) ;
} ,
componentWillUnmount : function ( ) {
$ ( '#user_settings1' ) . off ( 'hidden.bs.modal' , this . handleClose ) ;
} ,
2015-06-14 23:53:32 -08:00
getInitialState : function ( ) {
return { current _password : '' , new _password : '' , confirm _password : '' } ;
} ,
render : function ( ) {
var server _error = this . state . server _error ? this . state . server _error : null ;
var password _error = this . state . password _error ? this . state . password _error : null ;
var passwordSection ;
var self = this ;
if ( this . props . activeSection === 'password' ) {
var inputs = [ ] ;
2015-07-15 17:50:07 -04:00
var submit = null ;
2015-06-14 23:53:32 -08:00
2015-07-15 17:50:07 -04:00
if ( this . props . user . auth _service === "" ) {
inputs . push (
< div className = "form-group" >
< label className = "col-sm-5 control-label" > Current Password < / label >
< div className = "col-sm-7" >
< input className = "form-control" type = "password" onChange = { this . updateCurrentPassword } value = { this . state . current _password } / >
< / div >
2015-06-14 23:53:32 -08:00
< / div >
2015-07-15 17:50:07 -04:00
) ;
inputs . push (
< div className = "form-group" >
< label className = "col-sm-5 control-label" > New Password < / label >
< div className = "col-sm-7" >
< input className = "form-control" type = "password" onChange = { this . updateNewPassword } value = { this . state . new _password } / >
< / div >
2015-06-14 23:53:32 -08:00
< / div >
2015-07-15 17:50:07 -04:00
) ;
inputs . push (
< div className = "form-group" >
< label className = "col-sm-5 control-label" > Retype New Password < / label >
< div className = "col-sm-7" >
< input className = "form-control" type = "password" onChange = { this . updateConfirmPassword } value = { this . state . confirm _password } / >
< / div >
2015-06-14 23:53:32 -08:00
< / div >
2015-07-15 17:50:07 -04:00
) ;
submit = this . submitPassword ;
} else {
inputs . push (
< div className = "form-group" >
< label className = "col-sm-12" > Log in occurs through GitLab . Please see your GitLab account settings page to update your password . < / label >
< / div >
) ;
}
2015-06-14 23:53:32 -08:00
passwordSection = (
< SettingItemMax
title = "Password"
inputs = { inputs }
2015-07-15 17:50:07 -04:00
submit = { submit }
2015-06-14 23:53:32 -08:00
server _error = { server _error }
client _error = { password _error }
updateSection = { function ( e ) { self . props . updateSection ( "" ) ; e . preventDefault ( ) ; } }
/ >
) ;
} else {
2015-07-15 17:50:07 -04:00
var describe ;
if ( this . props . user . auth _service === "" ) {
var d = new Date ( this . props . user . last _password _update ) ;
var hour = d . getHours ( ) % 12 ? String ( d . getHours ( ) % 12 ) : "12" ;
var min = d . getMinutes ( ) < 10 ? "0" + d . getMinutes ( ) : String ( d . getMinutes ( ) ) ;
var timeOfDay = d . getHours ( ) >= 12 ? " pm" : " am" ;
describe = "Last updated " + Constants . MONTHS [ d . getMonth ( ) ] + " " + d . getDate ( ) + ", " + d . getFullYear ( ) + " at " + hour + ":" + min + timeOfDay ;
} else {
describe = "Log in done through GitLab"
}
2015-06-14 23:53:32 -08:00
passwordSection = (
< SettingItemMin
title = "Password"
2015-07-15 17:50:07 -04:00
describe = { describe }
2015-06-14 23:53:32 -08:00
updateSection = { function ( ) { self . props . updateSection ( "password" ) ; } }
/ >
) ;
}
return (
< div >
< div className = "modal-header" >
< button type = "button" className = "close" data - dismiss = "modal" aria - label = "Close" > < span aria - hidden = "true" > & times ; < / span > < / button >
< h4 className = "modal-title" ref = "title" > < i className = "modal-back" > < / i > Security Settings < / h4 >
< / div >
< div className = "user-settings" >
< h3 className = "tab-header" > Security Settings < / h3 >
< div className = "divider-dark first" / >
{ passwordSection }
< div className = "divider-dark" / >
2015-07-01 18:40:20 -07:00
< br > < / br >
2015-07-23 00:54:40 +05:00
< a data - toggle = "modal" className = "security-links theme" data - target = "#access-history" href = "#" onClick = { this . handleHistoryOpen } > < i className = "fa fa-clock-o" > < / i > View Access History < / a >
2015-07-01 18:40:20 -07:00
< b > < / b >
2015-07-27 17:13:53 -07:00
< a data - toggle = "modal" className = "security-links theme" data - target = "#activity-log" href = "#" onClick = { this . handleDevicesOpen } > < i className = "fa fa-globe" > < / i > View and Logout of Active Sessions < / a >
2015-06-14 23:53:32 -08:00
< / div >
< / div >
) ;
}
} ) ;
var GeneralTab = React . createClass ( {
submitActive : false ,
submitUsername : function ( e ) {
e . preventDefault ( ) ;
var user = this . props . user ;
var username = this . state . username . trim ( ) ;
var username _error = utils . isValidUsername ( username ) ;
if ( username _error === "Cannot use a reserved word as a username." ) {
this . setState ( { client _error : "This username is reserved, please choose a new one." } ) ;
return ;
} else if ( username _error ) {
this . setState ( { client _error : "Username must begin with a letter, and contain between 3 to 15 lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'." } ) ;
return ;
}
if ( user . username === username ) {
this . setState ( { client _error : "You must submit a new username" } ) ;
return ;
}
user . username = username ;
this . submitUser ( user ) ;
} ,
2015-07-09 17:20:18 -04:00
submitNickname : function ( e ) {
e . preventDefault ( ) ;
var user = UserStore . getCurrentUser ( ) ;
var nickname = this . state . nickname . trim ( ) ;
if ( user . nickname === nickname ) {
this . setState ( { client _error : "You must submit a new nickname" } )
return ;
}
user . nickname = nickname ;
this . submitUser ( user ) ;
} ,
2015-06-14 23:53:32 -08:00
submitName : function ( e ) {
e . preventDefault ( ) ;
var user = UserStore . getCurrentUser ( ) ;
var firstName = this . state . first _name . trim ( ) ;
var lastName = this . state . last _name . trim ( ) ;
2015-07-10 15:51:45 -04:00
if ( user . first _name === firstName && user . last _name === lastName ) {
this . setState ( { client _error : "You must submit a new first or last name" } )
2015-06-14 23:53:32 -08:00
return ;
}
2015-07-10 15:51:45 -04:00
user . first _name = firstName ;
user . last _name = lastName ;
2015-06-14 23:53:32 -08:00
this . submitUser ( user ) ;
} ,
submitEmail : function ( e ) {
e . preventDefault ( ) ;
var user = UserStore . getCurrentUser ( ) ;
var email = this . state . email . trim ( ) . toLowerCase ( ) ;
if ( user . email === email ) {
return ;
}
if ( email === '' || ! utils . isEmail ( email ) ) {
this . setState ( { email _error : "Please enter a valid email address" } ) ;
return ;
}
user . email = email ;
this . submitUser ( user ) ;
} ,
submitUser : function ( user ) {
client . updateUser ( user ,
function ( data ) {
this . updateSection ( "" ) ;
AsyncClient . getMe ( ) ;
} . bind ( this ) ,
function ( err ) {
state = this . getInitialState ( ) ;
state . server _error = err ;
this . setState ( state ) ;
} . bind ( this )
) ;
} ,
submitPicture : function ( e ) {
e . preventDefault ( ) ;
if ( ! this . state . picture ) return ;
if ( ! this . submitActive ) return ;
2015-07-23 11:37:59 -07:00
var picture = this . state . picture ;
if ( picture . type !== "image/jpeg" && picture . type !== "image/png" ) {
this . setState ( { client _error : "Only JPG or PNG images may be used for profile pictures" } ) ;
2015-07-01 16:04:18 -07:00
return ;
}
2015-06-14 23:53:32 -08:00
formData = new FormData ( ) ;
2015-07-23 11:37:59 -07:00
formData . append ( 'image' , picture , picture . name ) ;
2015-06-14 23:53:32 -08:00
client . uploadProfileImage ( formData ,
function ( data ) {
this . submitActive = false ;
2015-07-16 08:55:37 -07:00
AsyncClient . getMe ( ) ;
2015-06-14 23:53:32 -08:00
window . location . reload ( ) ;
} . bind ( this ) ,
function ( err ) {
state = this . getInitialState ( ) ;
state . server _error = err ;
this . setState ( state ) ;
} . bind ( this )
) ;
} ,
updateUsername : function ( e ) {
this . setState ( { username : e . target . value } ) ;
} ,
updateFirstName : function ( e ) {
this . setState ( { first _name : e . target . value } ) ;
} ,
updateLastName : function ( e ) {
this . setState ( { last _name : e . target . value } ) ;
} ,
2015-07-09 17:20:18 -04:00
updateNickname : function ( e ) {
this . setState ( { nickname : e . target . value } ) ;
} ,
2015-06-14 23:53:32 -08:00
updateEmail : function ( e ) {
this . setState ( { email : e . target . value } ) ;
} ,
updatePicture : function ( e ) {
if ( e . target . files && e . target . files [ 0 ] ) {
this . setState ( { picture : e . target . files [ 0 ] } ) ;
2015-07-01 17:04:10 -07:00
this . submitActive = true ;
this . setState ( { client _error : null } )
2015-06-14 23:53:32 -08:00
} else {
this . setState ( { picture : null } ) ;
}
} ,
updateSection : function ( section ) {
this . setState ( { client _error : "" } )
this . submitActive = false
this . props . updateSection ( section ) ;
} ,
2015-07-17 14:44:13 -07:00
handleClose : function ( ) {
2015-07-23 09:20:37 -07:00
$ ( this . getDOMNode ( ) ) . find ( ".form-control" ) . each ( function ( ) {
this . value = "" ;
} ) ;
this . setState ( assign ( { } , this . getInitialState ( ) , { client _error : null , server _error : null , email _error : null } ) ) ;
2015-07-17 14:44:13 -07:00
} ,
componentDidMount : function ( ) {
$ ( '#user_settings1' ) . on ( 'hidden.bs.modal' , this . handleClose ) ;
} ,
componentWillUnmount : function ( ) {
$ ( '#user_settings1' ) . off ( 'hidden.bs.modal' , this . handleClose ) ;
} ,
2015-06-14 23:53:32 -08:00
getInitialState : function ( ) {
var user = this . props . user ;
2015-07-10 15:51:45 -04:00
return { username : user . username , first _name : user . first _name , last _name : user . last _name , nickname : user . nickname ,
2015-06-14 23:53:32 -08:00
email : user . email , picture : null } ;
} ,
render : function ( ) {
var user = this . props . user ;
var client _error = this . state . client _error ? this . state . client _error : null ;
var server _error = this . state . server _error ? this . state . server _error : null ;
var email _error = this . state . email _error ? this . state . email _error : null ;
var nameSection ;
var self = this ;
if ( this . props . activeSection === 'name' ) {
var inputs = [ ] ;
inputs . push (
2015-06-28 04:18:24 +05:00
< div className = "form-group" >
2015-06-14 23:53:32 -08:00
< label className = "col-sm-5 control-label" > First Name < / label >
< div className = "col-sm-7" >
< input className = "form-control" type = "text" onChange = { this . updateFirstName } value = { this . state . first _name } / >
< / div >
< / div >
) ;
inputs . push (
2015-06-28 04:18:24 +05:00
< div className = "form-group" >
2015-06-14 23:53:32 -08:00
< label className = "col-sm-5 control-label" > Last Name < / label >
< div className = "col-sm-7" >
< input className = "form-control" type = "text" onChange = { this . updateLastName } value = { this . state . last _name } / >
< / div >
< / div >
) ;
nameSection = (
< SettingItemMax
2015-07-10 15:51:45 -04:00
title = "Full Name"
2015-06-14 23:53:32 -08:00
inputs = { inputs }
submit = { this . submitName }
server _error = { server _error }
client _error = { client _error }
updateSection = { function ( e ) { self . updateSection ( "" ) ; e . preventDefault ( ) ; } }
/ >
) ;
} else {
2015-07-10 15:51:45 -04:00
var full _name = "" ;
if ( user . first _name && user . last _name ) {
full _name = user . first _name + " " + user . last _name ;
} else if ( user . first _name ) {
full _name = user . first _name ;
} else if ( user . last _name ) {
full _name = user . last _name ;
}
2015-06-14 23:53:32 -08:00
nameSection = (
< SettingItemMin
2015-07-10 15:51:45 -04:00
title = "Full Name"
describe = { full _name }
2015-06-14 23:53:32 -08:00
updateSection = { function ( ) { self . updateSection ( "name" ) ; } }
/ >
) ;
}
2015-07-09 17:20:18 -04:00
var nicknameSection ;
if ( this . props . activeSection === 'nickname' ) {
var inputs = [ ] ;
inputs . push (
< div className = "form-group" >
< label className = "col-sm-5 control-label" > { utils . isMobile ( ) ? "" : "Nickname" } < / label >
< div className = "col-sm-7" >
< input className = "form-control" type = "text" onChange = { this . updateNickname } value = { this . state . nickname } / >
< / div >
< / div >
) ;
nicknameSection = (
< SettingItemMax
title = "Nickname"
inputs = { inputs }
submit = { this . submitNickname }
server _error = { server _error }
client _error = { client _error }
updateSection = { function ( e ) { self . updateSection ( "" ) ; e . preventDefault ( ) ; } }
/ >
) ;
} else {
nicknameSection = (
< SettingItemMin
title = "Nickname"
describe = { UserStore . getCurrentUser ( ) . nickname }
updateSection = { function ( ) { self . updateSection ( "nickname" ) ; } }
/ >
) ;
}
2015-06-14 23:53:32 -08:00
var usernameSection ;
if ( this . props . activeSection === 'username' ) {
var inputs = [ ] ;
inputs . push (
2015-06-28 04:18:24 +05:00
< div className = "form-group" >
2015-06-14 23:53:32 -08:00
< label className = "col-sm-5 control-label" > { utils . isMobile ( ) ? "" : "Username" } < / label >
< div className = "col-sm-7" >
< input className = "form-control" type = "text" onChange = { this . updateUsername } value = { this . state . username } / >
< / div >
< / div >
) ;
usernameSection = (
< SettingItemMax
title = "Username"
inputs = { inputs }
submit = { this . submitUsername }
server _error = { server _error }
client _error = { client _error }
updateSection = { function ( e ) { self . updateSection ( "" ) ; e . preventDefault ( ) ; } }
/ >
) ;
} else {
usernameSection = (
< SettingItemMin
title = "Username"
describe = { UserStore . getCurrentUser ( ) . username }
updateSection = { function ( ) { self . updateSection ( "username" ) ; } }
/ >
) ;
}
var emailSection ;
if ( this . props . activeSection === 'email' ) {
var inputs = [ ] ;
inputs . push (
2015-06-28 04:18:24 +05:00
< div className = "form-group" >
2015-06-14 23:53:32 -08:00
< label className = "col-sm-5 control-label" > Primary Email < / label >
< div className = "col-sm-7" >
< input className = "form-control" type = "text" onChange = { this . updateEmail } value = { this . state . email } / >
< / div >
< / div >
) ;
emailSection = (
< SettingItemMax
title = "Email"
inputs = { inputs }
submit = { this . submitEmail }
server _error = { server _error }
client _error = { email _error }
updateSection = { function ( e ) { self . updateSection ( "" ) ; e . preventDefault ( ) ; } }
/ >
) ;
} else {
emailSection = (
< SettingItemMin
title = "Email"
describe = { UserStore . getCurrentUser ( ) . email }
updateSection = { function ( ) { self . updateSection ( "email" ) ; } }
/ >
) ;
}
var pictureSection ;
if ( this . props . activeSection === 'picture' ) {
pictureSection = (
< SettingPicture
title = "Profile Picture"
submit = { this . submitPicture }
2015-07-16 08:55:37 -07:00
src = { "/api/v1/users/" + user . id + "/image?time=" + user . last _picture _update }
2015-06-14 23:53:32 -08:00
server _error = { server _error }
2015-07-01 16:04:18 -07:00
client _error = { client _error }
2015-06-14 23:53:32 -08:00
updateSection = { function ( e ) { self . updateSection ( "" ) ; e . preventDefault ( ) ; } }
picture = { this . state . picture }
pictureChange = { this . updatePicture }
submitActive = { this . submitActive }
/ >
) ;
} else {
2015-07-16 08:55:37 -07:00
var minMessage = "Click Edit to upload an image." ;
if ( user . last _picture _update ) {
minMessage = "Image last updated " + utils . displayDate ( user . last _picture _update )
}
2015-06-14 23:53:32 -08:00
pictureSection = (
< SettingItemMin
title = "Profile Picture"
2015-07-16 08:55:37 -07:00
describe = { minMessage }
2015-06-14 23:53:32 -08:00
updateSection = { function ( ) { self . updateSection ( "picture" ) ; } }
/ >
) ;
}
return (
< div >
< div className = "modal-header" >
< button type = "button" className = "close" data - dismiss = "modal" aria - label = "Close" > < span aria - hidden = "true" > & times ; < / span > < / button >
< h4 className = "modal-title" ref = "title" > < i className = "modal-back" > < / i > General Settings < / h4 >
< / div >
< div className = "user-settings" >
< h3 className = "tab-header" > General Settings < / h3 >
< div className = "divider-dark first" / >
{ nameSection }
< div className = "divider-light" / >
{ usernameSection }
< div className = "divider-light" / >
2015-07-09 17:20:18 -04:00
{ nicknameSection }
< div className = "divider-light" / >
2015-06-14 23:53:32 -08:00
{ emailSection }
< div className = "divider-light" / >
{ pictureSection }
< div className = "divider-dark" / >
< / div >
< / div >
) ;
}
} ) ;
var AppearanceTab = React . createClass ( {
submitTheme : function ( e ) {
e . preventDefault ( ) ;
var user = UserStore . getCurrentUser ( ) ;
if ( ! user . props ) user . props = { } ;
user . props . theme = this . state . theme ;
client . updateUser ( user ,
function ( data ) {
this . props . updateSection ( "" ) ;
window . location . reload ( ) ;
} . bind ( this ) ,
function ( err ) {
state = this . getInitialState ( ) ;
state . server _error = err ;
this . setState ( state ) ;
} . bind ( this )
) ;
} ,
updateTheme : function ( e ) {
var hex = utils . rgb2hex ( e . target . style . backgroundColor ) ;
this . setState ( { theme : hex . toLowerCase ( ) } ) ;
} ,
2015-07-17 14:44:13 -07:00
handleClose : function ( ) {
2015-07-23 09:20:37 -07:00
this . setState ( { server _error : null } ) ;
2015-07-17 14:44:13 -07:00
} ,
2015-06-14 23:53:32 -08:00
componentDidMount : function ( ) {
if ( this . props . activeSection === "theme" ) {
$ ( this . refs [ this . state . theme ] . getDOMNode ( ) ) . addClass ( 'active-border' ) ;
}
2015-07-17 14:44:13 -07:00
$ ( '#user_settings1' ) . on ( 'hidden.bs.modal' , this . handleClose ) ;
2015-06-14 23:53:32 -08:00
} ,
componentDidUpdate : function ( ) {
if ( this . props . activeSection === "theme" ) {
$ ( '.color-btn' ) . removeClass ( 'active-border' ) ;
$ ( this . refs [ this . state . theme ] . getDOMNode ( ) ) . addClass ( 'active-border' ) ;
}
} ,
2015-07-17 14:44:13 -07:00
componentWillUnmount : function ( ) {
$ ( '#user_settings1' ) . off ( 'hidden.bs.modal' , this . handleClose ) ;
} ,
2015-06-14 23:53:32 -08:00
getInitialState : function ( ) {
var user = UserStore . getCurrentUser ( ) ;
var theme = config . ThemeColors != null ? config . ThemeColors [ 0 ] : "#2389d7" ;
if ( user . props && user . props . theme ) {
theme = user . props . theme ;
}
return { theme : theme . toLowerCase ( ) } ;
} ,
render : function ( ) {
var server _error = this . state . server _error ? this . state . server _error : null ;
var themeSection ;
var self = this ;
if ( config . ThemeColors != null ) {
if ( this . props . activeSection === 'theme' ) {
var theme _buttons = [ ] ;
for ( var i = 0 ; i < config . ThemeColors . length ; i ++ ) {
theme _buttons . push ( < button ref = { config . ThemeColors [ i ] } type = "button" className = "btn btn-lg color-btn" style = { { backgroundColor : config . ThemeColors [ i ] } } onClick = { this . updateTheme } / > ) ;
}
var inputs = [ ] ;
inputs . push (
2015-06-28 04:18:24 +05:00
< li className = "setting-list-item" >
2015-06-14 23:53:32 -08:00
< div className = "btn-group" data - toggle = "buttons-radio" >
{ theme _buttons }
< / div >
< / li >
) ;
themeSection = (
< SettingItemMax
2015-06-18 08:38:07 -07:00
title = "Theme Color"
2015-06-14 23:53:32 -08:00
inputs = { inputs }
submit = { this . submitTheme }
server _error = { server _error }
updateSection = { function ( e ) { self . props . updateSection ( "" ) ; e . preventDefault ; } }
/ >
) ;
} else {
themeSection = (
< SettingItemMin
2015-06-18 08:38:07 -07:00
title = "Theme Color"
2015-06-14 23:53:32 -08:00
describe = { this . state . theme }
updateSection = { function ( ) { self . props . updateSection ( "theme" ) ; } }
/ >
) ;
}
}
return (
< div >
< div className = "modal-header" >
< button type = "button" className = "close" data - dismiss = "modal" aria - label = "Close" > < span aria - hidden = "true" > & times ; < / span > < / button >
< h4 className = "modal-title" ref = "title" > < i className = "modal-back" > < / i > Appearance Settings < / h4 >
< / div >
< div className = "user-settings" >
< h3 className = "tab-header" > Appearance Settings < / h3 >
< div className = "divider-dark first" / >
{ themeSection }
< div className = "divider-dark" / >
< / div >
< / div >
) ;
}
} ) ;
module . exports = React . createClass ( {
componentDidMount : function ( ) {
UserStore . addChangeListener ( this . _onChange ) ;
} ,
componentWillUnmount : function ( ) {
UserStore . removeChangeListener ( this . _onChange ) ;
} ,
_onChange : function ( ) {
var user = UserStore . getCurrentUser ( ) ;
if ( ! utils . areStatesEqual ( this . state . user , user ) ) {
this . setState ( { user : user } ) ;
}
} ,
getInitialState : function ( ) {
return { user : UserStore . getCurrentUser ( ) } ;
} ,
render : function ( ) {
if ( this . props . activeTab === 'general' ) {
return (
< div >
< GeneralTab user = { this . state . user } activeSection = { this . props . activeSection } updateSection = { this . props . updateSection } / >
< / div >
) ;
} else if ( this . props . activeTab === 'security' ) {
return (
< div >
< SecurityTab user = { this . state . user } activeSection = { this . props . activeSection } updateSection = { this . props . updateSection } / >
< / div >
) ;
} else if ( this . props . activeTab === 'notifications' ) {
return (
< div >
< NotificationsTab user = { this . state . user } activeSection = { this . props . activeSection } updateSection = { this . props . updateSection } / >
< / div >
) ;
} else if ( this . props . activeTab === 'appearance' ) {
return (
< div >
< AppearanceTab activeSection = { this . props . activeSection } updateSection = { this . props . updateSection } / >
< / div >
) ;
} else {
return < div / > ;
}
}
} ) ;