logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe
commit: 6ea5cfe71ee9ae5669c44f154b7ca5dae1211551
parent: 2330170d2305b664f623b9fe8b46d075086b13b5
Author: lambda <pleromagit@rogerbraun.net>
Date:   Tue, 12 Jun 2018 16:57:18 +0000

Merge branch 'feature/locked-accounts' into 'develop'

Feature/locked accounts

See merge request pleroma/pleroma-fe!274

Diffstat:

Mconfig/index.js4++--
Asrc/components/follow_requests/follow_requests.js23+++++++++++++++++++++++
Asrc/components/follow_requests/follow_requests.vue12++++++++++++
Msrc/components/nav_panel/nav_panel.vue5+++++
Msrc/components/user_card/user_card.js11++++++++++-
Msrc/components/user_card/user_card.vue11+++++++++++
Msrc/components/user_card_content/user_card_content.vue2+-
Msrc/components/user_settings/user_settings.js4+++-
Msrc/components/user_settings/user_settings.vue4++++
Msrc/i18n/messages.js10+++++++---
Msrc/main.js2++
Msrc/modules/api.js10+++++++++-
Msrc/services/api/api.service.js36+++++++++++++++++++++++++++++++++---
Msrc/services/backend_interactor_service/backend_interactor_service.js14+++++++++++++-
14 files changed, 135 insertions(+), 13 deletions(-)

diff --git 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 @@ -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 @@ -0,0 +1,12 @@ +<template> + <div class="settings panel panel-default"> + <div class="panel-heading"> + {{$t('nav.friend_requests')}} + </div> + <div class="panel-body"> + <user-card v-for="request in requests" :key="request.id" :user="request" :showFollows="false" :showApproval="true"></user-card> + </div> + </div> +</template> + +<script src="./follow_requests.js"></script> diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue @@ -12,6 +12,11 @@ {{ $t("nav.mentions") }} </router-link> </li> + <li v-if='currentUser && currentUser.locked'> + <router-link to='/friend-requests'> + {{ $t("nav.friend_requests") }} + </router-link> + </li> <li> <router-link to='/main/public'> {{ $t("nav.public_tl") }} diff --git 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 @@ -15,6 +15,10 @@ </div> <a :href="user.statusnet_profile_url" target="blank"><div class="user-screen-name">@{{ user.screen_name }}</div></a> </div> + <div class="approval" v-if="showApproval"> + <button class="btn btn-default" @click="approveUser">{{ $t('user_card.approve') }}</button> + <button class="btn btn-default" @click="denyUser">{{ $t('user_card.deny') }}</button> + </div> </div> </template> @@ -75,4 +79,11 @@ margin-bottom: 0; } } + +.approval { + button { + width: 100%; + margin-bottom: 0.5em; + } +} </style> diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue @@ -15,7 +15,7 @@ <div class="name-and-screen-name"> <div :title="user.name" class='user-name'>{{user.name}}</div> <router-link class='user-screen-name':to="{ name: 'user-profile', params: { id: user.id } }"> - <span>@{{user.screen_name}}</span> + <span>@{{user.screen_name}}</span><span v-if="user.locked"><i class="icon icon-lock"></i></span> <span class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span> </router-link> </div> diff --git 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 @@ -10,6 +10,10 @@ <input class='name-changer' id='username' v-model="newname"></input> <p>{{$t('settings.bio')}}</p> <textarea class="bio" v-model="newbio"></textarea> + <div class="setting-item"> + <input type="checkbox" v-model="newlocked" id="account-locked"> + <label for="account-locked">{{$t('settings.lock_account_description')}}</label> + </div> <button :disabled='newname.length <= 0' class="btn btn-default" @click="updateProfile">{{$t('general.submit')}}</button> </div> <div class="setting-item"> diff --git 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 @@ -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 @@ -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 @@ -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 @@ -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