aboutsummaryrefslogtreecommitdiff
path: root/src/components/user_settings
diff options
context:
space:
mode:
authorHenry Jameson <me@hjkos.com>2018-12-14 17:17:58 +0300
committerHenry Jameson <me@hjkos.com>2018-12-14 17:17:58 +0300
commitd7973b0b802cdeea42c8ca292574e52b4050525e (patch)
treed443d01edb20682d408d57855ee4088c96826dea /src/components/user_settings
parent9dfff107177e4461734c54f60d79448dec34c002 (diff)
parent5b6c1aa97c0d13101ebddb4c34b79a2e428ec30b (diff)
Merge remote-tracking branch 'upstream/develop' into async_follow
* upstream/develop: (45 commits) fix chrome Prevent html-minifier to remove placeholder comment in index.html template Add placeholder to insert server generated metatags. Related to #430 added condition to check for logined user fix gradients and minor artifacts keep track of new instance options fix old MR oof get rid of slots fix timeago font added hide_network option, fixed properties naming Fix fetching new users, add storing local users in usersObjects with their screen_name as well as id, so that they could be fetched zero-state with screen-name link. improve notification subscription Refactor arrays to individual options Reset enableFollowsExport to true after 2 sec when an export file is available to download Write a unit test for fileSizeFormatService add checkbox to disable web push I am dumb Handle errors from server Moved upload errors in user_settings to an array. Moved upload error strings to its separate section in i18n ...
Diffstat (limited to 'src/components/user_settings')
-rw-r--r--src/components/user_settings/user_settings.js121
-rw-r--r--src/components/user_settings/user_settings.vue52
2 files changed, 114 insertions, 59 deletions
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index 761e674a..ca7bf319 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -1,20 +1,30 @@
import TabSwitcher from '../tab_switcher/tab_switcher.jsx'
import StyleSwitcher from '../style_switcher/style_switcher.vue'
+import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
const UserSettings = {
data () {
return {
- newname: this.$store.state.users.currentUser.name,
- newbio: this.$store.state.users.currentUser.description,
- newlocked: this.$store.state.users.currentUser.locked,
- newnorichtext: this.$store.state.users.currentUser.no_rich_text,
- newdefaultScope: this.$store.state.users.currentUser.default_scope,
+ newName: this.$store.state.users.currentUser.name,
+ newBio: this.$store.state.users.currentUser.description,
+ newLocked: this.$store.state.users.currentUser.locked,
+ newNoRichText: this.$store.state.users.currentUser.no_rich_text,
+ newDefaultScope: this.$store.state.users.currentUser.default_scope,
+ newHideNetwork: this.$store.state.users.currentUser.hide_network,
followList: null,
followImportError: false,
followsImported: false,
enableFollowsExport: true,
- uploading: [ false, false, false, false ],
- previews: [ null, null, null ],
+ avatarUploading: false,
+ bannerUploading: false,
+ backgroundUploading: false,
+ followListUploading: false,
+ avatarPreview: null,
+ bannerPreview: null,
+ backgroundPreview: null,
+ avatarUploadError: null,
+ bannerUploadError: null,
+ backgroundUploadError: null,
deletingAccount: false,
deleteAccountConfirmPasswordInput: '',
deleteAccountError: false,
@@ -40,48 +50,67 @@ const UserSettings = {
},
vis () {
return {
- public: { selected: this.newdefaultScope === 'public' },
- unlisted: { selected: this.newdefaultScope === 'unlisted' },
- private: { selected: this.newdefaultScope === 'private' },
- direct: { selected: this.newdefaultScope === 'direct' }
+ public: { selected: this.newDefaultScope === 'public' },
+ unlisted: { selected: this.newDefaultScope === 'unlisted' },
+ private: { selected: this.newDefaultScope === 'private' },
+ direct: { selected: this.newDefaultScope === 'direct' }
}
}
},
methods: {
updateProfile () {
const name = this.newname
- const description = this.newbio
- const locked = this.newlocked
+ const description = this.newBio
+ const locked = this.newLocked
+ // Backend notation.
/* eslint-disable camelcase */
- const default_scope = this.newdefaultScope
- const no_rich_text = this.newnorichtext
- this.$store.state.api.backendInteractor.updateProfile({params: {name, description, locked, default_scope, no_rich_text}}).then((user) => {
- if (!user.error) {
- this.$store.commit('addNewUsers', [user])
- this.$store.commit('setCurrentUser', user)
- }
- })
+ const default_scope = this.newDefaultScope
+ const no_rich_text = this.newNoRichText
+ const hide_network = this.newHideNetwork
/* eslint-enable camelcase */
+ this.$store.state.api.backendInteractor
+ .updateProfile({
+ params: {
+ name,
+ description,
+ locked,
+ // Backend notation.
+ /* eslint-disable camelcase */
+ default_scope,
+ no_rich_text,
+ hide_network
+ /* eslint-enable camelcase */
+ }}).then((user) => {
+ if (!user.error) {
+ this.$store.commit('addNewUsers', [user])
+ this.$store.commit('setCurrentUser', user)
+ }
+ })
},
changeVis (visibility) {
- this.newdefaultScope = visibility
+ this.newDefaultScope = visibility
},
uploadFile (slot, e) {
const file = e.target.files[0]
if (!file) { return }
+ if (file.size > this.$store.state.instance[slot + 'limit']) {
+ const filesize = fileSizeFormatService.fileSizeFormat(file.size)
+ const allowedsize = fileSizeFormatService.fileSizeFormat(this.$store.state.instance[slot + 'limit'])
+ this[slot + 'UploadError'] = this.$t('upload.error.base') + ' ' + this.$t('upload.error.file_too_big', {filesize: filesize.num, filesizeunit: filesize.unit, allowedsize: allowedsize.num, allowedsizeunit: allowedsize.unit})
+ return
+ }
// eslint-disable-next-line no-undef
const reader = new FileReader()
reader.onload = ({target}) => {
const img = target.result
- this.previews[slot] = img
- this.$forceUpdate() // just changing the array with the index doesn't update the view
+ this[slot + 'Preview'] = img
}
reader.readAsDataURL(file)
},
submitAvatar () {
- if (!this.previews[0]) { return }
+ if (!this.avatarPreview) { return }
- let img = this.previews[0]
+ let img = this.avatarPreview
// eslint-disable-next-line no-undef
let imginfo = new Image()
let cropX, cropY, cropW, cropH
@@ -97,20 +126,25 @@ const UserSettings = {
cropX = Math.floor((imginfo.width - imginfo.height) / 2)
cropW = imginfo.height
}
- this.uploading[0] = true
+ this.avatarUploading = true
this.$store.state.api.backendInteractor.updateAvatar({params: {img, cropX, cropY, cropW, cropH}}).then((user) => {
if (!user.error) {
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)
- this.previews[0] = null
+ this.avatarPreview = null
+ } else {
+ this.avatarUploadError = this.$t('upload.error.base') + user.error
}
- this.uploading[0] = false
+ this.avatarUploading = false
})
},
+ clearUploadError (slot) {
+ this[slot + 'UploadError'] = null
+ },
submitBanner () {
- if (!this.previews[1]) { return }
+ if (!this.bannerPreview) { return }
- let banner = this.previews[1]
+ let banner = this.bannerPreview
// eslint-disable-next-line no-undef
let imginfo = new Image()
/* eslint-disable camelcase */
@@ -120,22 +154,24 @@ const UserSettings = {
height = imginfo.height
offset_top = 0
offset_left = 0
- this.uploading[1] = true
+ this.bannerUploading = true
this.$store.state.api.backendInteractor.updateBanner({params: {banner, offset_top, offset_left, width, height}}).then((data) => {
if (!data.error) {
let clone = JSON.parse(JSON.stringify(this.$store.state.users.currentUser))
clone.cover_photo = data.url
this.$store.commit('addNewUsers', [clone])
this.$store.commit('setCurrentUser', clone)
- this.previews[1] = null
+ this.bannerPreview = null
+ } else {
+ this.bannerUploadError = this.$t('upload.error.base') + data.error
}
- this.uploading[1] = false
+ this.bannerUploading = false
})
/* eslint-enable camelcase */
},
submitBg () {
- if (!this.previews[2]) { return }
- let img = this.previews[2]
+ if (!this.backgroundPreview) { return }
+ let img = this.backgroundPreview
// eslint-disable-next-line no-undef
let imginfo = new Image()
let cropX, cropY, cropW, cropH
@@ -144,20 +180,22 @@ const UserSettings = {
cropY = 0
cropW = imginfo.width
cropH = imginfo.width
- this.uploading[2] = true
+ this.backgroundUploading = true
this.$store.state.api.backendInteractor.updateBg({params: {img, cropX, cropY, cropW, cropH}}).then((data) => {
if (!data.error) {
let clone = JSON.parse(JSON.stringify(this.$store.state.users.currentUser))
clone.background_image = data.url
this.$store.commit('addNewUsers', [clone])
this.$store.commit('setCurrentUser', clone)
- this.previews[2] = null
+ this.backgroundPreview = null
+ } else {
+ this.backgroundUploadError = this.$t('upload.error.base') + data.error
}
- this.uploading[2] = false
+ this.backgroundUploading = false
})
},
importFollows () {
- this.uploading[3] = true
+ this.followListUploading = true
const followList = this.followList
this.$store.state.api.backendInteractor.followImport({params: followList})
.then((status) => {
@@ -166,7 +204,7 @@ const UserSettings = {
} else {
this.followImportError = true
}
- this.uploading[3] = false
+ this.followListUploading = false
})
},
/* This function takes an Array of Users
@@ -198,6 +236,7 @@ const UserSettings = {
.fetchFriends({id: this.$store.state.users.currentUser.id})
.then((friendList) => {
this.exportPeople(friendList, 'friends.csv')
+ setTimeout(() => { this.enableFollowsExport = true }, 2000)
})
},
followListChange () {
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 234a7d86..67b65b57 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -9,11 +9,11 @@
<div class="setting-item" >
<h2>{{$t('settings.name_bio')}}</h2>
<p>{{$t('settings.name')}}</p>
- <input class='name-changer' id='username' v-model="newname"></input>
+ <input class='name-changer' id='username' v-model="newName"></input>
<p>{{$t('settings.bio')}}</p>
- <textarea class="bio" v-model="newbio"></textarea>
+ <textarea class="bio" v-model="newBio"></textarea>
<p>
- <input type="checkbox" v-model="newlocked" id="account-locked">
+ <input type="checkbox" v-model="newLocked" id="account-locked">
<label for="account-locked">{{$t('settings.lock_account_description')}}</label>
</p>
<div v-if="scopeOptionsEnabled">
@@ -26,47 +26,63 @@
</div>
</div>
<p>
- <input type="checkbox" v-model="newnorichtext" id="account-no-rich-text">
+ <input type="checkbox" v-model="newNoRichText" id="account-no-rich-text">
<label for="account-no-rich-text">{{$t('settings.no_rich_text_description')}}</label>
</p>
- <button :disabled='newname.length <= 0' class="btn btn-default" @click="updateProfile">{{$t('general.submit')}}</button>
+ <p>
+ <input type="checkbox" v-model="newHideNetwork" id="account-hide-network">
+ <label for="account-no-rich-text">{{$t('settings.hide_network_description')}}</label>
+ </p>
+ <button :disabled='newName.length <= 0' class="btn btn-default" @click="updateProfile">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h2>{{$t('settings.avatar')}}</h2>
<p>{{$t('settings.current_avatar')}}</p>
<img :src="user.profile_image_url_original" class="old-avatar"></img>
<p>{{$t('settings.set_new_avatar')}}</p>
- <img class="new-avatar" v-bind:src="previews[0]" v-if="previews[0]">
+ <img class="new-avatar" v-bind:src="avatarPreview" v-if="avatarPreview">
</img>
<div>
- <input type="file" @change="uploadFile(0, $event)" ></input>
+ <input type="file" @change="uploadFile('avatar', $event)" ></input>
+ </div>
+ <i class="icon-spin4 animate-spin" v-if="avatarUploading"></i>
+ <button class="btn btn-default" v-else-if="avatarPreview" @click="submitAvatar">{{$t('general.submit')}}</button>
+ <div class='alert error' v-if="avatarUploadError">
+ Error: {{ avatarUploadError }}
+ <i class="icon-cancel" @click="clearUploadError('avatar')"></i>
</div>
- <i class="icon-spin4 animate-spin" v-if="uploading[0]"></i>
- <button class="btn btn-default" v-else-if="previews[0]" @click="submitAvatar">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h2>{{$t('settings.profile_banner')}}</h2>
<p>{{$t('settings.current_profile_banner')}}</p>
<img :src="user.cover_photo" class="banner"></img>
<p>{{$t('settings.set_new_profile_banner')}}</p>
- <img class="banner" v-bind:src="previews[1]" v-if="previews[1]">
+ <img class="banner" v-bind:src="bannerPreview" v-if="bannerPreview">
</img>
<div>
- <input type="file" @change="uploadFile(1, $event)" ></input>
+ <input type="file" @change="uploadFile('banner', $event)" ></input>
+ </div>
+ <i class=" icon-spin4 animate-spin uploading" v-if="bannerUploading"></i>
+ <button class="btn btn-default" v-else-if="bannerPreview" @click="submitBanner">{{$t('general.submit')}}</button>
+ <div class='alert error' v-if="bannerUploadError">
+ Error: {{ bannerUploadError }}
+ <i class="icon-cancel" @click="clearUploadError('banner')"></i>
</div>
- <i class=" icon-spin4 animate-spin uploading" v-if="uploading[1]"></i>
- <button class="btn btn-default" v-else-if="previews[1]" @click="submitBanner">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h2>{{$t('settings.profile_background')}}</h2>
<p>{{$t('settings.set_new_profile_background')}}</p>
- <img class="bg" v-bind:src="previews[2]" v-if="previews[2]">
+ <img class="bg" v-bind:src="backgroundPreview" v-if="backgroundPreview">
</img>
<div>
- <input type="file" @change="uploadFile(2, $event)" ></input>
+ <input type="file" @change="uploadFile('background', $event)" ></input>
+ </div>
+ <i class=" icon-spin4 animate-spin uploading" v-if="backgroundUploading"></i>
+ <button class="btn btn-default" v-else-if="backgroundPreview" @click="submitBg">{{$t('general.submit')}}</button>
+ <div class='alert error' v-if="backgroundUploadError">
+ Error: {{ backgroundUploadError }}
+ <i class="icon-cancel" @click="clearUploadError('background')"></i>
</div>
- <i class=" icon-spin4 animate-spin uploading" v-if="uploading[2]"></i>
- <button class="btn btn-default" v-else-if="previews[2]" @click="submitBg">{{$t('general.submit')}}</button>
</div>
</div>
@@ -113,7 +129,7 @@
<form v-model="followImportForm">
<input type="file" ref="followlist" v-on:change="followListChange"></input>
</form>
- <i class=" icon-spin4 animate-spin uploading" v-if="uploading[3]"></i>
+ <i class=" icon-spin4 animate-spin uploading" v-if="followListUploading"></i>
<button class="btn btn-default" v-else @click="importFollows">{{$t('general.submit')}}</button>
<div v-if="followsImported">
<i class="icon-cross" @click="dismissImported"></i>