aboutsummaryrefslogtreecommitdiff
path: root/src/components
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
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')
-rw-r--r--src/components/attachment/attachment.js2
-rw-r--r--src/components/media_upload/media_upload.js9
-rw-r--r--src/components/post_status_form/post_status_form.js5
-rw-r--r--src/components/post_status_form/post_status_form.vue2
-rw-r--r--src/components/settings/settings.js5
-rw-r--r--src/components/settings/settings.vue12
-rw-r--r--src/components/status/status.vue2
-rw-r--r--src/components/timeline/timeline.js5
-rw-r--r--src/components/user_card/user_card.js3
-rw-r--r--src/components/user_card/user_card.vue4
-rw-r--r--src/components/user_card_content/user_card_content.js12
-rw-r--r--src/components/user_card_content/user_card_content.vue5
-rw-r--r--src/components/user_finder/user_finder.vue5
-rw-r--r--src/components/user_profile/user_profile.vue18
-rw-r--r--src/components/user_settings/user_settings.js121
-rw-r--r--src/components/user_settings/user_settings.vue52
16 files changed, 190 insertions, 72 deletions
diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js
index 16114c30..97c4f283 100644
--- a/src/components/attachment/attachment.js
+++ b/src/components/attachment/attachment.js
@@ -11,7 +11,7 @@ const Attachment = {
],
data () {
return {
- nsfwImage,
+ nsfwImage: this.$store.state.config.nsfwCensorImage || nsfwImage,
hideNsfwLocal: this.$store.state.config.hideNsfw,
preloadImage: this.$store.state.config.preloadImage,
loopVideo: this.$store.state.config.loopVideo,
diff --git a/src/components/media_upload/media_upload.js b/src/components/media_upload/media_upload.js
index 66337c3f..42d900d3 100644
--- a/src/components/media_upload/media_upload.js
+++ b/src/components/media_upload/media_upload.js
@@ -1,5 +1,6 @@
/* eslint-env browser */
import statusPosterService from '../../services/status_poster/status_poster.service.js'
+import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
const mediaUpload = {
mounted () {
@@ -21,6 +22,12 @@ const mediaUpload = {
uploadFile (file) {
const self = this
const store = this.$store
+ if (file.size > store.state.instance.uploadlimit) {
+ const filesize = fileSizeFormatService.fileSizeFormat(file.size)
+ const allowedsize = fileSizeFormatService.fileSizeFormat(store.state.instance.uploadlimit)
+ self.$emit('upload-failed', 'file_too_big', {filesize: filesize.num, filesizeunit: filesize.unit, allowedsize: allowedsize.num, allowedsizeunit: allowedsize.unit})
+ return
+ }
const formData = new FormData()
formData.append('media', file)
@@ -32,7 +39,7 @@ const mediaUpload = {
self.$emit('uploaded', fileData)
self.uploading = false
}, (error) => { // eslint-disable-line handle-callback-err
- self.$emit('upload-failed')
+ self.$emit('upload-failed', 'default')
self.uploading = false
})
},
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index f9252f73..0ce2aff0 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -262,6 +262,11 @@ const PostStatusForm = {
let index = this.newStatus.files.indexOf(fileInfo)
this.newStatus.files.splice(index, 1)
},
+ uploadFailed (errString, templateArgs) {
+ templateArgs = templateArgs || {}
+ this.error = this.$t('upload.error.base') + ' ' + this.$t('upload.error.' + errString, templateArgs)
+ this.enableSubmit()
+ },
disableSubmit () {
this.submitDisabled = true
},
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index fcf5c873..4776c819 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -64,7 +64,7 @@
</div>
</div>
<div class='form-bottom'>
- <media-upload @uploading="disableSubmit" @uploaded="addMediaFile" @upload-failed="enableSubmit" :drop-files="dropFiles"></media-upload>
+ <media-upload @uploading="disableSubmit" @uploaded="addMediaFile" @upload-failed="uploadFailed" :drop-files="dropFiles"></media-upload>
<p v-if="isOverLengthLimit" class="error">{{ charactersLeft }}</p>
<p class="faint" v-else-if="hasStatusLengthLimit">{{ charactersLeft }}</p>
diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js
index c9e12708..681ccda8 100644
--- a/src/components/settings/settings.js
+++ b/src/components/settings/settings.js
@@ -47,6 +47,7 @@ const settings = {
scopeCopyLocal: user.scopeCopy,
scopeCopyDefault: this.$t('settings.values.' + instance.scopeCopy),
stopGifs: user.stopGifs,
+ webPushNotificationsLocal: user.webPushNotifications,
loopSilentAvailable:
// Firefox
Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') ||
@@ -142,6 +143,10 @@ const settings = {
},
stopGifs (value) {
this.$store.dispatch('setOption', { name: 'stopGifs', value })
+ },
+ webPushNotificationsLocal (value) {
+ this.$store.dispatch('setOption', { name: 'webPushNotifications', value })
+ if (value) this.$store.dispatch('registerPushNotifications')
}
}
}
diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue
index 6cdc82da..3f920de5 100644
--- a/src/components/settings/settings.vue
+++ b/src/components/settings/settings.vue
@@ -143,6 +143,18 @@
</li>
</ul>
</div>
+
+ <div class="setting-item">
+ <h2>{{$t('settings.notifications')}}</h2>
+ <ul class="setting-list">
+ <li>
+ <input type="checkbox" id="webPushNotifications" v-model="webPushNotificationsLocal">
+ <label for="webPushNotifications">
+ {{$t('settings.enable_web_push_notifications')}}
+ </label>
+ </li>
+ </ul>
+ </div>
</div>
<div :label="$t('settings.theme')" >
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 96709084..067980ac 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -54,7 +54,7 @@
</h4>
</div>
<div class="media-heading-right">
- <router-link @click.native="activatePanel('timeline')" :to="{ name: 'conversation', params: { id: status.id } }">
+ <router-link class="timeago" @click.native="activatePanel('timeline')" :to="{ name: 'conversation', params: { id: status.id } }">
<timeago :since="status.created_at" :auto-update="60"></timeago>
</router-link>
<div class="visibility-icon" v-if="status.visibility">
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index a651f619..f28b85bd 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -2,6 +2,7 @@ import Status from '../status/status.vue'
import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js'
import StatusOrConversation from '../status_or_conversation/status_or_conversation.vue'
import UserCard from '../user_card/user_card.vue'
+import { throttle } from 'lodash'
const Timeline = {
props: [
@@ -88,7 +89,7 @@ const Timeline = {
this.paused = false
}
},
- fetchOlderStatuses () {
+ fetchOlderStatuses: throttle(function () {
const store = this.$store
const credentials = store.state.users.currentUser.credentials
store.commit('setLoading', { timeline: this.timelineName, value: true })
@@ -101,7 +102,7 @@ const Timeline = {
userId: this.userId,
tag: this.tag
}).then(() => store.commit('setLoading', { timeline: this.timelineName, value: false }))
- },
+ }, 1000, this),
fetchFollowers () {
const id = this.userId
this.$store.state.api.backendInteractor.fetchFollowers({ id })
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index a019627a..b8eb28e3 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -14,6 +14,9 @@ const UserCard = {
components: {
UserCardContent
},
+ computed: {
+ currentUser () { return this.$store.state.users.currentUser }
+ },
methods: {
toggleUserExpanded () {
this.userExpanded = !this.userExpanded
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 5a8e5531..eb0d7576 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -10,13 +10,13 @@
<div :title="user.name" v-if="user.name_html" class="user-name">
<span v-html="user.name_html"></span>
<span class="follows-you" v-if="!userExpanded && showFollows && user.follows_you">
- {{ $t('user_card.follows_you') }}
+ {{ currentUser.id == user.id ? $t('user_card.its_you') : $t('user_card.follows_you') }}
</span>
</div>
<div :title="user.name" v-else class="user-name">
{{ user.name }}
<span class="follows-you" v-if="!userExpanded && showFollows && user.follows_you">
- {{ $t('user_card.follows_you') }}
+ {{ currentUser.id == user.id ? $t('user_card.its_you') : $t('user_card.follows_you') }}
</span>
</div>
<router-link class='user-screen-name' :to="{ name: 'user-profile', params: { id: user.id } }">
diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js
index 7e0bd725..8c6de8ec 100644
--- a/src/components/user_card_content/user_card_content.js
+++ b/src/components/user_card_content/user_card_content.js
@@ -22,10 +22,20 @@ export default {
if (color) {
const rgb = (typeof color === 'string') ? hex2rgb(color) : color
const tintColor = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .5)`
+
+ const gradient = [
+ [tintColor, this.hideBio ? '60%' : ''],
+ this.hideBio ? [
+ color, '100%'
+ ] : [
+ tintColor, ''
+ ]
+ ].map(_ => _.join(' ')).join(', ')
+
return {
backgroundColor: `rgb(${Math.floor(rgb.r * 0.53)}, ${Math.floor(rgb.g * 0.56)}, ${Math.floor(rgb.b * 0.59)})`,
backgroundImage: [
- `linear-gradient(to bottom, ${tintColor}, ${tintColor})`,
+ `linear-gradient(to bottom, ${gradient})`,
`url(${this.user.cover_photo})`
].join(', ')
}
diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue
index 2dc53c17..a40aff35 100644
--- a/src/components/user_card_content/user_card_content.vue
+++ b/src/components/user_card_content/user_card_content.vue
@@ -103,7 +103,7 @@
</div>
</div>
</div>
- <div class="panel-body profile-panel-body" v-if="switcher">
+ <div class="panel-body profile-panel-body" v-if="!hideBio">
<div v-if="!hideUserStatsLocal || switcher" class="user-counts" :class="{clickable: switcher}">
<div class="user-count" v-on:click.prevent="setProfileView('statuses')" :class="{selected: selected === 'statuses'}">
<h5>{{ $t('user_card.statuses') }}</h5>
@@ -135,6 +135,9 @@
border-radius: var(--panelRadius, $fallback--panelRadius);
overflow: hidden;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+
.panel-heading {
padding: 0.6em 0em;
text-align: center;
diff --git a/src/components/user_finder/user_finder.vue b/src/components/user_finder/user_finder.vue
index 8786f6c7..4d9f6842 100644
--- a/src/components/user_finder/user_finder.vue
+++ b/src/components/user_finder/user_finder.vue
@@ -1,12 +1,12 @@
<template>
- <span class="user-finder-container">
+ <div class="user-finder-container">
<i class="icon-spin4 user-finder-icon animate-spin-slow" v-if="loading" />
<a href="#" v-if="hidden" :title="$t('finder.find_user')" ><i class="icon-user-plus user-finder-icon" @click.prevent.stop="toggleHidden" /></a>
<span v-else>
<input class="user-finder-input" @keyup.enter="findUser(username)" v-model="username" :placeholder="$t('finder.find_user')" id="user-finder-input" type="text"/>
<i class="icon-cancel user-finder-icon" @click.prevent.stop="toggleHidden"/>
</span>
- </span>
+ </div>
</template>
<script src="./user_finder.js"></script>
@@ -15,7 +15,6 @@
@import '../../_variables.scss';
.user-finder-container {
- height: 29px;
max-width: 100%;
}
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index 91d4acd2..4d2853a6 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -3,6 +3,16 @@
<div v-if="user" class="user-profile panel panel-default">
<user-card-content :user="user" :switcher="true" :selected="timeline.viewing"></user-card-content>
</div>
+ <div v-else class="panel user-profile-placeholder">
+ <div class="panel-heading">
+ <div class="title">
+ {{ $t('settings.profile_tab') }}
+ </div>
+ </div>
+ <div class="panel-body">
+ <i class="icon-spin3 animate-spin"></i>
+ </div>
+ </div>
<Timeline :title="$t('user_profile.timeline_title')" :timeline="timeline" :timeline-name="'user'" :user-id="userId"/>
</div>
</template>
@@ -21,4 +31,12 @@
align-items: stretch;
}
}
+.user-profile-placeholder {
+ .panel-body {
+ display: flex;
+ justify-content: center;
+ align-items: middle;
+ padding: 7em;
+ }
+}
</style>
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>