diff options
| author | Shpuld Shpludson <shp@cock.li> | 2019-02-22 14:54:12 +0000 |
|---|---|---|
| committer | Shpuld Shpludson <shp@cock.li> | 2019-02-22 14:54:12 +0000 |
| commit | e34e1ccdae06302ee734414267a357ff5b7c888c (patch) | |
| tree | f1882a022a155a10ad10a3bb92d75f6a4a1f7f5a /src | |
| parent | 3768a4623fc227614b0b3920c2cb92ca16404a69 (diff) | |
| parent | 22851a3a967cc5364a95c71bda48eccc3808bf41 (diff) | |
Merge branch '227-manage-blocks-mutes' into 'develop'
Add Blocks / Mutes management tabs under user settings page
See merge request pleroma/pleroma-fe!578
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/basic_user_card/basic_user_card.js | 28 | ||||
| -rw-r--r-- | src/components/basic_user_card/basic_user_card.vue | 92 | ||||
| -rw-r--r-- | src/components/block_card/block_card.js | 37 | ||||
| -rw-r--r-- | src/components/block_card/block_card.vue | 24 | ||||
| -rw-r--r-- | src/components/mute_card/mute_card.js | 37 | ||||
| -rw-r--r-- | src/components/mute_card/mute_card.vue | 24 | ||||
| -rw-r--r-- | src/components/user_settings/user_settings.js | 30 | ||||
| -rw-r--r-- | src/components/user_settings/user_settings.vue | 6 | ||||
| -rw-r--r-- | src/hocs/with_list/with_list.js | 40 | ||||
| -rw-r--r-- | src/hocs/with_list/with_list.scss | 6 | ||||
| -rw-r--r-- | src/hocs/with_load_more/with_load_more.js | 91 | ||||
| -rw-r--r-- | src/hocs/with_load_more/with_load_more.scss | 10 | ||||
| -rw-r--r-- | src/hocs/with_subscription/with_subscription.js | 84 | ||||
| -rw-r--r-- | src/hocs/with_subscription/with_subscription.scss | 10 | ||||
| -rw-r--r-- | src/i18n/en.json | 12 | ||||
| -rw-r--r-- | src/modules/users.js | 47 | ||||
| -rw-r--r-- | src/services/api/api.service.js | 13 | ||||
| -rw-r--r-- | src/services/backend_interactor_service/backend_interactor_service.js | 2 |
18 files changed, 585 insertions, 8 deletions
diff --git a/src/components/basic_user_card/basic_user_card.js b/src/components/basic_user_card/basic_user_card.js new file mode 100644 index 00000000..a8441446 --- /dev/null +++ b/src/components/basic_user_card/basic_user_card.js @@ -0,0 +1,28 @@ +import UserCardContent from '../user_card_content/user_card_content.vue' +import UserAvatar from '../user_avatar/user_avatar.vue' +import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' + +const BasicUserCard = { + props: [ + 'user' + ], + data () { + return { + userExpanded: false + } + }, + components: { + UserCardContent, + UserAvatar + }, + methods: { + toggleUserExpanded () { + this.userExpanded = !this.userExpanded + }, + userProfileLink (user) { + return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames) + } + } +} + +export default BasicUserCard diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue new file mode 100644 index 00000000..4ede15e9 --- /dev/null +++ b/src/components/basic_user_card/basic_user_card.vue @@ -0,0 +1,92 @@ +<template> + <div class="user-card"> + <router-link :to="userProfileLink(user)"> + <UserAvatar class="avatar" :compact="true" @click.prevent.native="toggleUserExpanded" :src="user.profile_image_url"/> + </router-link> + <div class="user-card-expanded-content" v-if="userExpanded"> + <user-card-content :user="user" :switcher="false"></user-card-content> + </div> + <div class="user-card-collapsed-content" v-else> + <div class="user-card-primary-area"> + <div :title="user.name" class="user-name"> + <span v-if="user.name_html" v-html="user.name_html"></span> + <span v-else>{{ user.name }}</span> + </div> + <div> + <router-link class='user-screen-name' :to="userProfileLink(user)"> + @{{user.screen_name}} + </router-link> + </div> + </div> + <div class="user-card-secondary-area"> + <slot name="secondary-area"></slot> + </div> + </div> + </div> +</template> + +<script src="./basic_user_card.js"></script> + +<style lang="scss"> +@import '../../_variables.scss'; + +.user-card { + display: flex; + flex: 1 0; + padding-top: 0.6em; + padding-right: 1em; + padding-bottom: 0.6em; + padding-left: 1em; + border-bottom: 1px solid; + margin: 0; + border-bottom-color: $fallback--border; + border-bottom-color: var(--border, $fallback--border); + + &-collapsed-content { + margin-left: 0.7em; + text-align: left; + flex: 1; + display: flex; + align-items: flex-start; + justify-content: space-between; + } + + &-primary-area { + flex: 1; + .user-name { + img { + object-fit: contain; + height: 16px; + width: 16px; + vertical-align: middle; + } + } + } + + &-secondary-area { + flex: none; + } + + &-expanded-content { + flex: 1; + margin: 0.2em 0 0 0.7em; + border-radius: $fallback--panelRadius; + border-radius: var(--panelRadius, $fallback--panelRadius); + border-style: solid; + border-color: $fallback--border; + border-color: var(--border, $fallback--border); + border-width: 1px; + overflow: hidden; + + .panel-heading { + background: transparent; + flex-direction: column; + align-items: stretch; + } + + p { + margin-bottom: 0; + } + } +} +</style> diff --git a/src/components/block_card/block_card.js b/src/components/block_card/block_card.js new file mode 100644 index 00000000..11fa27b4 --- /dev/null +++ b/src/components/block_card/block_card.js @@ -0,0 +1,37 @@ +import BasicUserCard from '../basic_user_card/basic_user_card.vue' + +const BlockCard = { + props: ['userId'], + data () { + return { + progress: false + } + }, + computed: { + user () { + return this.$store.getters.userById(this.userId) + }, + blocked () { + return this.user.statusnet_blocking + } + }, + components: { + BasicUserCard + }, + methods: { + unblockUser () { + this.progress = true + this.$store.dispatch('unblockUser', this.user.id).then(() => { + this.progress = false + }) + }, + blockUser () { + this.progress = true + this.$store.dispatch('blockUser', this.user.id).then(() => { + this.progress = false + }) + } + } +} + +export default BlockCard diff --git a/src/components/block_card/block_card.vue b/src/components/block_card/block_card.vue new file mode 100644 index 00000000..ed7fe30b --- /dev/null +++ b/src/components/block_card/block_card.vue @@ -0,0 +1,24 @@ +<template> + <basic-user-card :user="user"> + <template slot="secondary-area"> + <button class="btn btn-default" @click="unblockUser" :disabled="progress" v-if="blocked"> + <template v-if="progress"> + {{ $t('user_card.unblock_progress') }} + </template> + <template v-else> + {{ $t('user_card.unblock') }} + </template> + </button> + <button class="btn btn-default" @click="blockUser" :disabled="progress" v-else> + <template v-if="progress"> + {{ $t('user_card.block_progress') }} + </template> + <template v-else> + {{ $t('user_card.block') }} + </template> + </button> + </template> + </basic-user-card> +</template> + +<script src="./block_card.js"></script>
\ No newline at end of file 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 @@ +<template> + <basic-user-card :user="user"> + <template slot="secondary-area"> + <button class="btn btn-default" @click="unmuteUser" :disabled="progress" v-if="muted"> + <template v-if="progress"> + {{ $t('user_card.unmute_progress') }} + </template> + <template v-else> + {{ $t('user_card.unmute') }} + </template> + </button> + <button class="btn btn-default" @click="muteUser" :disabled="progress" v-else> + <template v-if="progress"> + {{ $t('user_card.mute_progress') }} + </template> + <template v-else> + {{ $t('user_card.mute') }} + </template> + </button> + </template> + </basic-user-card> +</template> + +<script src="./mute_card.js"></script>
\ 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 904060b2..06e72112 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -1,9 +1,33 @@ -import { unescape } from 'lodash' +import { compose } from 'vue-compose' +import unescape from 'lodash/unescape' +import get from 'lodash/get' 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' +import BlockCard from '../block_card/block_card.vue' +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 = compose( + withSubscription({ + fetch: (props, $store) => $store.dispatch('fetchBlocks'), + select: (props, $store) => get($store.state.users.currentUser, 'blockIds', []), + childPropName: 'entries' + }), + withList({ getEntryProps: userId => ({ userId }) }) +)(BlockCard) + +const MuteList = compose( + withSubscription({ + fetch: (props, $store) => $store.dispatch('fetchMutes'), + select: (props, $store) => get($store.state.users.currentUser, 'muteIds', []), + childPropName: 'entries' + }), + withList({ getEntryProps: userId => ({ userId }) }) +)(MuteCard) const UserSettings = { data () { @@ -41,7 +65,9 @@ const UserSettings = { components: { StyleSwitcher, TabSwitcher, - ImageCropper + ImageCropper, + BlockList, + MuteList }, computed: { user () { diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index 948b5c25..983cbda0 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -162,6 +162,12 @@ <h2>{{$t('settings.follow_export_processing')}}</h2> </div> </div> + + <div :label="$t('settings.blocks_tab')"> + <block-list :refresh="true"> + <template slot="empty">{{$t('settings.no_blocks')}}</template> + </block-list> + </div> </tab-switcher> </div> </div> diff --git a/src/hocs/with_list/with_list.js b/src/hocs/with_list/with_list.js new file mode 100644 index 00000000..896f8fc8 --- /dev/null +++ b/src/hocs/with_list/with_list.js @@ -0,0 +1,40 @@ +import Vue from 'vue' +import map from 'lodash/map' +import isEmpty from 'lodash/isEmpty' +import './with_list.scss' + +const defaultEntryPropsGetter = entry => ({ entry }) +const defaultKeyGetter = entry => entry.id + +const withList = ({ + getEntryProps = defaultEntryPropsGetter, // function to accept entry and index values and return props to be passed into the item component + getKey = defaultKeyGetter // funciton to accept entry and index values and return key prop value +}) => (ItemComponent) => ( + Vue.component('withList', { + props: [ + 'entries', // array of entry + 'entryProps', // additional props to be passed into each entry + 'entryListeners' // additional event listeners to be passed into each entry + ], + render (createElement) { + return ( + <div class="with-list"> + {map(this.entries, (entry, index) => { + const props = { + key: getKey(entry, index), + props: { + ...this.$props.entryProps, + ...getEntryProps(entry, index) + }, + on: this.$props.entryListeners + } + return <ItemComponent {...props} /> + })} + {isEmpty(this.entries) && this.$slots.empty && <div class="with-list-empty-content faint">{this.$slots.empty}</div>} + </div> + ) + } + }) +) + +export default withList diff --git a/src/hocs/with_list/with_list.scss b/src/hocs/with_list/with_list.scss new file mode 100644 index 00000000..c6e13d5b --- /dev/null +++ b/src/hocs/with_list/with_list.scss @@ -0,0 +1,6 @@ +.with-list { + &-empty-content { + text-align: center; + padding: 10px; + } +}
\ No newline at end of file diff --git a/src/hocs/with_load_more/with_load_more.js b/src/hocs/with_load_more/with_load_more.js new file mode 100644 index 00000000..e862a39b --- /dev/null +++ b/src/hocs/with_load_more/with_load_more.js @@ -0,0 +1,91 @@ +import Vue from 'vue' +import filter from 'lodash/filter' +import isEmpty from 'lodash/isEmpty' +import './with_load_more.scss' + +const withLoadMore = ({ + fetch, // function to fetch entries and return a promise + select, // function to select data from store + childPropName = 'entries' // name of the prop to be passed into the wrapped component +}) => (WrappedComponent) => { + const originalProps = WrappedComponent.props || [] + const props = filter(originalProps, v => v !== 'entries') + + return Vue.component('withLoadMore', { + render (createElement) { + const props = { + props: { + ...this.$props, + [childPropName]: this.entries + }, + on: this.$listeners, + scopedSlots: this.$scopedSlots + } + const children = Object.entries(this.$slots).map(([key, value]) => createElement('template', { slot: key }, value)) + return ( + <div class="with-load-more"> + <WrappedComponent {...props}> + {children} + </WrappedComponent> + <div class="with-load-more-footer"> + {this.error && <a onClick={this.fetchEntries} class="alert error">{this.$t('general.generic_error')}</a>} + {!this.error && this.loading && <i class="icon-spin3 animate-spin"/>} + {!this.error && !this.loading && !this.bottomedOut && <a onClick={this.fetchEntries}>{this.$t('general.more')}</a>} + </div> + </div> + ) + }, + props, + data () { + return { + loading: false, + bottomedOut: false, + error: false + } + }, + computed: { + entries () { + return select(this.$props, this.$store) || [] + } + }, + created () { + window.addEventListener('scroll', this.scrollLoad) + if (this.entries.length === 0) { + this.fetchEntries() + } + }, + destroyed () { + window.removeEventListener('scroll', this.scrollLoad) + }, + methods: { + fetchEntries () { + if (!this.loading) { + this.loading = true + this.error = false + fetch(this.$props, this.$store) + .then((newEntries) => { + this.loading = false + this.bottomedOut = isEmpty(newEntries) + }) + .catch(() => { + this.loading = false + this.error = true + }) + } + }, + scrollLoad (e) { + const bodyBRect = document.body.getBoundingClientRect() + const height = Math.max(bodyBRect.height, -(bodyBRect.y)) + if (this.loading === false && + this.bottomedOut === false && + this.$el.offsetHeight > 0 && + (window.innerHeight + window.pageYOffset) >= (height - 750) + ) { + this.fetchEntries() + } + } + } + }) +} + +export default withLoadMore diff --git a/src/hocs/with_load_more/with_load_more.scss b/src/hocs/with_load_more/with_load_more.scss new file mode 100644 index 00000000..1a0a9c40 --- /dev/null +++ b/src/hocs/with_load_more/with_load_more.scss @@ -0,0 +1,10 @@ +.with-load-more { + &-footer { + padding: 10px; + text-align: center; + + .error { + font-size: 14px; + } + } +}
\ No newline at end of file diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.js new file mode 100644 index 00000000..1ac67cba --- /dev/null +++ b/src/hocs/with_subscription/with_subscription.js @@ -0,0 +1,84 @@ +import Vue from 'vue' +import reject from 'lodash/reject' +import isEmpty from 'lodash/isEmpty' +import omit from 'lodash/omit' +import './with_subscription.scss' + +const withSubscription = ({ + fetch, // function to fetch entries and return a promise + select, // function to select data from store + childPropName = 'content' // name of the prop to be passed into the wrapped component +}) => (WrappedComponent) => { + const originalProps = WrappedComponent.props || [] + const props = reject(originalProps, v => v === 'content') + + return Vue.component('withSubscription', { + props: [ + ...props, + 'refresh' // boolean saying to force-fetch data whenever created + ], + render (createElement) { + if (!this.error && !this.loading) { + const props = { + props: { + ...omit(this.$props, 'refresh'), + [childPropName]: this.fetchedData + }, + on: this.$listeners, + scopedSlots: this.$scopedSlots + } + const children = Object.entries(this.$slots).map(([key, value]) => createElement('template', { slot: key }, value)) + return ( + <div class="with-subscription"> + <WrappedComponent {...props}> + {children} + </WrappedComponent> + </div> + ) + } else { + return ( + <div class="with-subscription-loading"> + {this.error + ? <a onClick={this.fetchData} class="alert error">{this.$t('general.generic_error')}</a> + : <i class="icon-spin3 animate-spin"/> + } + </div> + ) + } + }, + data () { + return { + loading: false, + error: false + } + }, + computed: { + fetchedData () { + return select(this.$props, this.$store) + } + }, + created () { + if (this.refresh || isEmpty(this.fetchedData)) { + this.fetchData() + } + }, + methods: { + fetchData () { + if (!this.loading) { + this.loading = true + this.error = false + fetch(this.$props, this.$store) + .then(() => { + this.loading = false + }) + .catch(() => { + this.error = true + this.loading = false + }) + } + } + } + }) +} + +export default withSubscription diff --git a/src/hocs/with_subscription/with_subscription.scss b/src/hocs/with_subscription/with_subscription.scss new file mode 100644 index 00000000..52c7d94c --- /dev/null +++ b/src/hocs/with_subscription/with_subscription.scss @@ -0,0 +1,10 @@ +.with-subscription { + &-loading { + padding: 10px; + text-align: center; + + .error { + font-size: 14px; + } + } +}
\ No newline at end of file diff --git a/src/i18n/en.json b/src/i18n/en.json index cf838bae..518e8e0e 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -110,6 +110,7 @@ "avatarRadius": "Avatars", "background": "Background", "bio": "Bio", + "blocks_tab": "Blocks", "btnRadius": "Buttons", "cBlue": "Blue (Reply, follow)", "cGreen": "Green (Retweet)", @@ -164,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", @@ -175,6 +177,8 @@ "notification_visibility_mentions": "Mentions", "notification_visibility_repeats": "Repeats", "no_rich_text_description": "Strip rich text formatting from all posts", + "no_blocks": "No blocks", + "no_mutes": "No mutes", "hide_follows_description": "Don't show who I'm following", "hide_followers_description": "Don't show who's following me", "show_admin_badge": "Show Admin badge in my profile", @@ -366,7 +370,13 @@ "muted": "Muted", "per_day": "per day", "remote_follow": "Remote follow", - "statuses": "Statuses" + "statuses": "Statuses", + "unblock": "Unblock", + "unblock_progress": "Unblocking...", + "block_progress": "Blocking...", + "unmute": "Unmute", + "unmute_progress": "Unmuting...", + "mute_progress": "Muting..." }, "user_profile": { "timeline_title": "User Timeline" diff --git a/src/modules/users.js b/src/modules/users.js index 000cfd72..77df7168 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -85,6 +85,12 @@ export const mutations = { addNewUsers (state, users) { each(users, (user) => mergeOrAdd(state.users, state.usersObject, user)) }, + saveBlocks (state, blockIds) { + state.currentUser.blockIds = blockIds + }, + saveMutes (state, muteIds) { + state.currentUser.muteIds = muteIds + }, setUserForStatus (state, status) { status.user = state.usersObject[status.user.id] }, @@ -137,6 +143,38 @@ const users = { store.rootState.api.backendInteractor.fetchUser({ id }) .then((user) => store.commit('addNewUsers', [user])) }, + fetchBlocks (store) { + return store.rootState.api.backendInteractor.fetchBlocks() + .then((blocks) => { + store.commit('saveBlocks', map(blocks, 'id')) + store.commit('addNewUsers', blocks) + 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])) + }, + 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] @@ -263,6 +301,8 @@ const users = { const user = data // user.credentials = userCredentials user.credentials = accessToken + user.blockIds = [] + user.muteIds = [] commit('setCurrentUser', user) commit('addNewUsers', [user]) @@ -279,11 +319,8 @@ const users = { // Start getting fresh posts. 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) - }) + // Get user mutes + store.dispatch('fetchMutes') // Fetch our friends store.rootState.api.backendInteractor.fetchFriends({ id: user.id }) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 13d31d91..3d2e8823 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -18,6 +18,7 @@ const MENTIONS_URL = '/api/statuses/mentions.json' const DM_TIMELINE_URL = '/api/statuses/dm_timeline.json' const FOLLOWERS_URL = '/api/statuses/followers.json' const FRIENDS_URL = '/api/statuses/friends.json' +const BLOCKS_URL = '/api/statuses/blocks.json' const FOLLOWING_URL = '/api/friendships/create.json' const UNFOLLOWING_URL = '/api/friendships/destroy.json' const QVITTER_USER_PREF_URL = '/api/qvitter/set_profile_pref.json' @@ -519,6 +520,17 @@ const fetchMutes = ({credentials}) => { }).then((data) => data.json()) } +const fetchBlocks = ({page, credentials}) => { + return fetch(BLOCKS_URL, { + headers: authHeaders(credentials) + }).then((data) => { + if (data.ok) { + return data.json() + } + throw new Error('Error fetching blocks', data) + }) +} + const suggestions = ({credentials}) => { return fetch(SUGGESTIONS_URL, { headers: authHeaders(credentials) @@ -560,6 +572,7 @@ const apiService = { fetchAllFollowing, setUserMute, fetchMutes, + fetchBlocks, register, getCaptcha, updateAvatar, diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 80c5cc5e..43c914d9 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -63,6 +63,7 @@ const backendInteractorService = (credentials) => { } const fetchMutes = () => apiService.fetchMutes({credentials}) + const fetchBlocks = (params) => apiService.fetchBlocks({credentials, ...params}) const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials}) const getCaptcha = () => apiService.getCaptcha() @@ -94,6 +95,7 @@ const backendInteractorService = (credentials) => { startFetching, setUserMute, fetchMutes, + fetchBlocks, register, getCaptcha, updateAvatar, |
