logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe

user_settings.js (13695B)


      1 import unescape from 'lodash/unescape'
      2 import get from 'lodash/get'
      3 import map from 'lodash/map'
      4 import reject from 'lodash/reject'
      5 import TabSwitcher from '../tab_switcher/tab_switcher.js'
      6 import ImageCropper from '../image_cropper/image_cropper.vue'
      7 import StyleSwitcher from '../style_switcher/style_switcher.vue'
      8 import ScopeSelector from '../scope_selector/scope_selector.vue'
      9 import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
     10 import BlockCard from '../block_card/block_card.vue'
     11 import MuteCard from '../mute_card/mute_card.vue'
     12 import DomainMuteCard from '../domain_mute_card/domain_mute_card.vue'
     13 import SelectableList from '../selectable_list/selectable_list.vue'
     14 import ProgressButton from '../progress_button/progress_button.vue'
     15 import EmojiInput from '../emoji_input/emoji_input.vue'
     16 import suggestor from '../emoji_input/suggestor.js'
     17 import Autosuggest from '../autosuggest/autosuggest.vue'
     18 import Importer from '../importer/importer.vue'
     19 import Exporter from '../exporter/exporter.vue'
     20 import withSubscription from '../../hocs/with_subscription/with_subscription'
     21 import Checkbox from '../checkbox/checkbox.vue'
     22 import Mfa from './mfa.vue'
     23 
     24 const BlockList = withSubscription({
     25   fetch: (props, $store) => $store.dispatch('fetchBlocks'),
     26   select: (props, $store) => get($store.state.users.currentUser, 'blockIds', []),
     27   childPropName: 'items'
     28 })(SelectableList)
     29 
     30 const MuteList = withSubscription({
     31   fetch: (props, $store) => $store.dispatch('fetchMutes'),
     32   select: (props, $store) => get($store.state.users.currentUser, 'muteIds', []),
     33   childPropName: 'items'
     34 })(SelectableList)
     35 
     36 const DomainMuteList = withSubscription({
     37   fetch: (props, $store) => $store.dispatch('fetchDomainMutes'),
     38   select: (props, $store) => get($store.state.users.currentUser, 'domainMutes', []),
     39   childPropName: 'items'
     40 })(SelectableList)
     41 
     42 const UserSettings = {
     43   data () {
     44     return {
     45       newEmail: '',
     46       newName: this.$store.state.users.currentUser.name,
     47       newBio: unescape(this.$store.state.users.currentUser.description),
     48       newLocked: this.$store.state.users.currentUser.locked,
     49       newNoRichText: this.$store.state.users.currentUser.no_rich_text,
     50       newDefaultScope: this.$store.state.users.currentUser.default_scope,
     51       hideFollows: this.$store.state.users.currentUser.hide_follows,
     52       hideFollowers: this.$store.state.users.currentUser.hide_followers,
     53       hideFollowsCount: this.$store.state.users.currentUser.hide_follows_count,
     54       hideFollowersCount: this.$store.state.users.currentUser.hide_followers_count,
     55       showRole: this.$store.state.users.currentUser.show_role,
     56       role: this.$store.state.users.currentUser.role,
     57       discoverable: this.$store.state.users.currentUser.discoverable,
     58       allowFollowingMove: this.$store.state.users.currentUser.allow_following_move,
     59       pickAvatarBtnVisible: true,
     60       bannerUploading: false,
     61       backgroundUploading: false,
     62       banner: null,
     63       bannerPreview: null,
     64       background: null,
     65       backgroundPreview: null,
     66       bannerUploadError: null,
     67       backgroundUploadError: null,
     68       changeEmailError: false,
     69       changeEmailPassword: '',
     70       changedEmail: false,
     71       deletingAccount: false,
     72       deleteAccountConfirmPasswordInput: '',
     73       deleteAccountError: false,
     74       changePasswordInputs: [ '', '', '' ],
     75       changedPassword: false,
     76       changePasswordError: false,
     77       activeTab: 'profile',
     78       notificationSettings: this.$store.state.users.currentUser.notification_settings,
     79       newDomainToMute: ''
     80     }
     81   },
     82   created () {
     83     this.$store.dispatch('fetchTokens')
     84   },
     85   components: {
     86     StyleSwitcher,
     87     ScopeSelector,
     88     TabSwitcher,
     89     ImageCropper,
     90     BlockList,
     91     MuteList,
     92     DomainMuteList,
     93     EmojiInput,
     94     Autosuggest,
     95     BlockCard,
     96     MuteCard,
     97     DomainMuteCard,
     98     ProgressButton,
     99     Importer,
    100     Exporter,
    101     Mfa,
    102     Checkbox
    103   },
    104   computed: {
    105     user () {
    106       return this.$store.state.users.currentUser
    107     },
    108     emojiUserSuggestor () {
    109       return suggestor({
    110         emoji: [
    111           ...this.$store.state.instance.emoji,
    112           ...this.$store.state.instance.customEmoji
    113         ],
    114         users: this.$store.state.users.users,
    115         updateUsersList: (input) => this.$store.dispatch('searchUsers', input)
    116       })
    117     },
    118     emojiSuggestor () {
    119       return suggestor({ emoji: [
    120         ...this.$store.state.instance.emoji,
    121         ...this.$store.state.instance.customEmoji
    122       ] })
    123     },
    124     pleromaBackend () {
    125       return this.$store.state.instance.pleromaBackend
    126     },
    127     minimalScopesMode () {
    128       return this.$store.state.instance.minimalScopesMode
    129     },
    130     vis () {
    131       return {
    132         public: { selected: this.newDefaultScope === 'public' },
    133         unlisted: { selected: this.newDefaultScope === 'unlisted' },
    134         private: { selected: this.newDefaultScope === 'private' },
    135         direct: { selected: this.newDefaultScope === 'direct' }
    136       }
    137     },
    138     currentSaveStateNotice () {
    139       return this.$store.state.interface.settings.currentSaveStateNotice
    140     },
    141     oauthTokens () {
    142       return this.$store.state.oauthTokens.tokens.map(oauthToken => {
    143         return {
    144           id: oauthToken.id,
    145           appName: oauthToken.app_name,
    146           validUntil: new Date(oauthToken.valid_until).toLocaleDateString()
    147         }
    148       })
    149     }
    150   },
    151   methods: {
    152     updateProfile () {
    153       this.$store.state.api.backendInteractor
    154         .updateProfile({
    155           params: {
    156             note: this.newBio,
    157             locked: this.newLocked,
    158             // Backend notation.
    159             /* eslint-disable camelcase */
    160             display_name: this.newName,
    161             default_scope: this.newDefaultScope,
    162             no_rich_text: this.newNoRichText,
    163             hide_follows: this.hideFollows,
    164             hide_followers: this.hideFollowers,
    165             discoverable: this.discoverable,
    166             allow_following_move: this.allowFollowingMove,
    167             hide_follows_count: this.hideFollowsCount,
    168             hide_followers_count: this.hideFollowersCount,
    169             show_role: this.showRole
    170             /* eslint-enable camelcase */
    171           } }).then((user) => {
    172           this.$store.commit('addNewUsers', [user])
    173           this.$store.commit('setCurrentUser', user)
    174         })
    175     },
    176     updateNotificationSettings () {
    177       this.$store.state.api.backendInteractor
    178         .updateNotificationSettings({ settings: this.notificationSettings })
    179     },
    180     changeVis (visibility) {
    181       this.newDefaultScope = visibility
    182     },
    183     uploadFile (slot, e) {
    184       const file = e.target.files[0]
    185       if (!file) { return }
    186       if (file.size > this.$store.state.instance[slot + 'limit']) {
    187         const filesize = fileSizeFormatService.fileSizeFormat(file.size)
    188         const allowedsize = fileSizeFormatService.fileSizeFormat(this.$store.state.instance[slot + 'limit'])
    189         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 })
    190         return
    191       }
    192       // eslint-disable-next-line no-undef
    193       const reader = new FileReader()
    194       reader.onload = ({ target }) => {
    195         const img = target.result
    196         this[slot + 'Preview'] = img
    197         this[slot] = file
    198       }
    199       reader.readAsDataURL(file)
    200     },
    201     submitAvatar (cropper, file) {
    202       const that = this
    203       return new Promise((resolve, reject) => {
    204         function updateAvatar (avatar) {
    205           that.$store.state.api.backendInteractor.updateAvatar({ avatar })
    206             .then((user) => {
    207               that.$store.commit('addNewUsers', [user])
    208               that.$store.commit('setCurrentUser', user)
    209               resolve()
    210             })
    211             .catch((err) => {
    212               reject(new Error(that.$t('upload.error.base') + ' ' + err.message))
    213             })
    214         }
    215 
    216         if (cropper) {
    217           cropper.getCroppedCanvas().toBlob(updateAvatar, file.type)
    218         } else {
    219           updateAvatar(file)
    220         }
    221       })
    222     },
    223     clearUploadError (slot) {
    224       this[slot + 'UploadError'] = null
    225     },
    226     submitBanner () {
    227       if (!this.bannerPreview) { return }
    228 
    229       this.bannerUploading = true
    230       this.$store.state.api.backendInteractor.updateBanner({ banner: this.banner })
    231         .then((user) => {
    232           this.$store.commit('addNewUsers', [user])
    233           this.$store.commit('setCurrentUser', user)
    234           this.bannerPreview = null
    235         })
    236         .catch((err) => {
    237           this.bannerUploadError = this.$t('upload.error.base') + ' ' + err.message
    238         })
    239         .then(() => { this.bannerUploading = false })
    240     },
    241     submitBg () {
    242       if (!this.backgroundPreview) { return }
    243       let background = this.background
    244       this.backgroundUploading = true
    245       this.$store.state.api.backendInteractor.updateBg({ background }).then((data) => {
    246         if (!data.error) {
    247           this.$store.commit('addNewUsers', [data])
    248           this.$store.commit('setCurrentUser', data)
    249           this.backgroundPreview = null
    250         } else {
    251           this.backgroundUploadError = this.$t('upload.error.base') + data.error
    252         }
    253         this.backgroundUploading = false
    254       })
    255     },
    256     importFollows (file) {
    257       return this.$store.state.api.backendInteractor.importFollows({ file })
    258         .then((status) => {
    259           if (!status) {
    260             throw new Error('failed')
    261           }
    262         })
    263     },
    264     importBlocks (file) {
    265       return this.$store.state.api.backendInteractor.importBlocks({ file })
    266         .then((status) => {
    267           if (!status) {
    268             throw new Error('failed')
    269           }
    270         })
    271     },
    272     generateExportableUsersContent (users) {
    273       // Get addresses
    274       return users.map((user) => {
    275         // check is it's a local user
    276         if (user && user.is_local) {
    277           // append the instance address
    278           // eslint-disable-next-line no-undef
    279           return user.screen_name + '@' + location.hostname
    280         }
    281         return user.screen_name
    282       }).join('\n')
    283     },
    284     getFollowsContent () {
    285       return this.$store.state.api.backendInteractor.exportFriends({ id: this.$store.state.users.currentUser.id })
    286         .then(this.generateExportableUsersContent)
    287     },
    288     getBlocksContent () {
    289       return this.$store.state.api.backendInteractor.fetchBlocks()
    290         .then(this.generateExportableUsersContent)
    291     },
    292     confirmDelete () {
    293       this.deletingAccount = true
    294     },
    295     deleteAccount () {
    296       this.$store.state.api.backendInteractor.deleteAccount({ password: this.deleteAccountConfirmPasswordInput })
    297         .then((res) => {
    298           if (res.status === 'success') {
    299             this.$store.dispatch('logout')
    300             this.$router.push({ name: 'root' })
    301           } else {
    302             this.deleteAccountError = res.error
    303           }
    304         })
    305     },
    306     changePassword () {
    307       const params = {
    308         password: this.changePasswordInputs[0],
    309         newPassword: this.changePasswordInputs[1],
    310         newPasswordConfirmation: this.changePasswordInputs[2]
    311       }
    312       this.$store.state.api.backendInteractor.changePassword(params)
    313         .then((res) => {
    314           if (res.status === 'success') {
    315             this.changedPassword = true
    316             this.changePasswordError = false
    317             this.logout()
    318           } else {
    319             this.changedPassword = false
    320             this.changePasswordError = res.error
    321           }
    322         })
    323     },
    324     changeEmail () {
    325       const params = {
    326         email: this.newEmail,
    327         password: this.changeEmailPassword
    328       }
    329       this.$store.state.api.backendInteractor.changeEmail(params)
    330         .then((res) => {
    331           if (res.status === 'success') {
    332             this.changedEmail = true
    333             this.changeEmailError = false
    334           } else {
    335             this.changedEmail = false
    336             this.changeEmailError = res.error
    337           }
    338         })
    339     },
    340     activateTab (tabName) {
    341       this.activeTab = tabName
    342     },
    343     logout () {
    344       this.$store.dispatch('logout')
    345       this.$router.replace('/')
    346     },
    347     revokeToken (id) {
    348       if (window.confirm(`${this.$i18n.t('settings.revoke_token')}?`)) {
    349         this.$store.dispatch('revokeToken', id)
    350       }
    351     },
    352     filterUnblockedUsers (userIds) {
    353       return reject(userIds, (userId) => {
    354         const relationship = this.$store.getters.relationship(this.userId)
    355         return relationship.blocking || userId === this.$store.state.users.currentUser.id
    356       })
    357     },
    358     filterUnMutedUsers (userIds) {
    359       return reject(userIds, (userId) => {
    360         const relationship = this.$store.getters.relationship(this.userId)
    361         return relationship.muting || userId === this.$store.state.users.currentUser.id
    362       })
    363     },
    364     queryUserIds (query) {
    365       return this.$store.dispatch('searchUsers', query)
    366         .then((users) => map(users, 'id'))
    367     },
    368     blockUsers (ids) {
    369       return this.$store.dispatch('blockUsers', ids)
    370     },
    371     unblockUsers (ids) {
    372       return this.$store.dispatch('unblockUsers', ids)
    373     },
    374     muteUsers (ids) {
    375       return this.$store.dispatch('muteUsers', ids)
    376     },
    377     unmuteUsers (ids) {
    378       return this.$store.dispatch('unmuteUsers', ids)
    379     },
    380     unmuteDomains (domains) {
    381       return this.$store.dispatch('unmuteDomains', domains)
    382     },
    383     muteDomain () {
    384       return this.$store.dispatch('muteDomain', this.newDomainToMute)
    385         .then(() => { this.newDomainToMute = '' })
    386     },
    387     identity (value) {
    388       return value
    389     }
    390   }
    391 }
    392 
    393 export default UserSettings