2014-07-17 20:16:32 -04:00
|
|
|
RootView = require 'views/kinds/RootView'
|
2014-11-25 13:19:38 -05:00
|
|
|
template = require 'templates/account/account-settings-view'
|
2014-06-30 22:16:26 -04:00
|
|
|
{me} = require 'lib/auth'
|
|
|
|
forms = require 'lib/forms'
|
|
|
|
User = require 'models/User'
|
2014-07-23 10:02:45 -04:00
|
|
|
AuthModal = require 'views/modal/AuthModal'
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-07-23 10:02:45 -04:00
|
|
|
module.exports = class AccountSettingsView extends RootView
|
2014-01-03 17:28:00 -05:00
|
|
|
id: 'account-settings-view'
|
2014-01-03 13:32:13 -05:00
|
|
|
template: template
|
2014-07-10 14:50:16 -04:00
|
|
|
changedFields: [] # DOM input fields
|
2014-01-03 13:32:13 -05:00
|
|
|
|
|
|
|
events:
|
2014-11-25 13:19:38 -05:00
|
|
|
'change .panel input': 'onInputChanged'
|
|
|
|
'change #name': 'checkNameExists'
|
2014-01-03 13:32:13 -05:00
|
|
|
'click #toggle-all-button': 'toggleEmailSubscriptions'
|
2014-11-25 13:19:38 -05:00
|
|
|
'click .profile-photo': 'onEditProfilePhoto'
|
|
|
|
'click #save-button': 'save'
|
|
|
|
'click #upload-photo-button': 'onEditProfilePhoto'
|
|
|
|
|
|
|
|
shortcuts:
|
|
|
|
'enter': 'save'
|
2014-01-03 13:32:13 -05:00
|
|
|
|
|
|
|
constructor: (options) ->
|
|
|
|
super options
|
2014-11-25 13:19:38 -05:00
|
|
|
require('lib/services/filepicker')() unless window.application.isIPadApp # Initialize if needed
|
|
|
|
@uploadFilePath = "db/user/#{me.id}"
|
2014-07-10 14:50:16 -04:00
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
afterInsert: ->
|
|
|
|
super()
|
|
|
|
@openModalView new AuthModal() if me.get('anonymous')
|
2014-07-10 14:50:16 -04:00
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
getRenderData: ->
|
|
|
|
c = super()
|
|
|
|
return c unless me
|
|
|
|
c.subs = {}
|
|
|
|
c.subs[sub] = 1 for sub in me.getEnabledEmails()
|
|
|
|
c
|
2014-07-10 14:50:16 -04:00
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
|
|
|
|
#- Form input callbacks
|
|
|
|
|
|
|
|
onInputChanged: (e) ->
|
|
|
|
$(e.target).addClass 'changed'
|
|
|
|
return @enableSaveButton()
|
2014-07-10 14:50:16 -04:00
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
toggleEmailSubscriptions: =>
|
|
|
|
subs = @getSubscriptions()
|
|
|
|
$('#email-panel input[type="checkbox"]', @$el).prop('checked', not _.any(_.values(subs))).addClass('changed')
|
|
|
|
@save()
|
2014-07-10 14:50:16 -04:00
|
|
|
|
|
|
|
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
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
onPictureChanged: (e) =>
|
|
|
|
@trigger 'inputChanged', e
|
|
|
|
@$el.find('.gravatar-fallback').toggle not me.get 'photoURL'
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
|
|
|
|
#- Just copied from OptionsView, TODO refactor
|
|
|
|
|
|
|
|
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)
|
|
|
|
@onInputChanged() # 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
|
|
|
|
|
|
|
|
|
|
|
|
#- Save button enable/disable
|
2014-04-05 20:05:03 -04:00
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
enableSaveButton: ->
|
|
|
|
$('#save-button', @$el)
|
|
|
|
.addClass 'btn-info'
|
|
|
|
.removeClass 'disabled btn-danger'
|
|
|
|
.removeAttr 'disabled'
|
|
|
|
.text 'Save'
|
2014-04-05 20:05:03 -04:00
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
disableSaveButton: ->
|
|
|
|
$('#save-button', @$el)
|
|
|
|
.addClass 'disabled'
|
|
|
|
.removeClass 'btn-danger btn-info'
|
|
|
|
.attr 'disabled', "true"
|
|
|
|
.text 'No Changes'
|
2014-04-09 19:46:44 -04:00
|
|
|
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
#- Misc
|
2014-01-03 13:32:13 -05:00
|
|
|
|
|
|
|
getSubscriptions: ->
|
2014-11-25 13:19:38 -05:00
|
|
|
inputs = ($(i) for i in $('#email-panel input[type="checkbox"].changed', @$el))
|
2014-04-21 19:15:23 -04:00
|
|
|
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
|
|
|
|
2014-11-25 13:19:38 -05:00
|
|
|
|
|
|
|
#- Saving changes
|
|
|
|
|
2014-04-21 19:15:23 -04:00
|
|
|
save: (e) ->
|
2014-07-16 08:39:48 -04:00
|
|
|
$('#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)
|
2014-11-25 13:19:38 -05:00
|
|
|
$('.nano').nanoScroller({scrollTo: @$el.find('.has-error')})
|
2014-01-03 13:32:13 -05:00
|
|
|
return
|
2014-03-10 16:20:00 -04:00
|
|
|
|
2014-02-27 15:02:08 -05:00
|
|
|
return unless me.hasLocalChanges()
|
2014-01-03 13:32:13 -05:00
|
|
|
|
2014-06-10 23:43:25 -04:00
|
|
|
res = me.patch()
|
2014-01-03 13:32:13 -05:00
|
|
|
return unless res
|
2014-01-19 11:00:41 -05:00
|
|
|
save = $('#save-button', @$el).text($.i18n.t('common.saving', defaultValue: 'Saving...'))
|
2014-04-10 14:58:51 -04:00
|
|
|
.removeClass('btn-danger').addClass('btn-success').show()
|
2014-01-03 13:32:13 -05:00
|
|
|
|
|
|
|
res.error ->
|
|
|
|
errors = JSON.parse(res.responseText)
|
|
|
|
forms.applyErrorsToForm(@$el, errors)
|
2014-11-25 13:19:38 -05:00
|
|
|
$('.nano').nanoScroller({scrollTo: @$el.find('.has-error')})
|
2014-04-10 14:58:51 -04:00
|
|
|
save.text($.i18n.t('account_settings.error_saving', defaultValue: 'Error Saving')).removeClass('btn-success').addClass('btn-danger', 500)
|
2014-07-10 14:50:16 -04:00
|
|
|
res.success (model, response, options) =>
|
|
|
|
@changedFields = []
|
2014-11-25 13:19:38 -05:00
|
|
|
save.text($.i18n.t('account_settings.saved', defaultValue: 'Changes Saved')).removeClass('btn-success btn-info', 1000).attr('disabled', 'true')
|
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)
|
2014-11-25 13:19:38 -05:00
|
|
|
$('.nano').nanoScroller({scrollTo: @$el.find('.has-error')})
|
2014-01-03 13:32:13 -05:00
|
|
|
return
|
|
|
|
if bothThere
|
|
|
|
me.set('password', password1)
|
2014-07-16 08:39:48 -04:00
|
|
|
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)
|
2014-11-25 13:19:38 -05:00
|
|
|
$('.nano').nanoScroller({scrollTo: @$el.find('.has-error')})
|
2014-01-03 13:32:13 -05:00
|
|
|
|
|
|
|
grabOtherData: ->
|
2014-11-25 13:19:38 -05:00
|
|
|
@$el.find('#name').val @suggestedName if @suggestedName
|
|
|
|
me.set 'name', @$el.find('#name').val()
|
|
|
|
me.set 'email', @$el.find('#email').val()
|
2014-04-21 19:15:23 -04:00
|
|
|
for emailName, enabled of @getSubscriptions()
|
2014-05-31 01:12:44 -04:00
|
|
|
me.setEmailSubscription emailName, enabled
|
2014-11-25 13:19:38 -05:00
|
|
|
|
|
|
|
me.set('photoURL', @$el.find('#photoURL').val())
|
2014-01-03 17:28:00 -05:00
|
|
|
|
|
|
|
adminCheckbox = @$el.find('#admin')
|
|
|
|
if adminCheckbox.length
|
|
|
|
permissions = []
|
|
|
|
permissions.push 'admin' if adminCheckbox.prop('checked')
|
|
|
|
me.set('permissions', permissions)
|