akkoma-fe/src/components/user_settings/user_settings.js

412 lines
14 KiB
JavaScript
Raw Normal View History

import unescape from 'lodash/unescape'
import get from 'lodash/get'
import map from 'lodash/map'
import reject from 'lodash/reject'
import TabSwitcher from '../tab_switcher/tab_switcher.js'
2019-02-07 08:05:59 +00:00
import ImageCropper from '../image_cropper/image_cropper.vue'
import StyleSwitcher from '../style_switcher/style_switcher.vue'
import ScopeSelector from '../scope_selector/scope_selector.vue'
import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
2019-02-13 19:55:02 +00:00
import BlockCard from '../block_card/block_card.vue'
2019-02-14 03:04:28 +00:00
import MuteCard from '../mute_card/mute_card.vue'
2020-01-15 20:22:54 +00:00
import DomainMuteCard from '../domain_mute_card/domain_mute_card.vue'
import SelectableList from '../selectable_list/selectable_list.vue'
2019-04-04 17:30:34 +00:00
import ProgressButton from '../progress_button/progress_button.vue'
2019-08-12 10:18:37 +00:00
import EmojiInput from '../emoji_input/emoji_input.vue'
import suggestor from '../emoji_input/suggestor.js'
2019-04-02 20:10:03 +00:00
import Autosuggest from '../autosuggest/autosuggest.vue'
import Importer from '../importer/importer.vue'
2019-03-30 12:03:40 +00:00
import Exporter from '../exporter/exporter.vue'
import withSubscription from '../../hocs/with_subscription/with_subscription'
import Checkbox from '../checkbox/checkbox.vue'
import Mfa from './mfa.vue'
const BlockList = withSubscription({
fetch: (props, $store) => $store.dispatch('fetchBlocks'),
select: (props, $store) => get($store.state.users.currentUser, 'blockIds', []),
childPropName: 'items'
})(SelectableList)
const MuteList = withSubscription({
fetch: (props, $store) => $store.dispatch('fetchMutes'),
select: (props, $store) => get($store.state.users.currentUser, 'muteIds', []),
childPropName: 'items'
})(SelectableList)
2019-02-14 03:04:28 +00:00
2020-01-15 20:22:54 +00:00
const DomainMuteList = withSubscription({
fetch: (props, $store) => $store.dispatch('fetchDomainMutes'),
select: (props, $store) => get($store.state.users.currentUser, 'domainMutes', []),
childPropName: 'items'
})(SelectableList)
const UserSettings = {
data () {
return {
2019-11-08 02:21:19 +00:00
newEmail: '',
newName: this.$store.state.users.currentUser.name,
2019-02-04 20:03:01 +00:00
newBio: unescape(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,
hideFollows: this.$store.state.users.currentUser.hide_follows,
hideFollowers: this.$store.state.users.currentUser.hide_followers,
hideFollowsCount: this.$store.state.users.currentUser.hide_follows_count,
hideFollowersCount: this.$store.state.users.currentUser.hide_followers_count,
showRole: this.$store.state.users.currentUser.show_role,
role: this.$store.state.users.currentUser.role,
discoverable: this.$store.state.users.currentUser.discoverable,
2020-02-03 19:26:32 +00:00
allowFollowingMove: this.$store.state.users.currentUser.allow_following_move,
2019-02-09 02:59:33 +00:00
pickAvatarBtnVisible: true,
2018-12-13 08:25:03 +00:00
bannerUploading: false,
backgroundUploading: false,
banner: null,
2018-12-13 08:25:03 +00:00
bannerPreview: null,
background: null,
2018-12-13 08:25:03 +00:00
backgroundPreview: null,
bannerUploadError: null,
backgroundUploadError: null,
2020-05-08 13:38:46 +00:00
mascot: this.$store.state.users.currentUser.mascot,
mascotPreview: null,
mascotUploadError: null,
2019-11-08 02:21:19 +00:00
changeEmailError: false,
changeEmailPassword: '',
changedEmail: false,
deletingAccount: false,
deleteAccountConfirmPasswordInput: '',
2018-05-21 22:01:09 +00:00
deleteAccountError: false,
changePasswordInputs: [ '', '', '' ],
changedPassword: false,
2018-08-18 23:23:03 +00:00
changePasswordError: false,
2019-05-25 07:01:02 +00:00
activeTab: 'profile',
2020-01-15 20:22:54 +00:00
notificationSettings: this.$store.state.users.currentUser.notification_settings,
newDomainToMute: ''
}
},
created () {
this.$store.dispatch('fetchTokens')
2020-05-08 13:38:46 +00:00
this.$store.dispatch('fetchMascot')
},
components: {
StyleSwitcher,
ScopeSelector,
2019-02-07 08:05:59 +00:00
TabSwitcher,
ImageCropper,
BlockList,
MuteList,
2020-01-15 20:22:54 +00:00
DomainMuteList,
2019-04-02 10:12:31 +00:00
EmojiInput,
2019-04-02 20:10:03 +00:00
Autosuggest,
2019-04-02 20:14:45 +00:00
BlockCard,
2019-04-04 17:30:34 +00:00
MuteCard,
2020-01-15 20:22:54 +00:00
DomainMuteCard,
ProgressButton,
2019-03-30 12:03:40 +00:00
Importer,
Exporter,
Mfa,
Checkbox
},
computed: {
user () {
return this.$store.state.users.currentUser
2017-12-23 14:44:22 +00:00
},
emojiUserSuggestor () {
return suggestor({
emoji: [
...this.$store.state.instance.emoji,
...this.$store.state.instance.customEmoji
],
2019-07-18 03:40:02 +00:00
users: this.$store.state.users.users,
2020-05-13 14:48:31 +00:00
updateUsersList: (query) => this.$store.dispatch('searchUsers', { query })
})
},
emojiSuggestor () {
return suggestor({ emoji: [
...this.$store.state.instance.emoji,
...this.$store.state.instance.customEmoji
2019-07-05 07:02:14 +00:00
] })
},
2017-12-23 14:44:22 +00:00
pleromaBackend () {
2018-09-09 18:21:23 +00:00
return this.$store.state.instance.pleromaBackend
},
2019-03-30 10:41:42 +00:00
minimalScopesMode () {
return this.$store.state.instance.minimalScopesMode
},
vis () {
return {
public: { selected: this.newDefaultScope === 'public' },
unlisted: { selected: this.newDefaultScope === 'unlisted' },
private: { selected: this.newDefaultScope === 'private' },
direct: { selected: this.newDefaultScope === 'direct' }
}
},
currentSaveStateNotice () {
return this.$store.state.interface.settings.currentSaveStateNotice
},
oauthTokens () {
return this.$store.state.oauthTokens.tokens.map(oauthToken => {
return {
id: oauthToken.id,
appName: oauthToken.app_name,
validUntil: new Date(oauthToken.valid_until).toLocaleDateString()
}
})
2018-06-27 13:28:07 +00:00
}
},
methods: {
updateProfile () {
this.$store.state.api.backendInteractor
.updateProfile({
params: {
2019-04-27 18:04:30 +00:00
note: this.newBio,
locked: this.newLocked,
// Backend notation.
/* eslint-disable camelcase */
2019-04-27 18:04:30 +00:00
display_name: this.newName,
2019-04-28 01:51:17 +00:00
default_scope: this.newDefaultScope,
2019-04-27 18:04:30 +00:00
no_rich_text: this.newNoRichText,
hide_follows: this.hideFollows,
hide_followers: this.hideFollowers,
discoverable: this.discoverable,
2020-02-03 19:26:32 +00:00
allow_following_move: this.allowFollowingMove,
hide_follows_count: this.hideFollowsCount,
hide_followers_count: this.hideFollowersCount,
2019-04-27 18:04:30 +00:00
show_role: this.showRole
/* eslint-enable camelcase */
2019-07-05 07:02:14 +00:00
} }).then((user) => {
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)
})
},
2019-05-25 07:01:02 +00:00
updateNotificationSettings () {
this.$store.state.api.backendInteractor
.updateNotificationSettings({ settings: this.notificationSettings })
},
changeVis (visibility) {
this.newDefaultScope = visibility
},
uploadFile (slot, e) {
const file = e.target.files[0]
if (!file) { return }
2018-12-13 14:51:29 +00:00
if (file.size > this.$store.state.instance[slot + 'limit']) {
const filesize = fileSizeFormatService.fileSizeFormat(file.size)
2018-12-13 14:51:29 +00:00
const allowedsize = fileSizeFormatService.fileSizeFormat(this.$store.state.instance[slot + 'limit'])
2019-07-05 07:02:14 +00:00
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()
2019-07-05 07:02:14 +00:00
reader.onload = ({ target }) => {
const img = target.result
2018-12-13 14:44:37 +00:00
this[slot + 'Preview'] = img
2019-03-13 17:56:28 +00:00
this[slot] = file
}
reader.readAsDataURL(file)
},
submitAvatar (cropper, file) {
2019-03-22 17:00:58 +00:00
const that = this
return new Promise((resolve, reject) => {
function updateAvatar (avatar) {
2019-03-22 17:00:58 +00:00
that.$store.state.api.backendInteractor.updateAvatar({ avatar })
.then((user) => {
2019-03-22 17:00:58 +00:00
that.$store.commit('addNewUsers', [user])
that.$store.commit('setCurrentUser', user)
resolve()
})
.catch((err) => {
2019-03-22 17:00:58 +00:00
reject(new Error(that.$t('upload.error.base') + ' ' + err.message))
})
}
2019-03-19 01:19:42 +00:00
if (cropper) {
cropper.getCroppedCanvas().toBlob(updateAvatar, file.type)
2018-12-12 16:31:16 +00:00
} else {
updateAvatar(file)
}
})
},
clearUploadError (slot) {
2018-12-13 14:44:37 +00:00
this[slot + 'UploadError'] = null
},
submitBanner () {
2018-12-13 08:25:03 +00:00
if (!this.bannerPreview) { return }
2018-12-13 08:25:03 +00:00
this.bannerUploading = true
2019-07-05 07:02:14 +00:00
this.$store.state.api.backendInteractor.updateBanner({ banner: this.banner })
2019-03-13 17:56:28 +00:00
.then((user) => {
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)
2018-12-13 08:25:03 +00:00
this.bannerPreview = null
2019-03-13 17:56:28 +00:00
})
.catch((err) => {
this.bannerUploadError = this.$t('upload.error.base') + ' ' + err.message
})
.then(() => { this.bannerUploading = false })
},
submitBg () {
2018-12-13 08:25:03 +00:00
if (!this.backgroundPreview) { return }
let background = this.background
2018-12-13 08:25:03 +00:00
this.backgroundUploading = true
this.$store.state.api.backendInteractor.updateBg({ background }).then((data) => {
if (!data.error) {
this.$store.commit('addNewUsers', [data])
this.$store.commit('setCurrentUser', data)
2018-12-13 08:25:03 +00:00
this.backgroundPreview = null
2018-12-12 16:31:16 +00:00
} else {
2018-12-13 08:25:03 +00:00
this.backgroundUploadError = this.$t('upload.error.base') + data.error
}
2018-12-13 08:25:03 +00:00
this.backgroundUploading = false
})
2017-12-23 14:44:22 +00:00
},
2020-05-08 13:38:46 +00:00
submitMascot () {
if (!this.mascotPreview) { return }
let mascot = this.mascot
this.mascotUploading = true
this.$store.state.api.backendInteractor.updateMascot({ mascot }).then((data) => {
if (!data.error) {
this.mascotPreview = null
this.$store.commit('updateMascot', data.url)
} else {
this.mascotUploadError = this.$t('upload.error.base') + ' ' + data.error
}
this.mascotUploading = false
})
},
2019-03-30 09:10:57 +00:00
importFollows (file) {
return this.$store.state.api.backendInteractor.importFollows({ file })
2019-03-30 09:10:57 +00:00
.then((status) => {
if (!status) {
throw new Error('failed')
}
})
},
2019-03-30 11:27:53 +00:00
importBlocks (file) {
return this.$store.state.api.backendInteractor.importBlocks({ file })
2019-03-30 11:27:53 +00:00
.then((status) => {
if (!status) {
throw new Error('failed')
}
})
},
2019-03-30 12:17:37 +00:00
generateExportableUsersContent (users) {
// Get addresses
return users.map((user) => {
// check is it's a local user
if (user && user.is_local) {
// append the instance address
// eslint-disable-next-line no-undef
return user.screen_name + '@' + location.hostname
}
return user.screen_name
}).join('\n')
},
2019-03-30 12:03:40 +00:00
getFollowsContent () {
return this.$store.state.api.backendInteractor.exportFriends({ id: this.$store.state.users.currentUser.id })
2019-03-30 12:17:37 +00:00
.then(this.generateExportableUsersContent)
2019-03-30 12:14:52 +00:00
},
getBlocksContent () {
return this.$store.state.api.backendInteractor.fetchBlocks()
2019-03-30 12:17:37 +00:00
.then(this.generateExportableUsersContent)
2018-05-13 23:47:08 +00:00
},
confirmDelete () {
this.deletingAccount = true
},
deleteAccount () {
2019-07-05 07:02:14 +00:00
this.$store.state.api.backendInteractor.deleteAccount({ password: this.deleteAccountConfirmPasswordInput })
.then((res) => {
if (res.status === 'success') {
this.$store.dispatch('logout')
2019-07-05 07:02:14 +00:00
this.$router.push({ name: 'root' })
} else {
this.deleteAccountError = res.error
}
})
2018-05-21 22:01:09 +00:00
},
changePassword () {
const params = {
password: this.changePasswordInputs[0],
newPassword: this.changePasswordInputs[1],
newPasswordConfirmation: this.changePasswordInputs[2]
}
2020-01-28 03:12:32 +00:00
this.$store.state.api.backendInteractor.changePassword(params)
2018-05-21 22:01:09 +00:00
.then((res) => {
if (res.status === 'success') {
this.changedPassword = true
this.changePasswordError = false
this.logout()
2018-05-21 22:01:09 +00:00
} else {
this.changedPassword = false
this.changePasswordError = res.error
}
})
2018-08-18 23:23:03 +00:00
},
2019-11-08 02:21:19 +00:00
changeEmail () {
const params = {
email: this.newEmail,
password: this.changeEmailPassword
}
2020-01-28 03:12:32 +00:00
this.$store.state.api.backendInteractor.changeEmail(params)
2019-11-08 02:21:19 +00:00
.then((res) => {
if (res.status === 'success') {
this.changedEmail = true
this.changeEmailError = false
} else {
this.changedEmail = false
this.changeEmailError = res.error
}
})
},
2018-08-18 23:23:03 +00:00
activateTab (tabName) {
this.activeTab = tabName
2018-11-30 13:30:55 +00:00
},
logout () {
2018-11-30 13:30:55 +00:00
this.$store.dispatch('logout')
this.$router.replace('/')
},
revokeToken (id) {
2019-02-20 23:51:28 +00:00
if (window.confirm(`${this.$i18n.t('settings.revoke_token')}?`)) {
this.$store.dispatch('revokeToken', id)
}
},
filterUnblockedUsers (userIds) {
return reject(userIds, (userId) => {
const relationship = this.$store.getters.relationship(this.userId)
2020-04-21 20:27:51 +00:00
return relationship.blocking || userId === this.$store.state.users.currentUser.id
})
},
2019-04-02 20:14:45 +00:00
filterUnMutedUsers (userIds) {
return reject(userIds, (userId) => {
const relationship = this.$store.getters.relationship(this.userId)
2020-04-21 20:27:51 +00:00
return relationship.muting || userId === this.$store.state.users.currentUser.id
2019-04-02 20:14:45 +00:00
})
},
queryUserIds (query) {
2020-05-13 14:48:31 +00:00
return this.$store.dispatch('searchUsers', { query })
.then((users) => map(users, 'id'))
2019-04-04 17:54:52 +00:00
},
blockUsers (ids) {
return this.$store.dispatch('blockUsers', ids)
},
unblockUsers (ids) {
return this.$store.dispatch('unblockUsers', ids)
},
muteUsers (ids) {
return this.$store.dispatch('muteUsers', ids)
},
unmuteUsers (ids) {
return this.$store.dispatch('unmuteUsers', ids)
2019-04-06 18:56:50 +00:00
},
2020-01-15 20:22:54 +00:00
unmuteDomains (domains) {
return this.$store.dispatch('unmuteDomains', domains)
},
muteDomain () {
return this.$store.dispatch('muteDomain', this.newDomainToMute)
.then(() => { this.newDomainToMute = '' })
},
2019-04-06 18:56:50 +00:00
identity (value) {
return value
}
}
}
export default UserSettings