From 7bceabb5bda1f7d0737f8f51e0aa07879b7ce72e Mon Sep 17 00:00:00 2001 From: taehoon Date: Tue, 5 Mar 2019 14:01:49 -0500 Subject: Rename UserCardContent to UserCard --- src/components/user_card/user_card.js | 148 ++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/components/user_card/user_card.js (limited to 'src/components/user_card/user_card.js') diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js new file mode 100644 index 00000000..0cb616f4 --- /dev/null +++ b/src/components/user_card/user_card.js @@ -0,0 +1,148 @@ +import UserAvatar from '../user_avatar/user_avatar.vue' +import { hex2rgb } from '../../services/color_convert/color_convert.js' +import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate' +import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' + +export default { + props: [ 'user', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered' ], + data () { + return { + followRequestInProgress: false, + followRequestSent: false, + hideUserStatsLocal: typeof this.$store.state.config.hideUserStats === 'undefined' + ? this.$store.state.instance.hideUserStats + : this.$store.state.config.hideUserStats, + betterShadow: this.$store.state.interface.browserSupport.cssFilter + } + }, + computed: { + classes () { + return [{ + 'user-card-rt': this.rounded === 'top', // set border-top-left-radius and border-top-right-radius + 'user-card-r': this.rounded === true, // set border-radius for all sides + 'user-card-b': this.bordered === true // set border for all sides + }] + }, + style () { + const color = this.$store.state.config.customTheme.colors + ? this.$store.state.config.customTheme.colors.bg // v2 + : this.$store.state.config.colors.bg // v1 + + 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, ${gradient})`, + `url(${this.user.cover_photo})` + ].join(', ') + } + } + }, + isOtherUser () { + return this.user.id !== this.$store.state.users.currentUser.id + }, + subscribeUrl () { + // eslint-disable-next-line no-undef + const serverUrl = new URL(this.user.statusnet_profile_url) + return `${serverUrl.protocol}//${serverUrl.host}/main/ostatus` + }, + loggedIn () { + return this.$store.state.users.currentUser + }, + dailyAvg () { + const days = Math.ceil((new Date() - new Date(this.user.created_at)) / (60 * 60 * 24 * 1000)) + return Math.round(this.user.statuses_count / days) + }, + userHighlightType: { + get () { + const data = this.$store.state.config.highlight[this.user.screen_name] + return data && data.type || 'disabled' + }, + set (type) { + const data = this.$store.state.config.highlight[this.user.screen_name] + if (type !== 'disabled') { + this.$store.dispatch('setHighlight', { user: this.user.screen_name, color: data && data.color || '#FFFFFF', type }) + } else { + this.$store.dispatch('setHighlight', { user: this.user.screen_name, color: undefined }) + } + } + }, + userHighlightColor: { + get () { + const data = this.$store.state.config.highlight[this.user.screen_name] + return data && data.color + }, + set (color) { + this.$store.dispatch('setHighlight', { user: this.user.screen_name, color }) + } + }, + visibleRole () { + const validRole = (this.user.role === 'admin' || this.user.role === 'moderator') + const showRole = this.isOtherUser || this.user.show_role + + return validRole && showRole && this.user.role + } + }, + components: { + UserAvatar + }, + methods: { + followUser () { + this.followRequestInProgress = true + requestFollow(this.user, this.$store).then(({sent}) => { + this.followRequestInProgress = false + this.followRequestSent = sent + }) + }, + unfollowUser () { + this.followRequestInProgress = true + requestUnfollow(this.user, this.$store).then(() => { + this.followRequestInProgress = false + }) + }, + blockUser () { + const store = this.$store + store.state.api.backendInteractor.blockUser(this.user.id) + .then((blockedUser) => store.commit('addNewUsers', [blockedUser])) + }, + unblockUser () { + const store = this.$store + store.state.api.backendInteractor.unblockUser(this.user.id) + .then((unblockedUser) => store.commit('addNewUsers', [unblockedUser])) + }, + toggleMute () { + const store = this.$store + store.commit('setMuted', {user: this.user, muted: !this.user.muted}) + store.state.api.backendInteractor.setUserMute(this.user) + }, + setProfileView (v) { + if (this.switcher) { + const store = this.$store + store.commit('setProfileView', { v }) + } + }, + linkClicked ({target}) { + if (target.tagName === 'SPAN') { + target = target.parentNode + } + if (target.tagName === 'A') { + window.open(target.href, '_blank') + } + }, + userProfileLink (user) { + return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames) + } + } +} -- cgit v1.2.3-70-g09d2 From 5f51fe897dcd7d32c46a67a8d31c8b4ffc8858b2 Mon Sep 17 00:00:00 2001 From: taehoon Date: Tue, 5 Mar 2019 21:52:04 -0500 Subject: Revert modifier class notation --- src/components/user_card/user_card.js | 6 +++--- src/components/user_card/user_card.vue | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src/components/user_card/user_card.js') diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index 0cb616f4..81c938c0 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -18,9 +18,9 @@ export default { computed: { classes () { return [{ - 'user-card-rt': this.rounded === 'top', // set border-top-left-radius and border-top-right-radius - 'user-card-r': this.rounded === true, // set border-radius for all sides - 'user-card-b': this.bordered === true // set border for all sides + 'user-card-rounded-t': this.rounded === 'top', // set border-top-left-radius and border-top-right-radius + 'user-card-rounded': this.rounded === true, // set border-radius for all sides + 'user-card-bordered': this.bordered === true // set border for all sides }] }, style () { diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index b90f57a1..cc2ce6b8 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -161,22 +161,21 @@ text-align: center; } - // // Modifiers - &-rt { + &-rounded-t { border-top-left-radius: $fallback--panelRadius; border-top-left-radius: var(--panelRadius, $fallback--panelRadius); border-top-right-radius: $fallback--panelRadius; border-top-right-radius: var(--panelRadius, $fallback--panelRadius); } - &-r { + &-rounded { border-radius: $fallback--panelRadius; border-radius: var(--panelRadius, $fallback--panelRadius); } - &-b { + &-bordered { border-width: 1px; border-style: solid; border-color: $fallback--border; -- cgit v1.2.3-70-g09d2 From ee49409049430dedf042ddbeb73898f605664cd2 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Fri, 8 Mar 2019 00:35:30 +0200 Subject: Partially transitioned user data to MastoAPI. Added support for fetching relationship data. Upgraded code to be more resilient to nulls caused by missing data in either APIs --- src/components/user_card/user_card.js | 3 ++ src/components/user_profile/user_profile.js | 3 ++ src/modules/statuses.js | 6 ++-- src/modules/users.js | 32 ++++++++++++++++++---- src/services/api/api.service.js | 20 ++++++++++++-- .../backend_interactor_service.js | 5 ++++ 6 files changed, 59 insertions(+), 10 deletions(-) (limited to 'src/components/user_card/user_card.js') diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index 80d15a27..43a77f45 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -15,6 +15,9 @@ export default { betterShadow: this.$store.state.interface.browserSupport.cssFilter } }, + created () { + this.$store.dispatch('fetchUserRelationship', this.user.id) + }, computed: { classes () { return [{ diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js index 54126514..345e7035 100644 --- a/src/components/user_profile/user_profile.js +++ b/src/components/user_profile/user_profile.js @@ -43,6 +43,7 @@ const UserProfile = { this.startFetchFavorites() if (!this.user.id) { this.$store.dispatch('fetchUser', this.fetchBy) + .then(() => this.$store.dispatch('fetchUserRelationship', this.fetchBy)) .catch((reason) => { const errorMessage = get(reason, 'error.error') if (errorMessage === 'No user with such user_id') { // Known error @@ -53,6 +54,8 @@ const UserProfile = { this.error = this.$t('user_profile.profile_loading_error') } }) + } else if (typeof this.user.following === 'undefined' || this.user.following === null) { + this.$store.dispatch('fetchUserRelationship', this.fetchBy) } }, destroyed () { diff --git a/src/modules/statuses.js b/src/modules/statuses.js index 7571b62a..2b0215f0 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -1,4 +1,4 @@ -import { remove, slice, each, find, maxBy, minBy, merge, first, last, isArray } from 'lodash' +import { remove, slice, each, find, maxBy, minBy, merge, first, last, isArray, omitBy } from 'lodash' import apiService from '../services/api/api.service.js' // import parse from '../services/status_parser/status_parser.js' @@ -72,7 +72,9 @@ const mergeOrAdd = (arr, obj, item) => { if (oldItem) { // We already have this, so only merge the new info. - merge(oldItem, item) + // We ignore null values to avoid overwriting existing properties with missing data + // we also skip 'used' because that is handled by users module + merge(oldItem, omitBy(item, (v, k) => v === null || k === 'user')) // Reactivity fix. oldItem.attachments.splice(oldItem.attachments.length) return {item: oldItem, new: false} diff --git a/src/modules/users.js b/src/modules/users.js index 4159964c..a81ed964 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, omitBy } from 'lodash' import { set } from 'vue' import { registerPushNotifications, unregisterPushNotifications } from '../services/push/push.js' import oauthApi from '../services/new_api/oauth' @@ -11,7 +11,7 @@ export const mergeOrAdd = (arr, obj, item) => { const oldItem = obj[item.id] if (oldItem) { // We already have this, so only merge the new info. - merge(oldItem, item) + merge(oldItem, omitBy(item, _ => _ === null)) return { item: oldItem, new: false } } else { // This is a new item, prepare it @@ -39,7 +39,7 @@ export const mutations = { }, setCurrentUser (state, user) { state.lastLoginName = user.screen_name - state.currentUser = merge(state.currentUser || {}, user) + state.currentUser = merge(state.currentUser || {}, omitBy(user, _ => _ === null)) }, clearCurrentUser (state) { state.currentUser = false @@ -91,6 +91,16 @@ export const mutations = { addNewUsers (state, users) { each(users, (user) => mergeOrAdd(state.users, state.usersObject, user)) }, + updateUserRelationship (state, relationships) { + relationships.forEach((relationship) => { + const user = state.usersObject[relationship.id] + + user.follows_you = relationship.followed_by + user.following = relationship.following + user.muted = relationship.muting + user.statusnet_blocking = relationship.blocking + }) + }, saveBlocks (state, blockIds) { state.currentUser.blockIds = blockIds }, @@ -98,11 +108,17 @@ export const mutations = { state.currentUser.muteIds = muteIds }, setUserForStatus (state, status) { - status.user = state.usersObject[status.user.id] + // Not setting it again since it's already reactive if it has getters + if (!Object.getOwnPropertyDescriptor(status.user, 'id').get) { + status.user = state.usersObject[status.user.id] + } }, setUserForNotification (state, notification) { - notification.action.user = state.usersObject[notification.action.user.id] - notification.from_profile = state.usersObject[notification.action.user.id] + // Not setting it again since it's already reactive if it has getters + if (!Object.getOwnPropertyDescriptor(notification.action.user, 'id').get) { + notification.action.user = state.usersObject[notification.action.user.id] + notification.from_profile = state.usersObject[notification.action.user.id] + } }, setColor (state, { user: { id }, highlighted }) { const user = state.usersObject[id] @@ -149,6 +165,10 @@ const users = { return store.rootState.api.backendInteractor.fetchUser({ id }) .then((user) => store.commit('addNewUsers', [user])) }, + fetchUserRelationship (store, id) { + return store.rootState.api.backendInteractor.fetchUserRelationship({ id }) + .then((relationships) => store.commit('updateUserRelationship', relationships)) + }, fetchBlocks (store) { return store.rootState.api.backendInteractor.fetchBlocks() .then((blocks) => { diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 2de87026..d512b120 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -33,7 +33,6 @@ const QVITTER_USER_NOTIFICATIONS_URL = '/api/qvitter/statuses/notifications.json const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json' const BLOCKING_URL = '/api/blocks/create.json' const UNBLOCKING_URL = '/api/blocks/destroy.json' -const USER_URL = '/api/users/show.json' const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import' const DELETE_ACCOUNT_URL = '/api/pleroma/delete_account' const CHANGE_PASSWORD_URL = '/api/pleroma/change_password' @@ -43,6 +42,8 @@ const DENY_USER_URL = '/api/pleroma/friendships/deny' const SUGGESTIONS_URL = '/api/v1/suggestions' const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites' +const MASTODON_USER_URL = '/api/v1/accounts/' +const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships' import { each, map } from 'lodash' import { parseStatus, parseUser, parseNotification } from '../entity_normalizer/entity_normalizer.service.js' @@ -243,7 +244,7 @@ const denyUser = ({id, credentials}) => { } const fetchUser = ({id, credentials}) => { - let url = `${USER_URL}?user_id=${id}` + let url = `${MASTODON_USER_URL}/${id}` return fetch(url, { headers: authHeaders(credentials) }) .then((response) => { return new Promise((resolve, reject) => response.json() @@ -257,6 +258,20 @@ const fetchUser = ({id, credentials}) => { .then((data) => parseUser(data)) } +const fetchUserRelationship = ({id, credentials}) => { + let url = `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}` + return fetch(url, { headers: authHeaders(credentials) }) + .then((response) => { + return new Promise((resolve, reject) => response.json() + .then((json) => { + if (!response.ok) { + return reject(new StatusCodeError(response.status, json, { url }, response)) + } + return resolve(json) + })) + }) +} + const fetchFriends = ({id, page, credentials}) => { let url = `${FRIENDS_URL}?user_id=${id}` if (page) { @@ -588,6 +603,7 @@ const apiService = { blockUser, unblockUser, fetchUser, + fetchUserRelationship, favorite, unfavorite, retweet, diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 7e972d7b..cbd0b733 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -30,6 +30,10 @@ const backendInteractorService = (credentials) => { return apiService.fetchUser({id, credentials}) } + const fetchUserRelationship = ({id}) => { + return apiService.fetchUserRelationship({id, credentials}) + } + const followUser = (id) => { return apiService.followUser({credentials, id}) } @@ -92,6 +96,7 @@ const backendInteractorService = (credentials) => { blockUser, unblockUser, fetchUser, + fetchUserRelationship, fetchAllFollowing, verifyCredentials: apiService.verifyCredentials, startFetching, -- cgit v1.2.3-70-g09d2 From 07b8115a37a22b2a7d935154e8231c8a90f199d6 Mon Sep 17 00:00:00 2001 From: dave Date: Tue, 19 Mar 2019 14:36:27 -0400 Subject: #444 - show `remote follow` button when logged out --- src/components/follow_card/follow_card.js | 7 ++++++- src/components/follow_card/follow_card.vue | 9 ++++++--- src/components/remote_follow/remote_follow.js | 10 ++++++++++ src/components/remote_follow/remote_follow.vue | 26 ++++++++++++++++++++++++++ src/components/user_card/user_card.js | 4 +++- src/components/user_card/user_card.vue | 15 ++------------- 6 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 src/components/remote_follow/remote_follow.js create mode 100644 src/components/remote_follow/remote_follow.vue (limited to 'src/components/user_card/user_card.js') diff --git a/src/components/follow_card/follow_card.js b/src/components/follow_card/follow_card.js index 425c9c3e..ac4e265a 100644 --- a/src/components/follow_card/follow_card.js +++ b/src/components/follow_card/follow_card.js @@ -1,4 +1,5 @@ import BasicUserCard from '../basic_user_card/basic_user_card.vue' +import RemoteFollow from '../remote_follow/remote_follow.vue' import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate' const FollowCard = { @@ -14,13 +15,17 @@ const FollowCard = { } }, components: { - BasicUserCard + BasicUserCard, + RemoteFollow }, computed: { isMe () { return this.$store.state.users.currentUser.id === this.user.id }, following () { return this.updated ? this.updated.following : this.user.following }, showFollow () { return !this.following || this.updated && !this.updated.following + }, + loggedIn () { + return this.$store.state.users.currentUser } }, methods: { diff --git a/src/components/follow_card/follow_card.vue b/src/components/follow_card/follow_card.vue index 6cb064eb..9bd21cfd 100644 --- a/src/components/follow_card/follow_card.vue +++ b/src/components/follow_card/follow_card.vue @@ -4,9 +4,12 @@ {{ isMe ? $t('user_card.its_you') : $t('user_card.follows_you') }} +
+ +
+ + + + + + + diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index 43a77f45..b07da675 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -1,4 +1,5 @@ import UserAvatar from '../user_avatar/user_avatar.vue' +import RemoteFollow from '../remote_follow/remote_follow.vue' import { hex2rgb } from '../../services/color_convert/color_convert.js' import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' @@ -99,7 +100,8 @@ export default { } }, components: { - UserAvatar + UserAvatar, + RemoteFollow }, methods: { followUser () { diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index 690e1bde..f4114e6e 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -84,14 +84,8 @@ -
-
- - - -
+
+
@@ -375,11 +369,6 @@ min-height: 28px; } - .remote-follow { - max-width: 220px; - min-height: 28px; - } - .follow { max-width: 220px; min-height: 28px; -- cgit v1.2.3-70-g09d2 From 3255950b0e9a16f2a477d606b91d90bed8a6cef7 Mon Sep 17 00:00:00 2001 From: taehoon Date: Sun, 24 Feb 2019 03:02:04 -0500 Subject: Add mute/unmute featrue and mutes management tab --- src/components/mute_card/mute_card.js | 2 +- src/components/user_card/user_card.js | 20 +++++----- src/components/user_card/user_card.vue | 4 +- src/components/user_settings/user_settings.vue | 6 +++ src/modules/users.js | 32 ++++++++++------ src/services/api/api.service.js | 44 ++++++++++++++++++++-- .../backend_interactor_service.js | 6 ++- src/utils/url.js | 9 +++++ 8 files changed, 93 insertions(+), 30 deletions(-) create mode 100644 src/utils/url.js (limited to 'src/components/user_card/user_card.js') diff --git a/src/components/mute_card/mute_card.js b/src/components/mute_card/mute_card.js index 65c9cfb5..5ef17b60 100644 --- a/src/components/mute_card/mute_card.js +++ b/src/components/mute_card/mute_card.js @@ -12,7 +12,7 @@ const MuteCard = { return this.$store.getters.findUser(this.userId) }, muted () { - return this.user.muted + return this.user.mastodonMuted } }, components: { diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index b07da675..61b784fe 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -121,21 +121,19 @@ export default { }) }, blockUser () { - const store = this.$store - store.state.api.backendInteractor.blockUser(this.user.id) - .then((blockedUser) => { - store.commit('addNewUsers', [blockedUser]) - store.commit('removeStatus', { timeline: 'friends', userId: this.user.id }) - store.commit('removeStatus', { timeline: 'public', userId: this.user.id }) - store.commit('removeStatus', { timeline: 'publicAndExternal', userId: this.user.id }) - }) + this.$store.dispatch('blockUser', this.user.id) }, unblockUser () { - const store = this.$store - store.state.api.backendInteractor.unblockUser(this.user.id) - .then((unblockedUser) => store.commit('addNewUsers', [unblockedUser])) + this.$store.dispatch('unblockUser', this.user.id) + }, + muteUser () { // Mastodon Mute + this.$store.dispatch('muteUser', this.user.id) + }, + unmuteUser () { // Mastodon Unmute + this.$store.dispatch('unmuteUser', this.user.id) }, toggleMute () { + // TODO: Pleroma mute/unmute, Need to migrate to the Mastodon API const store = this.$store store.commit('setMuted', {user: this.user, muted: !this.user.muted}) store.state.api.backendInteractor.setUserMute(this.user) diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index f4114e6e..3259d1c5 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -74,12 +74,12 @@
- - diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index a1123638..c9e68808 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -192,6 +192,12 @@
+ +
+ + + +
diff --git a/src/modules/users.js b/src/modules/users.js index 1fe12fc8..9c89f34a 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -177,9 +177,14 @@ const users = { return blocks }) }, - blockUser (store, id) { - return store.rootState.api.backendInteractor.blockUser(id) - .then((user) => store.commit('addNewUsers', [user])) + blockUser (store, userId) { + return store.rootState.api.backendInteractor.blockUser(userId) + .then((blockedUser) => { + store.commit('addNewUsers', [blockedUser]) + store.commit('removeStatus', { timeline: 'friends', userId }) + store.commit('removeStatus', { timeline: 'public', userId }) + store.commit('removeStatus', { timeline: 'publicAndExternal', userId }) + }) }, unblockUser (store, id) { return store.rootState.api.backendInteractor.unblockUser(id) @@ -188,18 +193,26 @@ const users = { fetchMutes (store) { return store.rootState.api.backendInteractor.fetchMutes() .then((mutedUsers) => { - each(mutedUsers, (user) => { user.muted = true }) + each(mutedUsers, (user) => { user.mastodonMuted = 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])) + return store.rootState.api.backendInteractor.muteUser(id) + .then(() => { + const user = store.rootState.users.usersObject[id] + set(user, 'mastodonMuted', true) + store.commit('addNewUsers', [user]) + }) }, unmuteUser (store, id) { - return store.state.api.backendInteractor.setUserMute({ id, muted: false }) - .then((user) => store.commit('addNewUsers', [user])) + return store.rootState.api.backendInteractor.unmuteUser(id) + .then(() => { + const user = store.rootState.users.usersObject[id] + set(user, 'mastodonMuted', false) + store.commit('addNewUsers', [user]) + }) }, addFriends ({ rootState, commit }, fetchBy) { return new Promise((resolve, reject) => { @@ -350,9 +363,6 @@ const users = { // Start getting fresh posts. store.dispatch('startFetching', { timeline: 'friends' }) - // Get user mutes - store.dispatch('fetchMutes') - // Fetch our friends store.rootState.api.backendInteractor.fetchFriends({ id: user.id }) .then((friends) => commit('addNewUsers', friends)) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 176f1c18..92abf94b 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -1,3 +1,5 @@ +import { generateUrl } from '../../utils/url' + /* eslint-env browser */ const LOGIN_URL = '/api/account/verify_credentials.json' const FRIENDS_TIMELINE_URL = '/api/statuses/friends_timeline.json' @@ -19,6 +21,9 @@ 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 MUTES_URL = '/api/v1/mutes.json' +const MUTING_URL = '/api/v1/accounts/:id/mute' +const UNMUTING_URL = '/api/v1/accounts/:id/unmute' 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' @@ -538,14 +543,43 @@ const changePassword = ({credentials, password, newPassword, newPasswordConfirma } const fetchMutes = ({credentials}) => { - const url = '/api/qvitter/mutes.json' + return fetch(MUTES_URL, { + headers: authHeaders(credentials) + }).then((data) => { + if (data.ok) { + return data.json() + } + throw new Error('Error fetching mutes', data) + }) +} +const muteUser = ({id, credentials}) => { + const url = generateUrl(MUTING_URL, { id }) return fetch(url, { - headers: authHeaders(credentials) - }).then((data) => data.json()) + headers: authHeaders(credentials), + method: 'POST' + }).then((data) => { + if (data.ok) { + return data.json() + } + throw new Error('Error muting', data) + }) +} + +const unmuteUser = ({id, credentials}) => { + const url = generateUrl(UNMUTING_URL, { id }) + return fetch(url, { + headers: authHeaders(credentials), + method: 'POST' + }).then((data) => { + if (data.ok) { + return data.json() + } + throw new Error('Error unmuting', data) + }) } -const fetchBlocks = ({page, credentials}) => { +const fetchBlocks = ({credentials}) => { return fetch(BLOCKS_URL, { headers: authHeaders(credentials) }).then((data) => { @@ -620,6 +654,8 @@ const apiService = { fetchAllFollowing, setUserMute, fetchMutes, + muteUser, + unmuteUser, fetchBlocks, fetchOAuthTokens, revokeOAuthToken, diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index cbd0b733..674fb4a4 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -67,7 +67,9 @@ const backendInteractorService = (credentials) => { } const fetchMutes = () => apiService.fetchMutes({credentials}) - const fetchBlocks = (params) => apiService.fetchBlocks({credentials, ...params}) + const muteUser = (id) => apiService.muteUser({credentials, id}) + const unmuteUser = (id) => apiService.unmuteUser({credentials, id}) + const fetchBlocks = () => apiService.fetchBlocks({credentials}) const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials}) const fetchOAuthTokens = () => apiService.fetchOAuthTokens({credentials}) const revokeOAuthToken = (id) => apiService.revokeOAuthToken({id, credentials}) @@ -102,6 +104,8 @@ const backendInteractorService = (credentials) => { startFetching, setUserMute, fetchMutes, + muteUser, + unmuteUser, fetchBlocks, fetchOAuthTokens, revokeOAuthToken, diff --git a/src/utils/url.js b/src/utils/url.js new file mode 100644 index 00000000..79ea7394 --- /dev/null +++ b/src/utils/url.js @@ -0,0 +1,9 @@ +// Generate url based on template +// Example: /api/v1/accounts/:id/mute -> /api/v1/accounts/123/mute +export const generateUrl = (template, params = {}) => { + let url = template + Object.entries(params).forEach(([key, value]) => { + url = url.replace(':' + key, value) + }) + return url +} -- cgit v1.2.3-70-g09d2 From 302310a653083bc82226cf0743d52fc02c277a8a Mon Sep 17 00:00:00 2001 From: taehoon Date: Fri, 1 Mar 2019 11:37:34 -0500 Subject: Remove old muting logic --- src/components/mute_card/mute_card.js | 2 +- src/components/user_card/user_card.js | 10 ++-------- src/modules/users.js | 12 +++++++++--- src/services/api/api.service.js | 18 ------------------ .../backend_interactor_service.js | 5 ----- 5 files changed, 12 insertions(+), 35 deletions(-) (limited to 'src/components/user_card/user_card.js') diff --git a/src/components/mute_card/mute_card.js b/src/components/mute_card/mute_card.js index 5ef17b60..65c9cfb5 100644 --- a/src/components/mute_card/mute_card.js +++ b/src/components/mute_card/mute_card.js @@ -12,7 +12,7 @@ const MuteCard = { return this.$store.getters.findUser(this.userId) }, muted () { - return this.user.mastodonMuted + return this.user.muted } }, components: { diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index 61b784fe..197c61d5 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -126,18 +126,12 @@ export default { unblockUser () { this.$store.dispatch('unblockUser', this.user.id) }, - muteUser () { // Mastodon Mute + muteUser () { this.$store.dispatch('muteUser', this.user.id) }, - unmuteUser () { // Mastodon Unmute + unmuteUser () { this.$store.dispatch('unmuteUser', this.user.id) }, - toggleMute () { - // TODO: Pleroma mute/unmute, Need to migrate to the Mastodon API - const store = this.$store - store.commit('setMuted', {user: this.user, muted: !this.user.muted}) - store.state.api.backendInteractor.setUserMute(this.user) - }, setProfileView (v) { if (this.switcher) { const store = this.$store diff --git a/src/modules/users.js b/src/modules/users.js index af40be3d..5e53aafb 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -110,11 +110,11 @@ export const mutations = { }, muteUser (state, id) { const user = state.usersObject[id] - set(user, 'mastodonMuted', true) + set(user, 'muted', true) }, unmuteUser (state, id) { const user = state.usersObject[id] - set(user, 'mastodonMuted', false) + set(user, 'muted', false) }, setUserForStatus (state, status) { status.user = state.usersObject[status.user.id] @@ -206,9 +206,10 @@ const users = { return Promise.all(promises) }) .then((mutedUsers) => { - each(mutedUsers, (user) => { user.mastodonMuted = true }) + each(mutedUsers, (user) => { user.muted = true }) store.commit('addNewUsers', mutedUsers) store.commit('saveMutes', map(mutedUsers, 'id')) + // TODO: Unset muted property of the rest users }) }, muteUser (store, id) { @@ -368,6 +369,11 @@ const users = { // Start getting fresh posts. store.dispatch('startFetching', { timeline: 'friends' }) + // Fetch mutes + // TODO: We should not show timeline until fetchMutes is resolved + // However, we can get rid of this logic totally if we can know user muted state from user object + store.dispatch('fetchMutes') + // Fetch our friends store.rootState.api.backendInteractor.fetchFriends({ id: user.id }) .then((friends) => commit('addNewUsers', friends)) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 92abf94b..7da2758a 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -26,7 +26,6 @@ const MUTING_URL = '/api/v1/accounts/:id/mute' const UNMUTING_URL = '/api/v1/accounts/:id/unmute' 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' const REGISTRATION_URL = '/api/account/register.json' const AVATAR_UPDATE_URL = '/api/qvitter/update_avatar.json' const BG_UPDATE_URL = '/api/qvitter/update_background_image.json' @@ -343,22 +342,6 @@ const fetchStatus = ({id, credentials}) => { .then((data) => parseStatus(data)) } -const setUserMute = ({id, credentials, muted = true}) => { - const form = new FormData() - - const muteInteger = muted ? 1 : 0 - - form.append('namespace', 'qvitter') - form.append('data', muteInteger) - form.append('topic', `mute:${id}`) - - return fetch(QVITTER_USER_PREF_URL, { - method: 'POST', - headers: authHeaders(credentials), - body: form - }) -} - const fetchTimeline = ({timeline, credentials, since = false, until = false, userId = false, tag = false}) => { const timelineUrls = { public: PUBLIC_TIMELINE_URL, @@ -652,7 +635,6 @@ const apiService = { deleteStatus, uploadMedia, fetchAllFollowing, - setUserMute, fetchMutes, muteUser, unmuteUser, diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 674fb4a4..0f0bcddc 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -62,10 +62,6 @@ const backendInteractorService = (credentials) => { return timelineFetcherService.startFetching({timeline, store, credentials, userId, tag}) } - const setUserMute = ({id, muted = true}) => { - return apiService.setUserMute({id, muted, credentials}) - } - const fetchMutes = () => apiService.fetchMutes({credentials}) const muteUser = (id) => apiService.muteUser({credentials, id}) const unmuteUser = (id) => apiService.unmuteUser({credentials, id}) @@ -102,7 +98,6 @@ const backendInteractorService = (credentials) => { fetchAllFollowing, verifyCredentials: apiService.verifyCredentials, startFetching, - setUserMute, fetchMutes, muteUser, unmuteUser, -- cgit v1.2.3-70-g09d2