codecombat/app/views/account/AccountSettingsView.coffee

220 lines
7.5 KiB
CoffeeScript
Raw Normal View History

CocoView = require 'views/core/CocoView'
template = require 'templates/account/account-settings-view'
{me} = require 'core/auth'
forms = require 'core/forms'
2014-06-30 22:16:26 -04:00
User = require 'models/User'
AuthModal = require 'views/core/AuthModal'
2015-02-19 16:14:34 -05:00
ConfirmModal = require 'views/editor/modal/ConfirmModal'
{logoutUser, me} = require('core/auth')
2014-01-03 13:32:13 -05:00
module.exports = class AccountSettingsView extends CocoView
id: 'account-settings-view'
2014-01-03 13:32:13 -05:00
template: template
className: 'countainer-fluid'
2014-01-03 13:32:13 -05:00
events:
'change .panel input': 'onInputChanged'
'change #name': 'checkNameExists'
2014-01-03 13:32:13 -05:00
'click #toggle-all-button': 'toggleEmailSubscriptions'
'click .profile-photo': 'onEditProfilePhoto'
'click #upload-photo-button': 'onEditProfilePhoto'
2015-02-19 16:14:34 -05:00
'click #delete-account-button': 'confirmAccountDeletion'
2014-01-03 13:32:13 -05:00
constructor: (options) ->
super options
require('core/services/filepicker')() unless window.application.isIPadApp # Initialize if needed
@uploadFilePath = "db/user/#{me.id}"
afterInsert: ->
super()
@openModalView new AuthModal() if me.get('anonymous')
getRenderData: ->
c = super()
return c unless me
c.subs = {}
c.subs[sub] = 1 for sub in me.getEnabledEmails()
c
#- Form input callbacks
onInputChanged: (e) ->
$(e.target).addClass 'changed'
2015-02-19 16:14:34 -05:00
if (JSON.stringify(document.getElementById('email1').className)).indexOf("changed") > -1
$(e.target).removeClass 'changed'
else
@trigger 'input-changed'
toggleEmailSubscriptions: =>
subs = @getSubscriptions()
$('#email-panel input[type="checkbox"]', @$el).prop('checked', not _.any(_.values(subs))).addClass('changed')
checkNameExists: =>
name = $('#name', @$el).val()
return if name is me.get 'name'
User.getUnconflictedName name, (newName) =>
forms.clearFormAlerts(@$el)
if name is newName
@suggestedName = undefined
else
@suggestedName = newName
forms.setErrorToProperty @$el, 'name', "That name is taken! How about #{newName}?", true
2014-01-03 13:32:13 -05:00
onPictureChanged: (e) =>
@trigger 'inputChanged', e
@$el.find('.gravatar-fallback').toggle not me.get 'photoURL'
2014-01-03 13:32:13 -05:00
#- Just copied from OptionsView, TODO refactor
2015-02-19 16:14:34 -05:00
confirmAccountDeletion: ->
forms.clearFormAlerts(@$el)
myEmail = me.get 'email'
email1 = document.getElementById('email1').value
if Boolean(email1) and email1 is myEmail
renderData =
'confirmTitle': 'Are you really sure?'
'confirmBody': 'This will completely delete your account. This action CANNOT be undone. Are you entirely sure?'
'confirmDecline': 'Not really'
'confirmConfirm': 'Definitely'
confirmModal = new ConfirmModal renderData
confirmModal.on 'confirm', @deleteAccount
@openModalView confirmModal
else
message = $.i18n.t('account_settings.wrong_email', defaultValue: 'Wrong Email.')
err = [message: message, property: 'email1', formatted: true]
forms.applyErrorsToForm(@$el, err)
$('.nano').nanoScroller({scrollTo: @$el.find('.has-error')})
deleteAccount: ->
myID = me.id
$.ajax
type: 'DELETE'
success: ->
noty
timeout: 5000
text: 'Your account is gone.'
type: 'success'
layout: 'topCenter'
_.delay ->
Backbone.Mediator.publish("auth:logging-out", {})
window.tracker?.trackEvent 'Log Out', category:'Homepage', ['Google Analytics'] if @id is 'home-view'
logoutUser($('#login-email').val())
, 500
error: (jqXHR, status, error) ->
console.error jqXHR
timeout: 5000
text: "Deleting account failed with error code #{jqXHR.status}"
type: 'error'
layout: 'topCenter'
url: "/db/user/#{myID}"
onEditProfilePhoto: (e) ->
return if window.application.isIPadApp # TODO: have an iPad-native way of uploading a photo, since we don't want to load FilePicker on iPad (memory)
photoContainer = @$el.find('.profile-photo')
onSaving = =>
photoContainer.addClass('saving')
onSaved = (uploadingPath) =>
@$el.find('#photoURL').val(uploadingPath)
@$el.find('#photoURL').trigger('change') # cause for some reason editing the value doesn't trigger the jquery event
me.set('photoURL', uploadingPath)
photoContainer.removeClass('saving').attr('src', me.getPhotoURL(photoContainer.width()))
filepicker.pick {mimetypes: 'image/*'}, @onImageChosen(onSaving, onSaved)
formatImagePostData: (inkBlob) ->
url: inkBlob.url, filename: inkBlob.filename, mimetype: inkBlob.mimetype, path: @uploadFilePath, force: true
onImageChosen: (onSaving, onSaved) ->
(inkBlob) =>
onSaving()
uploadingPath = [@uploadFilePath, inkBlob.filename].join('/')
data = @formatImagePostData(inkBlob)
success = @onImageUploaded(onSaved, uploadingPath)
$.ajax '/file', type: 'POST', data: data, success: success
onImageUploaded: (onSaved, uploadingPath) ->
(e) =>
onSaved uploadingPath
#- Misc
2014-01-03 13:32:13 -05:00
getSubscriptions: ->
inputs = ($(i) for i in $('#email-panel input[type="checkbox"].changed', @$el))
emailNames = (i.attr('name').replace('email_', '') for i in inputs)
enableds = (i.prop('checked') for i in inputs)
_.zipObject emailNames, enableds
2014-01-03 13:32:13 -05:00
#- Saving changes
save: ->
$('#settings-tabs input').removeClass 'changed'
2014-01-03 13:32:13 -05:00
forms.clearFormAlerts(@$el)
@grabData()
res = me.validate()
if res?
2014-06-30 22:16:26 -04:00
console.error 'Couldn\'t save because of validation errors:', res
2014-01-03 13:32:13 -05:00
forms.applyErrorsToForm(@$el, res)
$('.nano').nanoScroller({scrollTo: @$el.find('.has-error')})
2014-01-03 13:32:13 -05:00
return
2014-03-10 16:20:00 -04:00
return unless me.hasLocalChanges()
2014-01-03 13:32:13 -05:00
res = me.patch()
2014-01-03 13:32:13 -05:00
return unless res
res.error =>
2014-01-03 13:32:13 -05:00
errors = JSON.parse(res.responseText)
forms.applyErrorsToForm(@$el, errors)
$('.nano').nanoScroller({scrollTo: @$el.find('.has-error')})
@trigger 'save-user-error'
res.success (model, response, options) =>
@trigger 'save-user-success'
@trigger 'save-user-began'
2014-01-03 13:32:13 -05:00
grabData: ->
@grabPasswordData()
@grabOtherData()
grabPasswordData: ->
password1 = $('#password', @$el).val()
password2 = $('#password2', @$el).val()
bothThere = Boolean(password1) and Boolean(password2)
if bothThere and password1 isnt password2
message = $.i18n.t('account_settings.password_mismatch', defaultValue: 'Password does not match.')
2014-06-30 22:16:26 -04:00
err = [message: message, property: 'password2', formatted: true]
2014-01-03 13:32:13 -05:00
forms.applyErrorsToForm(@$el, err)
$('.nano').nanoScroller({scrollTo: @$el.find('.has-error')})
2014-01-03 13:32:13 -05:00
return
if bothThere
me.set('password', password1)
else if password1
message = $.i18n.t('account_settings.password_repeat', defaultValue: 'Please repeat your password.')
err = [message: message, property: 'password2', formatted: true]
forms.applyErrorsToForm(@$el, err)
$('.nano').nanoScroller({scrollTo: @$el.find('.has-error')})
2014-01-03 13:32:13 -05:00
grabOtherData: ->
@$el.find('#name').val @suggestedName if @suggestedName
me.set 'name', @$el.find('#name').val()
me.set 'email', @$el.find('#email').val()
for emailName, enabled of @getSubscriptions()
me.setEmailSubscription emailName, enabled
me.set('photoURL', @$el.find('#photoURL').val())
permissions = []
adminCheckbox = @$el.find('#admin')
if adminCheckbox.length
permissions.push 'admin' if adminCheckbox.prop('checked')
godmodeCheckbox = @$el.find('#godmode')
if godmodeCheckbox.length
permissions.push 'godmode' if godmodeCheckbox.prop('checked')
me.set('permissions', permissions)