forked from AkkomaGang/akkoma-fe
Merge branch 'feature/locked-accounts' into 'develop'
Feature/locked accounts See merge request pleroma/pleroma-fe!274
This commit is contained in:
commit
6ea5cfe71e
14 changed files with 135 additions and 13 deletions
|
@ -23,12 +23,12 @@ module.exports = {
|
||||||
assetsPublicPath: '/',
|
assetsPublicPath: '/',
|
||||||
proxyTable: {
|
proxyTable: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'htts://localhost:4000/',
|
target: 'http://localhost:4000/',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
cookieDomainRewrite: 'localhost'
|
cookieDomainRewrite: 'localhost'
|
||||||
},
|
},
|
||||||
'/socket': {
|
'/socket': {
|
||||||
target: 'htts://localhost:4000/',
|
target: 'http://localhost:4000/',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
cookieDomainRewrite: 'localhost',
|
cookieDomainRewrite: 'localhost',
|
||||||
ws: true
|
ws: true
|
||||||
|
|
23
src/components/follow_requests/follow_requests.js
Normal file
23
src/components/follow_requests/follow_requests.js
Normal file
|
@ -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
|
12
src/components/follow_requests/follow_requests.vue
Normal file
12
src/components/follow_requests/follow_requests.vue
Normal file
|
@ -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>
|
|
@ -12,6 +12,11 @@
|
||||||
{{ $t("nav.mentions") }}
|
{{ $t("nav.mentions") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
|
<li v-if='currentUser && currentUser.locked'>
|
||||||
|
<router-link to='/friend-requests'>
|
||||||
|
{{ $t("nav.friend_requests") }}
|
||||||
|
</router-link>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<router-link to='/main/public'>
|
<router-link to='/main/public'>
|
||||||
{{ $t("nav.public_tl") }}
|
{{ $t("nav.public_tl") }}
|
||||||
|
|
|
@ -3,7 +3,8 @@ import UserCardContent from '../user_card_content/user_card_content.vue'
|
||||||
const UserCard = {
|
const UserCard = {
|
||||||
props: [
|
props: [
|
||||||
'user',
|
'user',
|
||||||
'showFollows'
|
'showFollows',
|
||||||
|
'showApproval'
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
@ -16,6 +17,14 @@ const UserCard = {
|
||||||
methods: {
|
methods: {
|
||||||
toggleUserExpanded () {
|
toggleUserExpanded () {
|
||||||
this.userExpanded = !this.userExpanded
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
</div>
|
</div>
|
||||||
<a :href="user.statusnet_profile_url" target="blank"><div class="user-screen-name">@{{ user.screen_name }}</div></a>
|
<a :href="user.statusnet_profile_url" target="blank"><div class="user-screen-name">@{{ user.screen_name }}</div></a>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -75,4 +79,11 @@
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.approval {
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<div class="name-and-screen-name">
|
<div class="name-and-screen-name">
|
||||||
<div :title="user.name" class='user-name'>{{user.name}}</div>
|
<div :title="user.name" class='user-name'>{{user.name}}</div>
|
||||||
<router-link class='user-screen-name':to="{ name: 'user-profile', params: { id: user.id } }">
|
<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>
|
<span class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,6 +5,7 @@ const UserSettings = {
|
||||||
return {
|
return {
|
||||||
newname: this.$store.state.users.currentUser.name,
|
newname: this.$store.state.users.currentUser.name,
|
||||||
newbio: this.$store.state.users.currentUser.description,
|
newbio: this.$store.state.users.currentUser.description,
|
||||||
|
newlocked: this.$store.state.users.currentUser.locked,
|
||||||
followList: null,
|
followList: null,
|
||||||
followImportError: false,
|
followImportError: false,
|
||||||
followsImported: false,
|
followsImported: false,
|
||||||
|
@ -34,7 +35,8 @@ const UserSettings = {
|
||||||
updateProfile () {
|
updateProfile () {
|
||||||
const name = this.newname
|
const name = this.newname
|
||||||
const description = this.newbio
|
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) {
|
if (!user.error) {
|
||||||
this.$store.commit('addNewUsers', [user])
|
this.$store.commit('addNewUsers', [user])
|
||||||
this.$store.commit('setCurrentUser', user)
|
this.$store.commit('setCurrentUser', user)
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
<input class='name-changer' id='username' v-model="newname"></input>
|
<input class='name-changer' id='username' v-model="newname"></input>
|
||||||
<p>{{$t('settings.bio')}}</p>
|
<p>{{$t('settings.bio')}}</p>
|
||||||
<textarea class="bio" v-model="newbio"></textarea>
|
<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>
|
<button :disabled='newname.length <= 0' class="btn btn-default" @click="updateProfile">{{$t('general.submit')}}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
|
|
|
@ -220,7 +220,8 @@ const en = {
|
||||||
timeline: 'Timeline',
|
timeline: 'Timeline',
|
||||||
mentions: 'Mentions',
|
mentions: 'Mentions',
|
||||||
public_tl: 'Public Timeline',
|
public_tl: 'Public Timeline',
|
||||||
twkn: 'The Whole Known Network'
|
twkn: 'The Whole Known Network',
|
||||||
|
friend_requests: 'Follow Requests'
|
||||||
},
|
},
|
||||||
user_card: {
|
user_card: {
|
||||||
follows_you: 'Follows you!',
|
follows_you: 'Follows you!',
|
||||||
|
@ -234,7 +235,9 @@ const en = {
|
||||||
followers: 'Followers',
|
followers: 'Followers',
|
||||||
followees: 'Following',
|
followees: 'Following',
|
||||||
per_day: 'per day',
|
per_day: 'per day',
|
||||||
remote_follow: 'Remote follow'
|
remote_follow: 'Remote follow',
|
||||||
|
approve: 'Approve',
|
||||||
|
deny: 'Deny'
|
||||||
},
|
},
|
||||||
timeline: {
|
timeline: {
|
||||||
show_new: 'Show new',
|
show_new: 'Show new',
|
||||||
|
@ -304,7 +307,8 @@ const en = {
|
||||||
new_password: 'New password',
|
new_password: 'New password',
|
||||||
confirm_new_password: 'Confirm new password',
|
confirm_new_password: 'Confirm new password',
|
||||||
changed_password: 'Password changed successfully!',
|
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: 'Notifications',
|
notifications: 'Notifications',
|
||||||
|
|
|
@ -12,6 +12,7 @@ import UserProfile from './components/user_profile/user_profile.vue'
|
||||||
import Settings from './components/settings/settings.vue'
|
import Settings from './components/settings/settings.vue'
|
||||||
import Registration from './components/registration/registration.vue'
|
import Registration from './components/registration/registration.vue'
|
||||||
import UserSettings from './components/user_settings/user_settings.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 statusesModule from './modules/statuses.js'
|
||||||
import usersModule from './modules/users.js'
|
import usersModule from './modules/users.js'
|
||||||
|
@ -118,6 +119,7 @@ window.fetch('/static/config.json')
|
||||||
{ name: 'mentions', path: '/:username/mentions', component: Mentions },
|
{ name: 'mentions', path: '/:username/mentions', component: Mentions },
|
||||||
{ name: 'settings', path: '/settings', component: Settings },
|
{ name: 'settings', path: '/settings', component: Settings },
|
||||||
{ name: 'registration', path: '/registration', component: Registration },
|
{ name: 'registration', path: '/registration', component: Registration },
|
||||||
|
{ name: 'friend-requests', path: '/friend-requests', component: FollowRequests },
|
||||||
{ name: 'user-settings', path: '/user-settings', component: UserSettings }
|
{ name: 'user-settings', path: '/user-settings', component: UserSettings }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ const api = {
|
||||||
backendInteractor: backendInteractorService(),
|
backendInteractor: backendInteractorService(),
|
||||||
fetchers: {},
|
fetchers: {},
|
||||||
socket: null,
|
socket: null,
|
||||||
chatDisabled: false
|
chatDisabled: false,
|
||||||
|
followRequests: []
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
setBackendInteractor (state, backendInteractor) {
|
setBackendInteractor (state, backendInteractor) {
|
||||||
|
@ -24,6 +25,9 @@ const api = {
|
||||||
},
|
},
|
||||||
setChatDisabled (state, value) {
|
setChatDisabled (state, value) {
|
||||||
state.chatDisabled = value
|
state.chatDisabled = value
|
||||||
|
},
|
||||||
|
setFollowRequests (state, value) {
|
||||||
|
state.followRequests = value
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -57,6 +61,10 @@ const api = {
|
||||||
},
|
},
|
||||||
disableChat (store) {
|
disableChat (store) {
|
||||||
store.commit('setChatDisabled', true)
|
store.commit('setChatDisabled', true)
|
||||||
|
},
|
||||||
|
removeFollowRequest (store, request) {
|
||||||
|
let requests = store.state.followRequests.filter((it) => it !== request)
|
||||||
|
store.commit('setFollowRequests', requests)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ const USER_URL = '/api/users/show.json'
|
||||||
const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import'
|
const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import'
|
||||||
const DELETE_ACCOUNT_URL = '/api/pleroma/delete_account'
|
const DELETE_ACCOUNT_URL = '/api/pleroma/delete_account'
|
||||||
const CHANGE_PASSWORD_URL = '/api/pleroma/change_password'
|
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 { each, map } from 'lodash'
|
||||||
import 'whatwg-fetch'
|
import 'whatwg-fetch'
|
||||||
|
@ -127,11 +130,13 @@ const updateBanner = ({credentials, params}) => {
|
||||||
const updateProfile = ({credentials, params}) => {
|
const updateProfile = ({credentials, params}) => {
|
||||||
let url = PROFILE_UPDATE_URL
|
let url = PROFILE_UPDATE_URL
|
||||||
|
|
||||||
|
console.log(params)
|
||||||
|
|
||||||
const form = new FormData()
|
const form = new FormData()
|
||||||
|
|
||||||
each(params, (value, key) => {
|
each(params, (value, key) => {
|
||||||
if (key === 'description' || /* Always include description, because it might be empty */
|
/* Always include description and locked, because it might be empty or false */
|
||||||
value) {
|
if (key === 'description' || key === 'locked' || value) {
|
||||||
form.append(key, value)
|
form.append(key, value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -216,6 +221,22 @@ const unblockUser = ({id, credentials}) => {
|
||||||
}).then((data) => data.json())
|
}).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}) => {
|
const fetchUser = ({id, credentials}) => {
|
||||||
let url = `${USER_URL}?user_id=${id}`
|
let url = `${USER_URL}?user_id=${id}`
|
||||||
return fetch(url, { headers: authHeaders(credentials) })
|
return fetch(url, { headers: authHeaders(credentials) })
|
||||||
|
@ -240,6 +261,12 @@ const fetchAllFollowing = ({username, credentials}) => {
|
||||||
.then((data) => data.json())
|
.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}) => {
|
const fetchConversation = ({id, credentials}) => {
|
||||||
let url = `${CONVERSATION_URL}/${id}.json?count=100`
|
let url = `${CONVERSATION_URL}/${id}.json?count=100`
|
||||||
return fetch(url, { headers: authHeaders(credentials) })
|
return fetch(url, { headers: authHeaders(credentials) })
|
||||||
|
@ -442,7 +469,10 @@ const apiService = {
|
||||||
externalProfile,
|
externalProfile,
|
||||||
followImport,
|
followImport,
|
||||||
deleteAccount,
|
deleteAccount,
|
||||||
changePassword
|
changePassword,
|
||||||
|
fetchFollowRequests,
|
||||||
|
approveUser,
|
||||||
|
denyUser
|
||||||
}
|
}
|
||||||
|
|
||||||
export default apiService
|
export default apiService
|
||||||
|
|
|
@ -42,6 +42,14 @@ const backendInteractorService = (credentials) => {
|
||||||
return apiService.unblockUser({credentials, id})
|
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}) => {
|
const startFetching = ({timeline, store, userId = false}) => {
|
||||||
return timelineFetcherService.startFetching({timeline, store, credentials, userId})
|
return timelineFetcherService.startFetching({timeline, store, credentials, userId})
|
||||||
}
|
}
|
||||||
|
@ -51,6 +59,7 @@ const backendInteractorService = (credentials) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchMutes = () => apiService.fetchMutes({credentials})
|
const fetchMutes = () => apiService.fetchMutes({credentials})
|
||||||
|
const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials})
|
||||||
|
|
||||||
const register = (params) => apiService.register(params)
|
const register = (params) => apiService.register(params)
|
||||||
const updateAvatar = ({params}) => apiService.updateAvatar({credentials, params})
|
const updateAvatar = ({params}) => apiService.updateAvatar({credentials, params})
|
||||||
|
@ -87,7 +96,10 @@ const backendInteractorService = (credentials) => {
|
||||||
externalProfile,
|
externalProfile,
|
||||||
followImport,
|
followImport,
|
||||||
deleteAccount,
|
deleteAccount,
|
||||||
changePassword
|
changePassword,
|
||||||
|
fetchFollowRequests,
|
||||||
|
approveUser,
|
||||||
|
denyUser
|
||||||
}
|
}
|
||||||
|
|
||||||
return backendInteractorServiceInstance
|
return backendInteractorServiceInstance
|
||||||
|
|
Loading…
Reference in a new issue