diff --git a/src/components/follow_request_card/follow_request_card.js b/src/components/follow_request_card/follow_request_card.js index b0873bb1..06af2489 100644 --- a/src/components/follow_request_card/follow_request_card.js +++ b/src/components/follow_request_card/follow_request_card.js @@ -43,6 +43,7 @@ const FollowRequestCard = { doApprove () { this.$store.state.api.backendInteractor.approveUser({ id: this.user.id }) this.$store.dispatch('removeFollowRequest', this.user) + this.$store.dispatch('decrementFollowRequestsCount') const notifId = this.findFollowRequestNotificationId() this.$store.dispatch('markSingleNotificationAsSeen', { id: notifId }) @@ -66,6 +67,7 @@ const FollowRequestCard = { this.$store.state.api.backendInteractor.denyUser({ id: this.user.id }) .then(() => { this.$store.dispatch('dismissNotificationLocal', { id: notifId }) + this.$store.dispatch('decrementFollowRequestsCount') this.$store.dispatch('removeFollowRequest', this.user) }) this.hideDenyConfirmDialog() diff --git a/src/components/follow_requests/follow_requests.js b/src/components/follow_requests/follow_requests.js index 704a76c6..e5f05643 100644 --- a/src/components/follow_requests/follow_requests.js +++ b/src/components/follow_requests/follow_requests.js @@ -1,10 +1,26 @@ 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 = { components: { - FollowRequestCard + FollowRequestCard, + FollowRequestList }, computed: { + userId () { + return this.$store.state.users.currentUser.id + }, requests () { return this.$store.state.api.followRequests } diff --git a/src/components/follow_requests/follow_requests.vue b/src/components/follow_requests/follow_requests.vue index 41f19db8..c3098292 100644 --- a/src/components/follow_requests/follow_requests.vue +++ b/src/components/follow_requests/follow_requests.vue @@ -6,12 +6,11 @@
- + + +
diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js index af165d47..0faec5e3 100644 --- a/src/components/nav_panel/nav_panel.js +++ b/src/components/nav_panel/nav_panel.js @@ -33,11 +33,6 @@ library.add( ) const NavPanel = { - created () { - if (this.currentUser && this.currentUser.locked) { - this.$store.dispatch('startFetchingFollowRequests') - } - }, components: { TimelineMenuContent }, @@ -54,11 +49,14 @@ const NavPanel = { computed: { ...mapState({ currentUser: state => state.users.currentUser, - followRequestCount: state => state.api.followRequests.length, privateMode: state => state.instance.private, federating: state => state.instance.federating }), - ...mapGetters(['unreadAnnouncementCount']) + ...mapGetters(['unreadAnnouncementCount']), + followRequestCount () { + console.log({...this.$store.state.users.currentUser}); + return this.$store.state.users.currentUser.follow_requests_count + } } } diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js index 1cadddda..9ea8c2a7 100644 --- a/src/components/user_profile/user_profile.js +++ b/src/components/user_profile/user_profile.js @@ -224,7 +224,7 @@ const UserProfile = { TabSwitcher, Conversation, RichContent, - FollowedTagList, + FollowedTagList } } diff --git a/src/modules/api.js b/src/modules/api.js index c54aa4fb..8de1449b 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -1,5 +1,6 @@ import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' import { WSConnectionStatus } from '../services/api/api.service.js' +import { map } from 'lodash' const retryTimeout = (multiplier) => 1000 * multiplier @@ -40,9 +41,6 @@ const api = { setSocket (state, socket) { state.socket = socket }, - setFollowRequests (state, value) { - state.followRequests = value - }, setMastoUserSocketStatus (state, value) { state.mastoUserSocketStatus = value }, @@ -51,6 +49,15 @@ const api = { }, resetRetryMultiplier (state) { state.retryMultiplier = 1 + }, + setFollowRequests (state, value) { + state.followRequests = [...value] + }, + saveFollowRequests (state, requests) { + state.followRequests = [...state.followRequests, ...requests] + }, + saveFollowRequestPagination (state, pagination) { + state.followRequestsPagination = pagination } }, actions: { @@ -240,24 +247,22 @@ const api = { ...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) { - let requests = store.state.followRequests.filter((it) => it !== request) + let requests = [...store.state.followRequests].filter((it) => it.id !== request.id) 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 startFetchingLists (store) { if (store.state.fetchers['lists']) return diff --git a/src/modules/users.js b/src/modules/users.js index c63b93de..bc1943c8 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -265,6 +265,12 @@ export const mutations = { signUpFailure (state, errors) { state.signUpPending = false 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) }) }, + decrementFollowRequestsCount (store) { + store.commit('decrementFollowRequestsCount') + }, + incrementFollowRequestsCount (store) { + store.commit('incrementFollowRequestsCount') + }, searchUsers ({ rootState, commit }, { query }) { return rootState.api.backendInteractor.searchUsers({ query }) .then((users) => { @@ -567,7 +579,6 @@ const users = { store.dispatch('stopFetchingTimeline', 'friends') store.commit('setBackendInteractor', backendInteractorService(store.getters.getToken())) store.dispatch('stopFetchingNotifications') - store.dispatch('stopFetchingFollowRequests') store.dispatch('stopFetchingConfig') store.commit('clearNotifications') store.commit('resetStatuses') diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 0f8b75a4..a2a766d5 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -406,14 +406,6 @@ const fetchFollowers = ({ id, maxId, sinceId, limit = 20, credentials }) => { .then((data) => data.json()) .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 url = MASTODON_LISTS_URL 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 + } + }); +} + export const getMastodonSocketURI = ({ credentials, stream, args = {} }) => { return Object.entries({ ...(credentials @@ -1790,7 +1802,6 @@ const apiService = { mfaConfirmOTP, addBackup, listBackups, - fetchFollowRequests, fetchLists, createList, getList, @@ -1841,6 +1852,7 @@ const apiService = { followHashtag, unfollowHashtag, getFollowedHashtags, + getFollowRequests } 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 4d6f80c2..58515387 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -1,7 +1,6 @@ import apiService, { getMastodonSocketURI, ProcessedWS } from '../api/api.service.js' import timelineFetcher from '../timeline_fetcher/timeline_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 announcementsFetcher from '../../services/announcements_fetcher/announcements_fetcher.service.js' import configFetcher from '../config_fetcher/config_fetcher.service.js' @@ -28,10 +27,6 @@ const backendInteractorService = credentials => ({ return notificationsFetcher.fetchAndUpdate({ ...args, credentials }) }, - startFetchingFollowRequests ({ store }) { - return followRequestFetcher.startFetching({ store, credentials }) - }, - startFetchingLists ({ store }) { return listsFetcher.startFetching({ store, credentials }) }, diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index c54ce3e2..e330ca8c 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -90,6 +90,7 @@ export const parseUser = (data) => { output.friends_count = data.following_count output.bot = data.bot + output.follow_requests_count = data.follow_requests_count if (data.akkoma) { output.instance = data.akkoma.instance output.status_ttl_days = data.akkoma.status_ttl_days diff --git a/src/services/follow_request_fetcher/follow_request_fetcher.service.js b/src/services/follow_request_fetcher/follow_request_fetcher.service.js deleted file mode 100644 index 5c0ab85e..00000000 --- a/src/services/follow_request_fetcher/follow_request_fetcher.service.js +++ /dev/null @@ -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