From 13725f040bca346a7b35b832f36f4e86c5da11e4 Mon Sep 17 00:00:00 2001 From: taehoon Date: Thu, 7 Feb 2019 03:05:59 -0500 Subject: Add avatar crop popup --- src/components/user_settings/user_settings.js | 29 ++++++--------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'src/components/user_settings/user_settings.js') diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index d20bf308..b3d31d67 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -1,6 +1,7 @@ import { unescape } from 'lodash' import TabSwitcher from '../tab_switcher/tab_switcher.js' +import ImageCropper from '../image_cropper/image_cropper.vue' import StyleSwitcher from '../style_switcher/style_switcher.vue' import fileSizeFormatService from '../../services/file_size_format/file_size_format.js' @@ -24,7 +25,6 @@ const UserSettings = { bannerUploading: false, backgroundUploading: false, followListUploading: false, - avatarPreview: null, bannerPreview: null, backgroundPreview: null, avatarUploadError: null, @@ -41,7 +41,8 @@ const UserSettings = { }, components: { StyleSwitcher, - TabSwitcher + TabSwitcher, + ImageCropper }, computed: { user () { @@ -117,31 +118,13 @@ const UserSettings = { } reader.readAsDataURL(file) }, - submitAvatar () { - if (!this.avatarPreview) { return } - - let img = this.avatarPreview - // eslint-disable-next-line no-undef - let imginfo = new Image() - let cropX, cropY, cropW, cropH - imginfo.src = img - if (imginfo.height > imginfo.width) { - cropX = 0 - cropW = imginfo.width - cropY = Math.floor((imginfo.height - imginfo.width) / 2) - cropH = imginfo.width - } else { - cropY = 0 - cropH = imginfo.height - cropX = Math.floor((imginfo.width - imginfo.height) / 2) - cropW = imginfo.height - } + submitAvatar (cropper) { + const img = cropper.getCroppedCanvas({ width: 150, height: 150 }).toDataURL('image/jpeg') this.avatarUploading = true - this.$store.state.api.backendInteractor.updateAvatar({params: {img, cropX, cropY, cropW, cropH}}).then((user) => { + this.$store.state.api.backendInteractor.updateAvatar({ params: { img } }).then((user) => { if (!user.error) { this.$store.commit('addNewUsers', [user]) this.$store.commit('setCurrentUser', user) - this.avatarPreview = null } else { this.avatarUploadError = this.$t('upload.error.base') + user.error } -- cgit v1.2.3-70-g09d2 From 09949fc7eea10e592339fd620d140eb92a18e28b Mon Sep 17 00:00:00 2001 From: taehoon Date: Fri, 8 Feb 2019 11:01:50 -0500 Subject: Crop avatar image using minWidth/minHeight --- src/components/user_settings/user_settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/components/user_settings/user_settings.js') diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index b3d31d67..8987c691 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -119,7 +119,7 @@ const UserSettings = { reader.readAsDataURL(file) }, submitAvatar (cropper) { - const img = cropper.getCroppedCanvas({ width: 150, height: 150 }).toDataURL('image/jpeg') + const img = cropper.getCroppedCanvas({ minWidth: 150, minHeight: 150 }).toDataURL('image/jpeg') this.avatarUploading = true this.$store.state.api.backendInteractor.updateAvatar({ params: { img } }).then((user) => { if (!user.error) { -- cgit v1.2.3-70-g09d2 From b24db12e1cc318e862169355a22f051d3ea2e809 Mon Sep 17 00:00:00 2001 From: taehoon Date: Fri, 8 Feb 2019 21:59:33 -0500 Subject: Make embedded image cropper --- src/components/image_cropper/image_cropper.js | 37 ++++++++++++++-------- src/components/image_cropper/image_cropper.vue | 25 ++++++++------- src/components/user_settings/user_settings.js | 9 ++---- src/components/user_settings/user_settings.vue | 43 ++++---------------------- src/i18n/en.json | 5 +-- 5 files changed, 50 insertions(+), 69 deletions(-) (limited to 'src/components/user_settings/user_settings.js') diff --git a/src/components/image_cropper/image_cropper.js b/src/components/image_cropper/image_cropper.js index b2580240..4eaa08d4 100644 --- a/src/components/image_cropper/image_cropper.js +++ b/src/components/image_cropper/image_cropper.js @@ -1,5 +1,4 @@ import Cropper from 'cropperjs' -import Modal from '../modal/modal.vue' import 'cropperjs/dist/cropper.css' const ImageCropper = { @@ -8,6 +7,10 @@ const ImageCropper = { type: [String, window.Element], required: true }, + submitHandler: { + type: Function, + required: true + }, cropperOptions: { type: Object, default () { @@ -25,10 +28,10 @@ const ImageCropper = { type: String, default: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' }, - title: { + saveButtonLabel: { type: String }, - saveButtonLabel: { + cancelButtonLabel: { type: String } }, @@ -36,18 +39,17 @@ const ImageCropper = { return { cropper: undefined, dataUrl: undefined, - filename: undefined + filename: undefined, + submitting: false, + submitError: null } }, - components: { - Modal - }, computed: { - modalTitle () { - return this.title || this.$t('image_cropper.crop_picture') - }, - modalSaveButtonLabel () { + saveText () { return this.saveButtonLabel || this.$t('image_cropper.save') + }, + cancelText () { + return this.cancelButtonLabel || this.$t('image_cropper.cancel') } }, methods: { @@ -57,10 +59,15 @@ const ImageCropper = { } this.$refs.input.value = '' this.dataUrl = undefined + this.$emit('close') }, submit () { - this.$emit('submit', this.cropper, this.filename) - this.destroy() + this.submitting = true + this.avatarUploadError = null + this.submitHandler(this.cropper, this.filename) + .then(() => this.destroy()) + .catch(err => this.submitError = err) + .finally(() => this.submitting = false) }, pickImage () { this.$refs.input.click() @@ -77,11 +84,15 @@ const ImageCropper = { let reader = new window.FileReader() reader.onload = (e) => { this.dataUrl = e.target.result + this.$emit('open') } reader.readAsDataURL(fileInput.files[0]) this.filename = fileInput.files[0].name || 'unknown' this.$emit('changed', fileInput.files[0], reader) } + }, + clearError () { + this.submitError = null } }, mounted () { diff --git a/src/components/image_cropper/image_cropper.vue b/src/components/image_cropper/image_cropper.vue index b2367128..aa895863 100644 --- a/src/components/image_cropper/image_cropper.vue +++ b/src/components/image_cropper/image_cropper.vue @@ -1,15 +1,19 @@ @@ -31,9 +35,8 @@ } } - &-btn { - display: block; - width: 100%; + &-buttons-wrapper { + margin-top: 15px; } } diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 8987c691..2d521c14 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -21,13 +21,12 @@ const UserSettings = { followImportError: false, followsImported: false, enableFollowsExport: true, - avatarUploading: false, + pickAvatarBtnVisible: true, bannerUploading: false, backgroundUploading: false, followListUploading: false, bannerPreview: null, backgroundPreview: null, - avatarUploadError: null, bannerUploadError: null, backgroundUploadError: null, deletingAccount: false, @@ -120,15 +119,13 @@ const UserSettings = { }, submitAvatar (cropper) { const img = cropper.getCroppedCanvas({ minWidth: 150, minHeight: 150 }).toDataURL('image/jpeg') - this.avatarUploading = true - this.$store.state.api.backendInteractor.updateAvatar({ params: { img } }).then((user) => { + return this.$store.state.api.backendInteractor.updateAvatar({ params: { img } }).then((user) => { if (!user.error) { this.$store.commit('addNewUsers', [user]) this.$store.commit('setCurrentUser', user) } else { - this.avatarUploadError = this.$t('upload.error.base') + user.error + throw this.$t('upload.error.base') + user.error } - this.avatarUploading = false }) }, clearUploadError (slot) { diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index 9fcd3752..8ab92e95 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -47,20 +47,11 @@

{{$t('settings.avatar')}}

{{$t('settings.avatar_size_instruction')}}

-
-
- -
- -
-
-
- -
- Error: {{ avatarUploadError }} - -
- +

{{$t('settings.current_avatar')}}

+ +

{{$t('settings.set_new_avatar')}}

+ +

{{$t('settings.profile_banner')}}

@@ -196,29 +187,7 @@ max-width: 100%; } - .avatar-upload { - display: inline-block; - position: relative; - } - - .avatar-upload-loading-wrapper { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: flex; - justify-content: center; - align-items: center; - background: rgba(0,0,0,.3); - - i { - font-size: 50px; - color: #FFF; - } - } - - .avatar { + .current-avatar { display: block; width: 150px; height: 150px; diff --git a/src/i18n/en.json b/src/i18n/en.json index 3e9ac157..af62acfc 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -23,7 +23,8 @@ }, "image_cropper": { "crop_picture": "Crop picture", - "save": "Save" + "save": "Save", + "cancel": "Cancel" }, "login": { "login": "Log in", @@ -116,7 +117,6 @@ "collapse_subject": "Collapse posts with subjects", "composing": "Composing", "confirm_new_password": "Confirm new password", - "crop_your_new_avatar": "Crop your new avatar", "current_avatar": "Your current avatar", "current_password": "Current password", "current_profile_banner": "Your current profile banner", @@ -211,6 +211,7 @@ "theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.", "theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.", "tooltipRadius": "Tooltips/alerts", + "upload_a_photo": "Upload a photo", "user_settings": "User Settings", "values": { "false": "no", -- cgit v1.2.3-70-g09d2 From 2132d58075c71bd8a445288d052cc05e321fdf24 Mon Sep 17 00:00:00 2001 From: taehoon Date: Fri, 8 Feb 2019 22:06:02 -0500 Subject: Remove cropped image size restriction --- src/components/user_settings/user_settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/components/user_settings/user_settings.js') diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 2d521c14..c1c60102 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -118,7 +118,7 @@ const UserSettings = { reader.readAsDataURL(file) }, submitAvatar (cropper) { - const img = cropper.getCroppedCanvas({ minWidth: 150, minHeight: 150 }).toDataURL('image/jpeg') + const img = cropper.getCroppedCanvas().toDataURL('image/jpeg') return this.$store.state.api.backendInteractor.updateAvatar({ params: { img } }).then((user) => { if (!user.error) { this.$store.commit('addNewUsers', [user]) -- cgit v1.2.3-70-g09d2 From 2de756aa0c27ae5267032e07c2e1f998d49d0df5 Mon Sep 17 00:00:00 2001 From: taehoon Date: Fri, 8 Feb 2019 22:17:53 -0500 Subject: Better error handling --- src/components/image_cropper/image_cropper.js | 3 +++ src/components/image_cropper/image_cropper.vue | 2 +- src/components/user_settings/user_settings.js | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/components/user_settings/user_settings.js') diff --git a/src/components/image_cropper/image_cropper.js b/src/components/image_cropper/image_cropper.js index 4eaa08d4..da94427a 100644 --- a/src/components/image_cropper/image_cropper.js +++ b/src/components/image_cropper/image_cropper.js @@ -50,6 +50,9 @@ const ImageCropper = { }, cancelText () { return this.cancelButtonLabel || this.$t('image_cropper.cancel') + }, + submitErrorMsg () { + return this.submitError && this.submitError instanceof Error ? this.submitError.toString() : this.submitError } }, methods: { diff --git a/src/components/image_cropper/image_cropper.vue b/src/components/image_cropper/image_cropper.vue index aa895863..24a6f3bd 100644 --- a/src/components/image_cropper/image_cropper.vue +++ b/src/components/image_cropper/image_cropper.vue @@ -10,7 +10,7 @@
- Error: {{ submitError }} + {{submitErrorMsg}}
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index c1c60102..dce3eeed 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -124,7 +124,7 @@ const UserSettings = { this.$store.commit('addNewUsers', [user]) this.$store.commit('setCurrentUser', user) } else { - throw this.$t('upload.error.base') + user.error + throw new Error(this.$t('upload.error.base') + user.error) } }) }, -- cgit v1.2.3-70-g09d2 From 63cfe051c7f5419da3942632f3a5453f6cd5c769 Mon Sep 17 00:00:00 2001 From: dave Date: Tue, 19 Feb 2019 12:38:49 -0500 Subject: #371: show notification when user setting's saved --- src/components/user_settings/user_settings.js | 3 +++ src/components/user_settings/user_settings.vue | 15 ++++++++++++++- src/lib/persisted_state.js | 4 ++-- 3 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src/components/user_settings/user_settings.js') diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index d20bf308..3ad711c2 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -60,6 +60,9 @@ const UserSettings = { private: { selected: this.newDefaultScope === 'private' }, direct: { selected: this.newDefaultScope === 'direct' } } + }, + currentSaveStateNotice () { + return this.$store.state.interface.settings.currentSaveStateNotice } }, methods: { diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index d2381da2..d1770562 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -1,7 +1,20 @@ diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 3bcecdf4..621dcd4b 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -9,7 +9,7 @@ import BlockCard from '../block_card/block_card.vue' import withLoadMore from '../../hocs/with_load_more/with_load_more' import withList from '../../hocs/with_list/with_list' -const BlockList = withList(BlockCard, entry => ({ user: entry })) +const BlockList = withList(BlockCard, entry => ({ userId: entry.id })) const BlockListWithLoadMore = withLoadMore( BlockList, (props, $store) => $store.dispatch('fetchBlocks'), diff --git a/src/i18n/en.json b/src/i18n/en.json index 9027803d..eeb95f9c 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -368,7 +368,8 @@ "remote_follow": "Remote follow", "statuses": "Statuses", "unblock": "Unblock", - "unblock_progress": "Unblocking..." + "unblock_progress": "Unblocking...", + "block_progress": "Blocking..." }, "user_profile": { "timeline_title": "User Timeline" diff --git a/src/modules/users.js b/src/modules/users.js index 6ea4e0c9..ce8af68c 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -154,6 +154,14 @@ const users = { return blocks }) }, + blockUser (store, id) { + return store.rootState.api.backendInteractor.blockUser(id) + .then((user) => store.commit('addNewUsers', [user])) + }, + unblockUser (store, id) { + return store.rootState.api.backendInteractor.unblockUser(id) + .then((user) => store.commit('addNewUsers', [user])) + }, addFriends ({ rootState, commit }, fetchBy) { return new Promise((resolve, reject) => { const user = rootState.users.usersObject[fetchBy] -- cgit v1.2.3-70-g09d2 From 8c8a6edc7800bac854ef23f29aa87f5b932cb415 Mon Sep 17 00:00:00 2001 From: taehoon Date: Wed, 13 Feb 2019 21:08:14 -0500 Subject: Remove pagination support from block-list --- src/components/user_settings/user_settings.js | 10 ++++++---- src/components/user_settings/user_settings.vue | 2 +- src/modules/users.js | 17 ++++++----------- .../entity_normalizer/entity_normalizer.service.js | 2 +- 4 files changed, 14 insertions(+), 17 deletions(-) (limited to 'src/components/user_settings/user_settings.js') diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 621dcd4b..8eade382 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -7,13 +7,15 @@ import StyleSwitcher from '../style_switcher/style_switcher.vue' import fileSizeFormatService from '../../services/file_size_format/file_size_format.js' import BlockCard from '../block_card/block_card.vue' import withLoadMore from '../../hocs/with_load_more/with_load_more' +import withSubscription from '../../hocs/with_subscription/with_subscription' import withList from '../../hocs/with_list/with_list' -const BlockList = withList(BlockCard, entry => ({ userId: entry.id })) -const BlockListWithLoadMore = withLoadMore( +const BlockList = withList(BlockCard, userId => ({ userId })) +const BlockListWithSubscription = withSubscription( BlockList, (props, $store) => $store.dispatch('fetchBlocks'), - (props, $store) => get($store.state.users.currentUser, 'blocks', []) + (props, $store) => get($store.state.users.currentUser, 'blockIds', []), + 'entries' ) const UserSettings = { @@ -53,7 +55,7 @@ const UserSettings = { StyleSwitcher, TabSwitcher, ImageCropper, - 'block-list': BlockListWithLoadMore + 'block-list': BlockListWithSubscription }, computed: { user () { diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index be9f27e7..5cf21815 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -164,7 +164,7 @@
- +
diff --git a/src/modules/users.js b/src/modules/users.js index ce8af68c..1f03b47e 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -1,5 +1,5 @@ import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' -import { compact, map, each, merge, find } from 'lodash' +import { compact, map, each, merge, find, union } from 'lodash' import { set } from 'vue' import { registerPushNotifications, unregisterPushNotifications } from '../services/push/push.js' import oauthApi from '../services/new_api/oauth' @@ -85,14 +85,9 @@ export const mutations = { addNewUsers (state, users) { each(users, (user) => mergeOrAdd(state.users, state.usersObject, user)) }, - addBlocks (state, { blocks, page }) { + addBlocks (state, blockIds) { const user = state.currentUser - each(blocks, block => { - if (!find(user.blocks, { id: block.id })) { - user.blocks.push(block) - } - }) - user.blocksPage = page + 1 + user.blockIds = union(user.blockIds, blockIds) }, setUserForStatus (state, status) { status.user = state.usersObject[status.user.id] @@ -147,10 +142,10 @@ const users = { .then((user) => store.commit('addNewUsers', [user])) }, fetchBlocks (store) { - const page = store.state.currentUser.blocksPage || 1 - return store.rootState.api.backendInteractor.fetchBlocks({ page }) + return store.rootState.api.backendInteractor.fetchBlocks() .then((blocks) => { - store.commit('addBlocks', { blocks, page }) + store.commit('addBlocks', map(blocks, 'id')) + store.commit('addNewUsers', blocks) return blocks }) }, diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 1192b6cc..0e1be61e 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -120,7 +120,7 @@ export const parseUser = (data) => { if (data.pleroma) { output.follow_request_count = data.pleroma.follow_request_count } - output.blocks = [] + output.blockIds = [] return output } -- cgit v1.2.3-70-g09d2 From e91a94ff9c4b9559f53a4b001f8972ceca843771 Mon Sep 17 00:00:00 2001 From: taehoon Date: Wed, 13 Feb 2019 22:04:28 -0500 Subject: Add mutes tab --- src/components/mute_card/mute_card.js | 37 ++++++++++++++++++++++ src/components/mute_card/mute_card.vue | 24 ++++++++++++++ src/components/user_settings/user_settings.js | 13 ++++++-- src/components/user_settings/user_settings.vue | 4 +++ src/i18n/en.json | 1 + src/modules/users.js | 25 ++++++++++++--- .../entity_normalizer/entity_normalizer.service.js | 1 + 7 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 src/components/mute_card/mute_card.js create mode 100644 src/components/mute_card/mute_card.vue (limited to 'src/components/user_settings/user_settings.js') diff --git a/src/components/mute_card/mute_card.js b/src/components/mute_card/mute_card.js new file mode 100644 index 00000000..5dd0a9e5 --- /dev/null +++ b/src/components/mute_card/mute_card.js @@ -0,0 +1,37 @@ +import BasicUserCard from '../basic_user_card/basic_user_card.vue' + +const MuteCard = { + props: ['userId'], + data () { + return { + progress: false + } + }, + computed: { + user () { + return this.$store.getters.userById(this.userId) + }, + muted () { + return this.user.muted + } + }, + components: { + BasicUserCard + }, + methods: { + unmuteUser () { + this.progress = true + this.$store.dispatch('unmuteUser', this.user.id).then(() => { + this.progress = false + }) + }, + muteUser () { + this.progress = true + this.$store.dispatch('muteUser', this.user.id).then(() => { + this.progress = false + }) + } + } +} + +export default MuteCard diff --git a/src/components/mute_card/mute_card.vue b/src/components/mute_card/mute_card.vue new file mode 100644 index 00000000..e1bfe20b --- /dev/null +++ b/src/components/mute_card/mute_card.vue @@ -0,0 +1,24 @@ + + + \ No newline at end of file diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 8eade382..8114d5e2 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -6,7 +6,7 @@ import ImageCropper from '../image_cropper/image_cropper.vue' import StyleSwitcher from '../style_switcher/style_switcher.vue' import fileSizeFormatService from '../../services/file_size_format/file_size_format.js' import BlockCard from '../block_card/block_card.vue' -import withLoadMore from '../../hocs/with_load_more/with_load_more' +import MuteCard from '../mute_card/mute_card.vue' import withSubscription from '../../hocs/with_subscription/with_subscription' import withList from '../../hocs/with_list/with_list' @@ -18,6 +18,14 @@ const BlockListWithSubscription = withSubscription( 'entries' ) +const MuteList = withList(MuteCard, userId => ({ userId })) +const MuteListWithSubscription = withSubscription( + MuteList, + (props, $store) => $store.dispatch('fetchMutes'), + (props, $store) => get($store.state.users.currentUser, 'muteIds', []), + 'entries' +) + const UserSettings = { data () { return { @@ -55,7 +63,8 @@ const UserSettings = { StyleSwitcher, TabSwitcher, ImageCropper, - 'block-list': BlockListWithSubscription + 'block-list': BlockListWithSubscription, + 'mute-list': MuteListWithSubscription }, computed: { user () { diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index 5bae583c..27f3e7cb 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -166,6 +166,10 @@
+ +
+ +
diff --git a/src/i18n/en.json b/src/i18n/en.json index eeb95f9c..b41b6db9 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -165,6 +165,7 @@ "lock_account_description": "Restrict your account to approved followers only", "loop_video": "Loop videos", "loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")", + "mutes_tab": "Mutes", "play_videos_in_modal": "Play videos directly in the media viewer", "use_contain_fit": "Don't crop the attachment in thumbnails", "name": "Name", diff --git a/src/modules/users.js b/src/modules/users.js index 1f03b47e..71201a77 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -89,6 +89,10 @@ export const mutations = { const user = state.currentUser user.blockIds = union(user.blockIds, blockIds) }, + saveMutes (state, ids) { + const user = state.currentUser + user.muteIds = union(user.muteIds, ids) + }, setUserForStatus (state, status) { status.user = state.usersObject[status.user.id] }, @@ -157,6 +161,22 @@ const users = { return store.rootState.api.backendInteractor.unblockUser(id) .then((user) => store.commit('addNewUsers', [user])) }, + fetchMutes (store) { + return store.rootState.api.backendInteractor.fetchMutes() + .then((mutedUsers) => { + each(mutedUsers, (user) => { user.muted = true }) + store.commit('addNewUsers', mutedUsers) + store.commit('saveMutes', map(mutedUsers, 'id')) + }) + }, + muteUser (store, id) { + return store.state.api.backendInteractor.setUserMute({ id, muted: true }) + .then((user) => store.commit('addNewUsers', [user])) + }, + unmuteUser (store, id) { + return store.state.api.backendInteractor.setUserMute({ id, muted: false }) + .then((user) => store.commit('addNewUsers', [user])) + }, addFriends ({ rootState, commit }, fetchBy) { return new Promise((resolve, reject) => { const user = rootState.users.usersObject[fetchBy] @@ -300,10 +320,7 @@ const users = { store.dispatch('startFetching', { timeline: 'friends' }) // Get user mutes and follower info - store.rootState.api.backendInteractor.fetchMutes().then((mutedUsers) => { - each(mutedUsers, (user) => { user.muted = true }) - store.commit('addNewUsers', mutedUsers) - }) + store.dispatch('fetchMutes') // Fetch our friends store.rootState.api.backendInteractor.fetchFriends({ id: user.id }) diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 0e1be61e..49c83811 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -121,6 +121,7 @@ export const parseUser = (data) => { output.follow_request_count = data.pleroma.follow_request_count } output.blockIds = [] + output.muteIds = [] return output } -- cgit v1.2.3-70-g09d2 From f81b82b4714643ba396b69ca54b97259a36a6b9f Mon Sep 17 00:00:00 2001 From: taehoon Date: Wed, 13 Feb 2019 22:52:57 -0500 Subject: Use hoc definitions to be factor of factory --- src/components/user_settings/user_settings.js | 26 ++++++++++++------------- src/hocs/with_list/with_list.js | 8 ++++---- src/hocs/with_load_more/with_load_more.js | 6 +++--- src/hocs/with_subscription/with_subscription.js | 6 +++--- 4 files changed, 22 insertions(+), 24 deletions(-) (limited to 'src/components/user_settings/user_settings.js') diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 8114d5e2..21023841 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -10,21 +10,19 @@ import MuteCard from '../mute_card/mute_card.vue' import withSubscription from '../../hocs/with_subscription/with_subscription' import withList from '../../hocs/with_list/with_list' -const BlockList = withList(BlockCard, userId => ({ userId })) -const BlockListWithSubscription = withSubscription( - BlockList, - (props, $store) => $store.dispatch('fetchBlocks'), - (props, $store) => get($store.state.users.currentUser, 'blockIds', []), - 'entries' -) +const BlockList = withList({ getEntryProps: userId => ({ userId }) })(BlockCard) +const BlockListWithSubscription = withSubscription({ + fetch: (props, $store) => $store.dispatch('fetchBlocks'), + select: (props, $store) => get($store.state.users.currentUser, 'blockIds', []), + contentPropName: 'entries' +})(BlockList) -const MuteList = withList(MuteCard, userId => ({ userId })) -const MuteListWithSubscription = withSubscription( - MuteList, - (props, $store) => $store.dispatch('fetchMutes'), - (props, $store) => get($store.state.users.currentUser, 'muteIds', []), - 'entries' -) +const MuteList = withList({ getEntryProps: userId => ({ userId }) })(MuteCard) +const MuteListWithSubscription = withSubscription({ + fetch: (props, $store) => $store.dispatch('fetchMutes'), + select: (props, $store) => get($store.state.users.currentUser, 'muteIds', []), + contentPropName: 'entries' +})(MuteList) const UserSettings = { data () { diff --git a/src/hocs/with_list/with_list.js b/src/hocs/with_list/with_list.js index 5ec37a2b..c31cdcb1 100644 --- a/src/hocs/with_list/with_list.js +++ b/src/hocs/with_list/with_list.js @@ -4,8 +4,8 @@ import map from 'lodash/map' const defaultEntryPropsGetter = entry => ({ entry }) const defaultKeyGetter = entry => entry.id -const withList = (Component, getEntryProps = defaultEntryPropsGetter, getKey = defaultKeyGetter) => { - return Vue.component('withList', { +const withList = ({ getEntryProps = defaultEntryPropsGetter, getKey = defaultKeyGetter }) => (ItemComponent) => ( + Vue.component('withList', { render (createElement) { return (
@@ -18,13 +18,13 @@ const withList = (Component, getEntryProps = defaultEntryPropsGetter, getKey = d }, on: this.$props.entryListeners } - return + return })}
) }, props: ['entries', 'entryProps', 'entryListeners'] }) -} +) export default withList diff --git a/src/hocs/with_load_more/with_load_more.js b/src/hocs/with_load_more/with_load_more.js index 8877f8d3..28c741e3 100644 --- a/src/hocs/with_load_more/with_load_more.js +++ b/src/hocs/with_load_more/with_load_more.js @@ -3,8 +3,8 @@ import filter from 'lodash/filter' import isEmpty from 'lodash/isEmpty' import './with_load_more.scss' -const withLoadMore = (Component, fetch, select, entriesPropName = 'entries') => { - const originalProps = Component.props || [] +const withLoadMore = ({ fetch, select, entriesPropName = 'entries' }) => (WrappedComponent) => { + const originalProps = WrappedComponent.props || [] const props = filter(originalProps, v => v !== 'entries') return Vue.component('withLoadMore', { @@ -18,7 +18,7 @@ const withLoadMore = (Component, fetch, select, entriesPropName = 'entries') => } return (
- +