diff --git a/config/index.js b/config/index.js index c48d91b8..5d2cb833 100644 --- a/config/index.js +++ b/config/index.js @@ -23,12 +23,12 @@ module.exports = { assetsPublicPath: '/', proxyTable: { '/api': { - target: 'htts://localhost:4000/', + target: 'http://localhost:4000/', changeOrigin: true, cookieDomainRewrite: 'localhost' }, '/socket': { - target: 'htts://localhost:4000/', + target: 'http://localhost:4000/', changeOrigin: true, cookieDomainRewrite: 'localhost', ws: true diff --git a/src/components/follow_requests/follow_requests.js b/src/components/follow_requests/follow_requests.js new file mode 100644 index 00000000..11a228aa --- /dev/null +++ b/src/components/follow_requests/follow_requests.js @@ -0,0 +1,23 @@ +import UserCard from '../user_card/user_card.vue' + +const FollowRequests = { + components: { + UserCard + }, + created () { + this.updateRequests() + }, + computed: { + requests () { + return this.$store.state.api.followRequests + } + }, + methods: { + updateRequests () { + this.$store.state.api.backendInteractor.fetchFollowRequests() + .then((requests) => { this.$store.commit('setFollowRequests', requests) }) + } + } +} + +export default FollowRequests diff --git a/src/components/follow_requests/follow_requests.vue b/src/components/follow_requests/follow_requests.vue new file mode 100644 index 00000000..87dc4194 --- /dev/null +++ b/src/components/follow_requests/follow_requests.vue @@ -0,0 +1,12 @@ + + + diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue index 2e1a6c7a..0b188f9a 100644 --- a/src/components/nav_panel/nav_panel.vue +++ b/src/components/nav_panel/nav_panel.vue @@ -12,6 +12,11 @@ {{ $t("nav.mentions") }} +
  • + + {{ $t("nav.friend_requests") }} + +
  • {{ $t("nav.public_tl") }} diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index a7a871c3..a019627a 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -3,7 +3,8 @@ import UserCardContent from '../user_card_content/user_card_content.vue' const UserCard = { props: [ 'user', - 'showFollows' + 'showFollows', + 'showApproval' ], data () { return { @@ -16,6 +17,14 @@ const UserCard = { methods: { toggleUserExpanded () { this.userExpanded = !this.userExpanded + }, + approveUser () { + this.$store.state.api.backendInteractor.approveUser(this.user.id) + this.$store.dispatch('removeFollowRequest', this.user) + }, + denyUser () { + this.$store.state.api.backendInteractor.denyUser(this.user.id) + this.$store.dispatch('removeFollowRequest', this.user) } } } diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue index 51d6965f..6478a65f 100644 --- a/src/components/user_card/user_card.vue +++ b/src/components/user_card/user_card.vue @@ -15,6 +15,10 @@
    @{{ user.screen_name }}
    +
    + + +
    @@ -75,4 +79,11 @@ margin-bottom: 0; } } + +.approval { + button { + width: 100%; + margin-bottom: 0.5em; + } +} diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue index c120df9a..09e91271 100644 --- a/src/components/user_card_content/user_card_content.vue +++ b/src/components/user_card_content/user_card_content.vue @@ -15,7 +15,7 @@
    {{user.name}}
    - @{{user.screen_name}} + @{{user.screen_name}} {{dailyAvg}} {{ $t('user_card.per_day') }}
    diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index b6026e18..443e63dd 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -5,6 +5,7 @@ const UserSettings = { return { newname: this.$store.state.users.currentUser.name, newbio: this.$store.state.users.currentUser.description, + newlocked: this.$store.state.users.currentUser.locked, followList: null, followImportError: false, followsImported: false, @@ -34,7 +35,8 @@ const UserSettings = { updateProfile () { const name = this.newname const description = this.newbio - this.$store.state.api.backendInteractor.updateProfile({params: {name, description}}).then((user) => { + const locked = this.newlocked + this.$store.state.api.backendInteractor.updateProfile({params: {name, description, locked}}).then((user) => { if (!user.error) { this.$store.commit('addNewUsers', [user]) this.$store.commit('setCurrentUser', user) diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index fbf3f651..4abdfc8e 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -10,6 +10,10 @@

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

    +
    + + +
    diff --git a/src/i18n/messages.js b/src/i18n/messages.js index 58961601..98835298 100644 --- a/src/i18n/messages.js +++ b/src/i18n/messages.js @@ -220,7 +220,8 @@ const en = { timeline: 'Timeline', mentions: 'Mentions', public_tl: 'Public Timeline', - twkn: 'The Whole Known Network' + twkn: 'The Whole Known Network', + friend_requests: 'Follow Requests' }, user_card: { follows_you: 'Follows you!', @@ -234,7 +235,9 @@ const en = { followers: 'Followers', followees: 'Following', per_day: 'per day', - remote_follow: 'Remote follow' + remote_follow: 'Remote follow', + approve: 'Approve', + deny: 'Deny' }, timeline: { show_new: 'Show new', @@ -304,7 +307,8 @@ const en = { new_password: 'New password', confirm_new_password: 'Confirm new password', changed_password: 'Password changed successfully!', - change_password_error: 'There was an issue changing your password.' + change_password_error: 'There was an issue changing your password.', + lock_account_description: 'Restrict your account to approved followers only' }, notifications: { notifications: 'Notifications', diff --git a/src/main.js b/src/main.js index 0c964dcc..bacd7f6d 100644 --- a/src/main.js +++ b/src/main.js @@ -12,6 +12,7 @@ import UserProfile from './components/user_profile/user_profile.vue' import Settings from './components/settings/settings.vue' import Registration from './components/registration/registration.vue' import UserSettings from './components/user_settings/user_settings.vue' +import FollowRequests from './components/follow_requests/follow_requests.vue' import statusesModule from './modules/statuses.js' import usersModule from './modules/users.js' @@ -118,6 +119,7 @@ window.fetch('/static/config.json') { name: 'mentions', path: '/:username/mentions', component: Mentions }, { name: 'settings', path: '/settings', component: Settings }, { name: 'registration', path: '/registration', component: Registration }, + { name: 'friend-requests', path: '/friend-requests', component: FollowRequests }, { name: 'user-settings', path: '/user-settings', component: UserSettings } ] diff --git a/src/modules/api.js b/src/modules/api.js index c91fb97b..a61340c2 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -7,7 +7,8 @@ const api = { backendInteractor: backendInteractorService(), fetchers: {}, socket: null, - chatDisabled: false + chatDisabled: false, + followRequests: [] }, mutations: { setBackendInteractor (state, backendInteractor) { @@ -24,6 +25,9 @@ const api = { }, setChatDisabled (state, value) { state.chatDisabled = value + }, + setFollowRequests (state, value) { + state.followRequests = value } }, actions: { @@ -57,6 +61,10 @@ const api = { }, disableChat (store) { store.commit('setChatDisabled', true) + }, + removeFollowRequest (store, request) { + let requests = store.state.followRequests.filter((it) => it !== request) + store.commit('setFollowRequests', requests) } } } diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 0d91851b..d1659784 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -32,6 +32,9 @@ 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' +const FOLLOW_REQUESTS_URL = '/api/pleroma/friend_requests' +const APPROVE_USER_URL = '/api/pleroma/friendships/approve' +const DENY_USER_URL = '/api/pleroma/friendships/deny' import { each, map } from 'lodash' import 'whatwg-fetch' @@ -127,11 +130,13 @@ const updateBanner = ({credentials, params}) => { const updateProfile = ({credentials, params}) => { let url = PROFILE_UPDATE_URL + console.log(params) + const form = new FormData() each(params, (value, key) => { - if (key === 'description' || /* Always include description, because it might be empty */ - value) { + /* Always include description and locked, because it might be empty or false */ + if (key === 'description' || key === 'locked' || value) { form.append(key, value) } }) @@ -216,6 +221,22 @@ const unblockUser = ({id, credentials}) => { }).then((data) => data.json()) } +const approveUser = ({id, credentials}) => { + let url = `${APPROVE_USER_URL}?user_id=${id}` + return fetch(url, { + headers: authHeaders(credentials), + method: 'POST' + }).then((data) => data.json()) +} + +const denyUser = ({id, credentials}) => { + let url = `${DENY_USER_URL}?user_id=${id}` + return fetch(url, { + headers: authHeaders(credentials), + method: 'POST' + }).then((data) => data.json()) +} + const fetchUser = ({id, credentials}) => { let url = `${USER_URL}?user_id=${id}` return fetch(url, { headers: authHeaders(credentials) }) @@ -240,6 +261,12 @@ const fetchAllFollowing = ({username, credentials}) => { .then((data) => data.json()) } +const fetchFollowRequests = ({credentials}) => { + const url = FOLLOW_REQUESTS_URL + return fetch(url, { headers: authHeaders(credentials) }) + .then((data) => data.json()) +} + const fetchConversation = ({id, credentials}) => { let url = `${CONVERSATION_URL}/${id}.json?count=100` return fetch(url, { headers: authHeaders(credentials) }) @@ -442,7 +469,10 @@ const apiService = { externalProfile, followImport, deleteAccount, - changePassword + changePassword, + fetchFollowRequests, + approveUser, + denyUser } export default apiService diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 14173558..dbfb54f9 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -42,6 +42,14 @@ const backendInteractorService = (credentials) => { return apiService.unblockUser({credentials, id}) } + const approveUser = (id) => { + return apiService.approveUser({credentials, id}) + } + + const denyUser = (id) => { + return apiService.denyUser({credentials, id}) + } + const startFetching = ({timeline, store, userId = false}) => { return timelineFetcherService.startFetching({timeline, store, credentials, userId}) } @@ -51,6 +59,7 @@ const backendInteractorService = (credentials) => { } const fetchMutes = () => apiService.fetchMutes({credentials}) + const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials}) const register = (params) => apiService.register(params) const updateAvatar = ({params}) => apiService.updateAvatar({credentials, params}) @@ -87,7 +96,10 @@ const backendInteractorService = (credentials) => { externalProfile, followImport, deleteAccount, - changePassword + changePassword, + fetchFollowRequests, + approveUser, + denyUser } return backendInteractorServiceInstance