paginate-follow-requests #277
12 changed files with 92 additions and 72 deletions
|
@ -43,6 +43,7 @@ const FollowRequestCard = {
|
||||||
doApprove () {
|
doApprove () {
|
||||||
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
|
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
|
||||||
this.$store.dispatch('removeFollowRequest', this.user)
|
this.$store.dispatch('removeFollowRequest', this.user)
|
||||||
|
this.$store.dispatch('decrementFollowRequestsCount')
|
||||||
|
|
||||||
const notifId = this.findFollowRequestNotificationId()
|
const notifId = this.findFollowRequestNotificationId()
|
||||||
this.$store.dispatch('markSingleNotificationAsSeen', { id: notifId })
|
this.$store.dispatch('markSingleNotificationAsSeen', { id: notifId })
|
||||||
|
@ -66,6 +67,7 @@ const FollowRequestCard = {
|
||||||
this.$store.state.api.backendInteractor.denyUser({ id: this.user.id })
|
this.$store.state.api.backendInteractor.denyUser({ id: this.user.id })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$store.dispatch('dismissNotificationLocal', { id: notifId })
|
this.$store.dispatch('dismissNotificationLocal', { id: notifId })
|
||||||
|
this.$store.dispatch('decrementFollowRequestsCount')
|
||||||
this.$store.dispatch('removeFollowRequest', this.user)
|
this.$store.dispatch('removeFollowRequest', this.user)
|
||||||
})
|
})
|
||||||
this.hideDenyConfirmDialog()
|
this.hideDenyConfirmDialog()
|
||||||
|
@ -80,6 +82,11 @@ const FollowRequestCard = {
|
||||||
},
|
},
|
||||||
shouldConfirmDeny () {
|
shouldConfirmDeny () {
|
||||||
return this.mergedConfig.modalOnDenyFollow
|
return this.mergedConfig.modalOnDenyFollow
|
||||||
|
},
|
||||||
|
show () {
|
||||||
|
const notifId = this.$store.state.api.followRequests.find(req => req.id === this.user.id)
|
||||||
|
|
||||||
|
return notifId !== undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<basic-user-card :user="user">
|
<basic-user-card :user="user" v-if="show">
|
||||||
<div class="follow-request-card-content-container">
|
<div class="follow-request-card-content-container">
|
||||||
<button
|
<button
|
||||||
class="btn button-default"
|
class="btn button-default"
|
||||||
|
|
|
@ -1,10 +1,26 @@
|
||||||
import FollowRequestCard from '../follow_request_card/follow_request_card.vue'
|
import FollowRequestCard from '../follow_request_card/follow_request_card.vue'
|
||||||
|
import withLoadMore from '../../hocs/with_load_more/with_load_more'
|
||||||
|
import List from '../list/list.vue'
|
||||||
|
import get from 'lodash/get'
|
||||||
|
|
||||||
|
const FollowRequestList = withLoadMore({
|
||||||
|
fetch: (props, $store) => $store.dispatch('fetchFollowRequests'),
|
||||||
|
select: (props, $store) => get($store.state.api, 'followRequests', []).map(req => $store.getters.findUser(req.id)),
|
||||||
|
destroy: (props, $store) => $store.dispatch('clearFollowRequests'),
|
||||||
|
childPropName: 'items',
|
||||||
|
additionalPropNames: ['userId']
|
||||||
|
})(List);
|
||||||
|
|
||||||
|
|
||||||
const FollowRequests = {
|
const FollowRequests = {
|
||||||
components: {
|
components: {
|
||||||
FollowRequestCard
|
FollowRequestCard,
|
||||||
|
FollowRequestList
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
userId () {
|
||||||
|
return this.$store.state.users.currentUser.id
|
||||||
|
},
|
||||||
requests () {
|
requests () {
|
||||||
return this.$store.state.api.followRequests
|
return this.$store.state.api.followRequests
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<FollowRequestCard
|
<FollowRequestList :user-id="userId">
|
||||||
v-for="request in requests"
|
<template #item="{item}">
|
||||||
:key="request.id"
|
<FollowRequestCard :user="item" />
|
||||||
:user="request"
|
</template>
|
||||||
class="list-item"
|
</FollowRequestList>
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -33,11 +33,6 @@ library.add(
|
||||||
)
|
)
|
||||||
|
|
||||||
const NavPanel = {
|
const NavPanel = {
|
||||||
created () {
|
|
||||||
if (this.currentUser && this.currentUser.locked) {
|
|
||||||
this.$store.dispatch('startFetchingFollowRequests')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
components: {
|
||||||
TimelineMenuContent
|
TimelineMenuContent
|
||||||
},
|
},
|
||||||
|
@ -54,11 +49,13 @@ const NavPanel = {
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
currentUser: state => state.users.currentUser,
|
currentUser: state => state.users.currentUser,
|
||||||
followRequestCount: state => state.api.followRequests.length,
|
|
||||||
privateMode: state => state.instance.private,
|
privateMode: state => state.instance.private,
|
||||||
federating: state => state.instance.federating
|
federating: state => state.instance.federating
|
||||||
}),
|
}),
|
||||||
...mapGetters(['unreadAnnouncementCount'])
|
...mapGetters(['unreadAnnouncementCount']),
|
||||||
|
followRequestCount () {
|
||||||
|
return this.$store.state.users.currentUser.follow_requests_count
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -224,7 +224,7 @@ const UserProfile = {
|
||||||
TabSwitcher,
|
TabSwitcher,
|
||||||
Conversation,
|
Conversation,
|
||||||
RichContent,
|
RichContent,
|
||||||
FollowedTagList,
|
FollowedTagList
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
||||||
import { WSConnectionStatus } from '../services/api/api.service.js'
|
import { WSConnectionStatus } from '../services/api/api.service.js'
|
||||||
|
import { map } from 'lodash'
|
||||||
|
|
||||||
const retryTimeout = (multiplier) => 1000 * multiplier
|
const retryTimeout = (multiplier) => 1000 * multiplier
|
||||||
|
|
||||||
|
@ -40,9 +41,6 @@ const api = {
|
||||||
setSocket (state, socket) {
|
setSocket (state, socket) {
|
||||||
state.socket = socket
|
state.socket = socket
|
||||||
},
|
},
|
||||||
setFollowRequests (state, value) {
|
|
||||||
state.followRequests = value
|
|
||||||
},
|
|
||||||
setMastoUserSocketStatus (state, value) {
|
setMastoUserSocketStatus (state, value) {
|
||||||
state.mastoUserSocketStatus = value
|
state.mastoUserSocketStatus = value
|
||||||
},
|
},
|
||||||
|
@ -51,6 +49,15 @@ const api = {
|
||||||
},
|
},
|
||||||
resetRetryMultiplier (state) {
|
resetRetryMultiplier (state) {
|
||||||
state.retryMultiplier = 1
|
state.retryMultiplier = 1
|
||||||
|
},
|
||||||
|
setFollowRequests (state, value) {
|
||||||
|
state.followRequests = [...value]
|
||||||
|
},
|
||||||
|
saveFollowRequests (state, requests) {
|
||||||
|
state.followRequests = [...state.followRequests, ...requests]
|
||||||
|
},
|
||||||
|
saveFollowRequestPagination (state, pagination) {
|
||||||
|
state.followRequestsPagination = pagination
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -240,24 +247,22 @@ const api = {
|
||||||
...rest
|
...rest
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// Follow requests
|
|
||||||
startFetchingFollowRequests (store) {
|
|
||||||
if (store.state.fetchers['followRequests']) return
|
|
||||||
const fetcher = store.state.backendInteractor.startFetchingFollowRequests({ store })
|
|
||||||
|
|
||||||
store.commit('addFetcher', { fetcherName: 'followRequests', fetcher })
|
|
||||||
},
|
|
||||||
stopFetchingFollowRequests (store) {
|
|
||||||
const fetcher = store.state.fetchers.followRequests
|
|
||||||
if (!fetcher) return
|
|
||||||
store.commit('removeFetcher', { fetcherName: 'followRequests', fetcher })
|
|
||||||
},
|
|
||||||
removeFollowRequest (store, request) {
|
removeFollowRequest (store, request) {
|
||||||
let requests = store.state.followRequests.filter((it) => it !== request)
|
let requests = [...store.state.followRequests].filter((it) => it.id !== request.id)
|
||||||
store.commit('setFollowRequests', requests)
|
store.commit('setFollowRequests', requests)
|
||||||
},
|
},
|
||||||
|
fetchFollowRequests ({ rootState, commit }) {
|
||||||
|
const pagination = rootState.api.followRequestsPagination
|
||||||
|
return rootState.api.backendInteractor.getFollowRequests({ pagination })
|
||||||
|
.then((requests) => {
|
||||||
|
if (requests.data.length > 0) {
|
||||||
|
commit('addNewUsers', requests.data)
|
||||||
|
commit('saveFollowRequests', requests.data)
|
||||||
|
commit('saveFollowRequestPagination', requests.pagination)
|
||||||
|
}
|
||||||
|
return requests
|
||||||
|
})
|
||||||
|
},
|
||||||
// Lists
|
// Lists
|
||||||
startFetchingLists (store) {
|
startFetchingLists (store) {
|
||||||
if (store.state.fetchers['lists']) return
|
if (store.state.fetchers['lists']) return
|
||||||
|
|
|
@ -265,6 +265,12 @@ export const mutations = {
|
||||||
signUpFailure (state, errors) {
|
signUpFailure (state, errors) {
|
||||||
state.signUpPending = false
|
state.signUpPending = false
|
||||||
state.signUpErrors = errors
|
state.signUpErrors = errors
|
||||||
|
},
|
||||||
|
decrementFollowRequestsCount (store) {
|
||||||
|
store.currentUser.follow_requests_count--
|
||||||
|
},
|
||||||
|
incrementFollowRequestsCount (store) {
|
||||||
|
store.currentUser.follow_requests_count++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,6 +510,12 @@ const users = {
|
||||||
store.commit('setUserForNotification', notification)
|
store.commit('setUserForNotification', notification)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
decrementFollowRequestsCount (store) {
|
||||||
|
store.commit('decrementFollowRequestsCount')
|
||||||
|
},
|
||||||
|
incrementFollowRequestsCount (store) {
|
||||||
|
store.commit('incrementFollowRequestsCount')
|
||||||
|
},
|
||||||
searchUsers ({ rootState, commit }, { query }) {
|
searchUsers ({ rootState, commit }, { query }) {
|
||||||
return rootState.api.backendInteractor.searchUsers({ query })
|
return rootState.api.backendInteractor.searchUsers({ query })
|
||||||
.then((users) => {
|
.then((users) => {
|
||||||
|
@ -567,7 +579,6 @@ const users = {
|
||||||
store.dispatch('stopFetchingTimeline', 'friends')
|
store.dispatch('stopFetchingTimeline', 'friends')
|
||||||
store.commit('setBackendInteractor', backendInteractorService(store.getters.getToken()))
|
store.commit('setBackendInteractor', backendInteractorService(store.getters.getToken()))
|
||||||
store.dispatch('stopFetchingNotifications')
|
store.dispatch('stopFetchingNotifications')
|
||||||
store.dispatch('stopFetchingFollowRequests')
|
|
||||||
store.dispatch('stopFetchingConfig')
|
store.dispatch('stopFetchingConfig')
|
||||||
store.commit('clearNotifications')
|
store.commit('clearNotifications')
|
||||||
store.commit('resetStatuses')
|
store.commit('resetStatuses')
|
||||||
|
|
|
@ -406,14 +406,6 @@ const fetchFollowers = ({ id, maxId, sinceId, limit = 20, credentials }) => {
|
||||||
.then((data) => data.json())
|
.then((data) => data.json())
|
||||||
.then((data) => data.map(parseUser))
|
.then((data) => data.map(parseUser))
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchFollowRequests = ({ credentials }) => {
|
|
||||||
const url = MASTODON_FOLLOW_REQUESTS_URL
|
|
||||||
return fetch(url, { headers: authHeaders(credentials) })
|
|
||||||
.then((data) => data.json())
|
|
||||||
.then((data) => data.map(parseUser))
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchLists = ({ credentials }) => {
|
const fetchLists = ({ credentials }) => {
|
||||||
const url = MASTODON_LISTS_URL
|
const url = MASTODON_LISTS_URL
|
||||||
return fetch(url, { headers: authHeaders(credentials) })
|
return fetch(url, { headers: authHeaders(credentials) })
|
||||||
|
@ -1601,6 +1593,26 @@ const getFollowedHashtags = ({ credentials, pagination: savedPagination }) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getFollowRequests = ({ credentials, pagination: savedPagination }) => {
|
||||||
|
const queryParams = new URLSearchParams()
|
||||||
|
if (savedPagination?.maxId) {
|
||||||
|
queryParams.append('max_id', savedPagination.maxId)
|
||||||
|
}
|
||||||
|
const url = `${MASTODON_FOLLOW_REQUESTS_URL}?${queryParams.toString()}`
|
||||||
|
let pagination = {};
|
||||||
|
return fetch(url, {
|
||||||
|
credentials
|
||||||
|
}).then((data) => {
|
||||||
|
pagination = parseLinkHeaderPagination(data.headers.get('Link'), { flakeId: true });
|
||||||
|
return data.json()
|
||||||
|
}).then((data) => {
|
||||||
|
return {
|
||||||
|
pagination,
|
||||||
|
data: data.map(parseUser)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export const getMastodonSocketURI = ({ credentials, stream, args = {} }) => {
|
export const getMastodonSocketURI = ({ credentials, stream, args = {} }) => {
|
||||||
return Object.entries({
|
return Object.entries({
|
||||||
...(credentials
|
...(credentials
|
||||||
|
@ -1790,7 +1802,6 @@ const apiService = {
|
||||||
mfaConfirmOTP,
|
mfaConfirmOTP,
|
||||||
addBackup,
|
addBackup,
|
||||||
listBackups,
|
listBackups,
|
||||||
fetchFollowRequests,
|
|
||||||
fetchLists,
|
fetchLists,
|
||||||
createList,
|
createList,
|
||||||
getList,
|
getList,
|
||||||
|
@ -1841,6 +1852,7 @@ const apiService = {
|
||||||
followHashtag,
|
followHashtag,
|
||||||
unfollowHashtag,
|
unfollowHashtag,
|
||||||
getFollowedHashtags,
|
getFollowedHashtags,
|
||||||
|
getFollowRequests
|
||||||
}
|
}
|
||||||
|
|
||||||
export default apiService
|
export default apiService
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import apiService, { getMastodonSocketURI, ProcessedWS } from '../api/api.service.js'
|
import apiService, { getMastodonSocketURI, ProcessedWS } from '../api/api.service.js'
|
||||||
import timelineFetcher from '../timeline_fetcher/timeline_fetcher.service.js'
|
import timelineFetcher from '../timeline_fetcher/timeline_fetcher.service.js'
|
||||||
import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js'
|
import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js'
|
||||||
import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service'
|
|
||||||
import listsFetcher from '../../services/lists_fetcher/lists_fetcher.service.js'
|
import listsFetcher from '../../services/lists_fetcher/lists_fetcher.service.js'
|
||||||
import announcementsFetcher from '../../services/announcements_fetcher/announcements_fetcher.service.js'
|
import announcementsFetcher from '../../services/announcements_fetcher/announcements_fetcher.service.js'
|
||||||
import configFetcher from '../config_fetcher/config_fetcher.service.js'
|
import configFetcher from '../config_fetcher/config_fetcher.service.js'
|
||||||
|
@ -28,10 +27,6 @@ const backendInteractorService = credentials => ({
|
||||||
return notificationsFetcher.fetchAndUpdate({ ...args, credentials })
|
return notificationsFetcher.fetchAndUpdate({ ...args, credentials })
|
||||||
},
|
},
|
||||||
|
|
||||||
startFetchingFollowRequests ({ store }) {
|
|
||||||
return followRequestFetcher.startFetching({ store, credentials })
|
|
||||||
},
|
|
||||||
|
|
||||||
startFetchingLists ({ store }) {
|
startFetchingLists ({ store }) {
|
||||||
return listsFetcher.startFetching({ store, credentials })
|
return listsFetcher.startFetching({ store, credentials })
|
||||||
},
|
},
|
||||||
|
|
|
@ -90,6 +90,7 @@ export const parseUser = (data) => {
|
||||||
output.friends_count = data.following_count
|
output.friends_count = data.following_count
|
||||||
|
|
||||||
output.bot = data.bot
|
output.bot = data.bot
|
||||||
|
output.follow_requests_count = data.follow_requests_count
|
||||||
if (data.akkoma) {
|
if (data.akkoma) {
|
||||||
output.instance = data.akkoma.instance
|
output.instance = data.akkoma.instance
|
||||||
output.status_ttl_days = data.akkoma.status_ttl_days
|
output.status_ttl_days = data.akkoma.status_ttl_days
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import apiService from '../api/api.service.js'
|
|
||||||
import { promiseInterval } from '../promise_interval/promise_interval.js'
|
|
||||||
|
|
||||||
const fetchAndUpdate = ({ store, credentials }) => {
|
|
||||||
return apiService.fetchFollowRequests({ credentials })
|
|
||||||
.then((requests) => {
|
|
||||||
store.commit('setFollowRequests', requests)
|
|
||||||
store.commit('addNewUsers', requests)
|
|
||||||
}, () => {})
|
|
||||||
.catch(() => {})
|
|
||||||
}
|
|
||||||
|
|
||||||
const startFetching = ({ credentials, store }) => {
|
|
||||||
const boundFetchAndUpdate = () => fetchAndUpdate({ credentials, store })
|
|
||||||
boundFetchAndUpdate()
|
|
||||||
return promiseInterval(boundFetchAndUpdate, 240000)
|
|
||||||
}
|
|
||||||
|
|
||||||
const followRequestFetcher = {
|
|
||||||
startFetching
|
|
||||||
}
|
|
||||||
|
|
||||||
export default followRequestFetcher
|
|
Loading…
Reference in a new issue