diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/App.scss | 25 | ||||
| -rw-r--r-- | src/components/attachment/attachment.vue | 2 | ||||
| -rw-r--r-- | src/components/moderation_tools/moderation_tools.vue | 6 | ||||
| -rw-r--r-- | src/components/progress_button/progress_button.vue | 2 | ||||
| -rw-r--r-- | src/components/user_card/user_card.js | 10 | ||||
| -rw-r--r-- | src/components/user_card/user_card.vue | 213 | ||||
| -rw-r--r-- | src/components/user_profile/user_profile.js | 2 | ||||
| -rw-r--r-- | src/i18n/en.json | 2 | ||||
| -rw-r--r-- | src/modules/users.js | 9 | ||||
| -rw-r--r-- | src/services/api/api.service.js | 12 | ||||
| -rw-r--r-- | src/services/backend_interactor_service/backend_interactor_service.js | 4 | ||||
| -rw-r--r-- | src/services/entity_normalizer/entity_normalizer.service.js | 1 |
12 files changed, 173 insertions, 115 deletions
diff --git a/src/App.scss b/src/App.scss index e4c764bf..1299e05d 100644 --- a/src/App.scss +++ b/src/App.scss @@ -283,6 +283,31 @@ i[class*=icon-] { color: var(--icon, $fallback--icon) } +.btn-block { + display: block; + width: 100%; +} + +.btn-group { + position: relative; + display: inline-flex; + vertical-align: middle; + + button { + position: relative; + flex: 1 1 auto; + + &:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + &:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + } +} .container { display: flex; diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue index 108dc36e..ec326c45 100644 --- a/src/components/attachment/attachment.vue +++ b/src/components/attachment/attachment.vue @@ -100,7 +100,7 @@ <!-- eslint-disable vue/no-v-html --> <h1><a :href="attachment.url">{{ attachment.oembed.title }}</a></h1> <div v-html="attachment.oembed.oembedHTML" /> - <!-- eslint-enabled vue/no-v-html --> + <!-- eslint-enable vue/no-v-html --> </div> </div> </div> diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue index c6f8354b..f1ab67a6 100644 --- a/src/components/moderation_tools/moderation_tools.vue +++ b/src/components/moderation_tools/moderation_tools.vue @@ -1,8 +1,5 @@ <template> - <div - class="block" - style="position: relative" - > + <div> <Popper trigger="click" append-to-body @@ -131,6 +128,7 @@ </div> <button slot="reference" + class="btn btn-default btn-block" :class="{ pressed: showDropDown }" @click="toggleMenu" > diff --git a/src/components/progress_button/progress_button.vue b/src/components/progress_button/progress_button.vue index d19aa97d..283a51af 100644 --- a/src/components/progress_button/progress_button.vue +++ b/src/components/progress_button/progress_button.vue @@ -3,7 +3,7 @@ :disabled="progress || disabled" @click="onClick" > - <template v-if="progress"> + <template v-if="progress && $slots.progress"> <slot name="progress" /> </template> <template v-else> diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index 92cd0e54..e019ebbd 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -1,5 +1,6 @@ import UserAvatar from '../user_avatar/user_avatar.vue' import RemoteFollow from '../remote_follow/remote_follow.vue' +import ProgressButton from '../progress_button/progress_button.vue' import ModerationTools from '../moderation_tools/moderation_tools.vue' import { hex2rgb } from '../../services/color_convert/color_convert.js' import { requestFollow, requestUnfollow } from '../../services/follow_manipulate/follow_manipulate' @@ -104,7 +105,8 @@ export default { components: { UserAvatar, RemoteFollow, - ModerationTools + ModerationTools, + ProgressButton }, methods: { followUser () { @@ -135,6 +137,12 @@ export default { unmuteUser () { this.$store.dispatch('unmuteUser', this.user.id) }, + subscribeUser () { + return this.$store.dispatch('subscribeUser', this.user.id) + }, + unsubscribeUser () { + return this.$store.dispatch('unsubscribeUser', this.user.id) + }, setProfileView (v) { if (this.switcher) { const store = this.$store diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index 5a5a4881..f987fbbb 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -112,101 +112,120 @@ </div> </div> <div - v-if="isOtherUser" + v-if="loggedIn && isOtherUser" class="user-interactions" > - <div - v-if="loggedIn" - class="follow" - > - <span v-if="user.following"> - <!--Following them!--> - <button - class="pressed" - :disabled="followRequestInProgress" - :title="$t('user_card.follow_unfollow')" - @click="unfollowUser" - > - <template v-if="followRequestInProgress"> - {{ $t('user_card.follow_progress') }} - </template> - <template v-else> - {{ $t('user_card.following') }} - </template> - </button> - </span> - <span v-if="!user.following"> - <button - :disabled="followRequestInProgress" - :title="followRequestSent ? $t('user_card.follow_again') : ''" - @click="followUser" - > - <template v-if="followRequestInProgress"> - {{ $t('user_card.follow_progress') }} - </template> - <template v-else-if="followRequestSent"> - {{ $t('user_card.follow_sent') }} - </template> - <template v-else> - {{ $t('user_card.follow') }} - </template> - </button> - </span> + <div v-if="!user.following"> + <button + class="btn btn-default btn-block" + :disabled="followRequestInProgress" + :title="followRequestSent ? $t('user_card.follow_again') : ''" + @click="followUser" + > + <template v-if="followRequestInProgress"> + {{ $t('user_card.follow_progress') }} + </template> + <template v-else-if="followRequestSent"> + {{ $t('user_card.follow_sent') }} + </template> + <template v-else> + {{ $t('user_card.follow') }} + </template> + </button> + </div> + <div v-else-if="followRequestInProgress"> + <button + class="btn btn-default btn-block pressed" + disabled + :title="$t('user_card.follow_unfollow')" + @click="unfollowUser" + > + {{ $t('user_card.follow_progress') }} + </button> </div> <div - v-if="isOtherUser && loggedIn" - class="mute" + v-else + class="btn-group" > - <span v-if="user.muted"> - <button - class="pressed" - @click="unmuteUser" - > - {{ $t('user_card.muted') }} - </button> - </span> - <span v-if="!user.muted"> - <button @click="muteUser"> - {{ $t('user_card.mute') }} - </button> - </span> + <button + class="btn btn-default pressed" + :title="$t('user_card.follow_unfollow')" + @click="unfollowUser" + > + {{ $t('user_card.following') }} + </button> + <ProgressButton + v-if="!user.subscribed" + class="btn btn-default" + :click="subscribeUser" + :title="$t('user_card.subscribe')" + > + <i class="icon-bell-alt" /> + </ProgressButton> + <ProgressButton + v-else + class="btn btn-default pressed" + :click="unsubscribeUser" + :title="$t('user_card.unsubscribe')" + > + <i class="icon-bell-ringing-o" /> + </ProgressButton> </div> - <div v-if="!loggedIn && user.is_local"> - <RemoteFollow :user="user" /> + + <div> + <button + v-if="user.muted" + class="btn btn-default btn-block pressed" + @click="unmuteUser" + > + {{ $t('user_card.muted') }} + </button> + <button + v-else + class="btn btn-default btn-block" + @click="muteUser" + > + {{ $t('user_card.mute') }} + </button> </div> - <div - v-if="isOtherUser && loggedIn" - class="block" - > - <span v-if="user.statusnet_blocking"> - <button - class="pressed" - @click="unblockUser" - > - {{ $t('user_card.blocked') }} - </button> - </span> - <span v-if="!user.statusnet_blocking"> - <button @click="blockUser"> - {{ $t('user_card.block') }} - </button> - </span> + + <div> + <button + v-if="user.statusnet_blocking" + class="btn btn-default btn-block pressed" + @click="unblockUser" + > + {{ $t('user_card.blocked') }} + </button> + <button + v-else + class="btn btn-default btn-block" + @click="blockUser" + > + {{ $t('user_card.block') }} + </button> </div> - <div - v-if="isOtherUser && loggedIn" - class="block" - > - <span> - <button @click="reportUser"> - {{ $t('user_card.report') }} - </button> - </span> + + <div> + <button + class="btn btn-default btn-block" + @click="reportUser" + > + {{ $t('user_card.report') }} + </button> </div> + <ModerationTools v-if="loggedIn.role === "admin"" :user="user" /> </div> + <div + v-if="!loggedIn && user.is_local" + class="user-interactions" + > + <RemoteFollow :user="user" /> + </div> </div> </div> <div @@ -487,40 +506,22 @@ display: flex; flex-flow: row wrap; justify-content: space-between; - margin-right: -.75em; - div { + > * { flex: 1 0 0; - margin-right: .75em; - margin-bottom: .6em; + margin: 0 .75em .6em 0; white-space: nowrap; } - .mute { - max-width: 220px; - min-height: 28px; - } - - .follow { - max-width: 220px; - min-height: 28px; - } - button { - width: 100%; - height: 100%; margin: 0; - } - - .remote-button { - height: 28px !important; - width: 92%; - } - .pressed { - border-bottom-color: rgba(255, 255, 255, 0.2); - border-top-color: rgba(0, 0, 0, 0.2); + &.pressed { + // TODO: This should be themed. + border-bottom-color: rgba(255, 255, 255, 0.2); + border-top-color: rgba(0, 0, 0, 0.2); + } } } } diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js index 7eb4ed3a..39b99dac 100644 --- a/src/components/user_profile/user_profile.js +++ b/src/components/user_profile/user_profile.js @@ -3,7 +3,6 @@ import UserCard from '../user_card/user_card.vue' import FollowCard from '../follow_card/follow_card.vue' import Timeline from '../timeline/timeline.vue' import Conversation from '../conversation/conversation.vue' -import ModerationTools from '../moderation_tools/moderation_tools.vue' import List from '../list/list.vue' import withLoadMore from '../../hocs/with_load_more/with_load_more' @@ -132,7 +131,6 @@ const UserProfile = { Timeline, FollowerList, FriendList, - ModerationTools, FollowCard, Conversation } diff --git a/src/i18n/en.json b/src/i18n/en.json index dd34a95d..49989f78 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -529,6 +529,8 @@ "remote_follow": "Remote follow", "report": "Report", "statuses": "Statuses", + "subscribe": "Subscribe", + "unsubscribe": "Unsubscribe", "unblock": "Unblock", "unblock_progress": "Unblocking...", "block_progress": "Blocking...", diff --git a/src/modules/users.js b/src/modules/users.js index 453a6899..57d3a3e3 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -135,6 +135,7 @@ export const mutations = { user.following = relationship.following user.muted = relationship.muting user.statusnet_blocking = relationship.blocking + user.subscribed = relationship.subscribing } }) }, @@ -304,6 +305,14 @@ const users = { clearFollowers ({ commit }, userId) { commit('clearFollowers', userId) }, + subscribeUser ({ rootState, commit }, id) { + return rootState.api.backendInteractor.subscribeUser(id) + .then((relationship) => commit('updateUserRelationship', [relationship])) + }, + unsubscribeUser ({ rootState, commit }, id) { + return rootState.api.backendInteractor.unsubscribeUser(id) + .then((relationship) => commit('updateUserRelationship', [relationship])) + }, registerPushNotifications (store) { const token = store.state.currentUser.credentials const vapidPublicKey = store.rootState.instance.vapidPublicKey diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 304fc869..e417cf29 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -55,6 +55,8 @@ const MASTODON_BLOCK_USER_URL = id => `/api/v1/accounts/${id}/block` const MASTODON_UNBLOCK_USER_URL = id => `/api/v1/accounts/${id}/unblock` const MASTODON_MUTE_USER_URL = id => `/api/v1/accounts/${id}/mute` const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute` +const MASTODON_SUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/subscribe` +const MASTODON_UNSUBSCRIBE_USER = id => `/api/v1/pleroma/accounts/${id}/unsubscribe` const MASTODON_POST_STATUS_URL = '/api/v1/statuses' const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media' const MASTODON_VOTE_URL = id => `/api/v1/polls/${id}/votes` @@ -752,6 +754,14 @@ const unmuteUser = ({ id, credentials }) => { return promisedRequest({ url: MASTODON_UNMUTE_USER_URL(id), credentials, method: 'POST' }) } +const subscribeUser = ({ id, credentials }) => { + return promisedRequest({ url: MASTODON_SUBSCRIBE_USER(id), credentials, method: 'POST' }) +} + +const unsubscribeUser = ({ id, credentials }) => { + return promisedRequest({ url: MASTODON_UNSUBSCRIBE_USER(id), credentials, method: 'POST' }) +} + const fetchBlocks = ({ credentials }) => { return promisedRequest({ url: MASTODON_USER_BLOCKS_URL, credentials }) .then((users) => users.map(parseUser)) @@ -882,6 +892,8 @@ const apiService = { fetchMutes, muteUser, unmuteUser, + subscribeUser, + unsubscribeUser, 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 5162d38f..4e1675c2 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -108,6 +108,8 @@ const backendInteractorService = credentials => { const fetchMutes = () => apiService.fetchMutes({ credentials }) const muteUser = (id) => apiService.muteUser({ credentials, id }) const unmuteUser = (id) => apiService.unmuteUser({ credentials, id }) + const subscribeUser = (id) => apiService.subscribeUser({ credentials, id }) + const unsubscribeUser = (id) => apiService.unsubscribeUser({ credentials, id }) const fetchBlocks = () => apiService.fetchBlocks({ credentials }) const fetchFollowRequests = () => apiService.fetchFollowRequests({ credentials }) const fetchOAuthTokens = () => apiService.fetchOAuthTokens({ credentials }) @@ -167,6 +169,8 @@ const backendInteractorService = credentials => { fetchMutes, muteUser, unmuteUser, + subscribeUser, + unsubscribeUser, fetchBlocks, fetchOAuthTokens, revokeOAuthToken, diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index df6747a6..de6664d1 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -68,6 +68,7 @@ export const parseUser = (data) => { output.following = relationship.following output.statusnet_blocking = relationship.blocking output.muted = relationship.muting + output.subscribed = relationship.subscribing } output.hide_follows = data.pleroma.hide_follows |
