diff options
Diffstat (limited to 'src/modules/users.js')
| -rw-r--r-- | src/modules/users.js | 301 |
1 files changed, 199 insertions, 102 deletions
diff --git a/src/modules/users.js b/src/modules/users.js index 1a507d31..57d3a3e3 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -1,8 +1,8 @@ import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' -import { compact, map, each, merge, find, last } from 'lodash' +import oauthApi from '../services/new_api/oauth.js' +import { compact, map, each, merge, last, concat, uniq } from 'lodash' import { set } from 'vue' import { registerPushNotifications, unregisterPushNotifications } from '../services/push/push.js' -import oauthApi from '../services/new_api/oauth' import { humanizeErrors } from './errors' // TODO: Unify with mergeOrAdd in statuses.js @@ -32,11 +32,62 @@ const getNotificationPermission = () => { return Promise.resolve(Notification.permission) } +const blockUser = (store, id) => { + return store.rootState.api.backendInteractor.blockUser(id) + .then((relationship) => { + store.commit('updateUserRelationship', [relationship]) + store.commit('addBlockId', id) + store.commit('removeStatus', { timeline: 'friends', userId: id }) + store.commit('removeStatus', { timeline: 'public', userId: id }) + store.commit('removeStatus', { timeline: 'publicAndExternal', userId: id }) + }) +} + +const unblockUser = (store, id) => { + return store.rootState.api.backendInteractor.unblockUser(id) + .then((relationship) => store.commit('updateUserRelationship', [relationship])) +} + +const muteUser = (store, id) => { + return store.rootState.api.backendInteractor.muteUser(id) + .then((relationship) => { + store.commit('updateUserRelationship', [relationship]) + store.commit('addMuteId', id) + }) +} + +const unmuteUser = (store, id) => { + return store.rootState.api.backendInteractor.unmuteUser(id) + .then((relationship) => store.commit('updateUserRelationship', [relationship])) +} + export const mutations = { setMuted (state, { user: { id }, muted }) { const user = state.usersObject[id] set(user, 'muted', muted) }, + tagUser (state, { user: { id }, tag }) { + const user = state.usersObject[id] + const tags = user.tags || [] + const newTags = tags.concat([tag]) + set(user, 'tags', newTags) + }, + untagUser (state, { user: { id }, tag }) { + const user = state.usersObject[id] + const tags = user.tags || [] + const newTags = tags.filter(t => t !== tag) + set(user, 'tags', newTags) + }, + updateRight (state, { user: { id }, right, value }) { + const user = state.usersObject[id] + let newRights = user.rights + newRights[right] = value + set(user, 'rights', newRights) + }, + updateActivationStatus (state, { user: { id }, status }) { + const user = state.usersObject[id] + set(user, 'deactivated', !status) + }, setCurrentUser (state, user) { state.lastLoginName = user.screen_name state.currentUser = merge(state.currentUser || {}, user) @@ -51,42 +102,27 @@ export const mutations = { endLogin (state) { state.loggingIn = false }, - // TODO Clean after ourselves? - addFriends (state, { id, friends }) { + saveFriendIds (state, { id, friendIds }) { const user = state.usersObject[id] - each(friends, friend => { - if (!find(user.friends, { id: friend.id })) { - user.friends.push(friend) - } - }) - user.lastFriendId = last(friends).id + user.friendIds = uniq(concat(user.friendIds, friendIds)) }, - addFollowers (state, { id, followers }) { + saveFollowerIds (state, { id, followerIds }) { const user = state.usersObject[id] - each(followers, follower => { - if (!find(user.followers, { id: follower.id })) { - user.followers.push(follower) - } - }) - user.lastFollowerId = last(followers).id + user.followerIds = uniq(concat(user.followerIds, followerIds)) }, // Because frontend doesn't have a reason to keep these stuff in memory // outside of viewing someones user profile. clearFriends (state, userId) { const user = state.usersObject[userId] - if (!user) { - return + if (user) { + set(user, 'friendIds', []) } - user.friends = [] - user.lastFriendId = null }, clearFollowers (state, userId) { const user = state.usersObject[userId] - if (!user) { - return + if (user) { + set(user, 'followerIds', []) } - user.followers = [] - user.lastFollowerId = null }, addNewUsers (state, users) { each(users, (user) => mergeOrAdd(state.users, state.usersObject, user)) @@ -99,6 +135,7 @@ export const mutations = { user.following = relationship.following user.muted = relationship.muting user.statusnet_blocking = relationship.blocking + user.subscribed = relationship.subscribing } }) }, @@ -110,6 +147,11 @@ export const mutations = { saveBlockIds (state, blockIds) { state.currentUser.blockIds = blockIds }, + addBlockId (state, blockId) { + if (state.currentUser.blockIds.indexOf(blockId) === -1) { + state.currentUser.blockIds.push(blockId) + } + }, updateMutes (state, mutedUsers) { // Reset muted of all fetched users each(state.users, (user) => { user.muted = false }) @@ -118,12 +160,28 @@ export const mutations = { saveMuteIds (state, muteIds) { state.currentUser.muteIds = muteIds }, + addMuteId (state, muteId) { + if (state.currentUser.muteIds.indexOf(muteId) === -1) { + state.currentUser.muteIds.push(muteId) + } + }, + setPinned (state, status) { + const user = state.usersObject[status.user.id] + const index = user.pinnedStatuseIds.indexOf(status.id) + if (status.pinned && index === -1) { + user.pinnedStatuseIds.push(status.id) + } else if (!status.pinned && index !== -1) { + user.pinnedStatuseIds.splice(index, 1) + } + }, setUserForStatus (state, status) { status.user = state.usersObject[status.user.id] }, setUserForNotification (state, notification) { - notification.action.user = state.usersObject[notification.action.user.id] - notification.from_profile = state.usersObject[notification.action.user.id] + if (notification.type !== 'follow') { + notification.action.user = state.usersObject[notification.action.user.id] + } + notification.from_profile = state.usersObject[notification.from_profile.id] }, setColor (state, { user: { id }, highlighted }) { const user = state.usersObject[id] @@ -176,8 +234,10 @@ const users = { }) }, fetchUserRelationship (store, id) { - return store.rootState.api.backendInteractor.fetchUserRelationship({ id }) - .then((relationships) => store.commit('updateUserRelationship', relationships)) + if (store.state.currentUser) { + store.rootState.api.backendInteractor.fetchUserRelationship({ id }) + .then((relationships) => store.commit('updateUserRelationship', relationships)) + } }, fetchBlocks (store) { return store.rootState.api.backendInteractor.fetchBlocks() @@ -187,18 +247,17 @@ const users = { return blocks }) }, - blockUser (store, userId) { - return store.rootState.api.backendInteractor.blockUser(userId) - .then((relationship) => { - store.commit('updateUserRelationship', [relationship]) - store.commit('removeStatus', { timeline: 'friends', userId }) - store.commit('removeStatus', { timeline: 'public', userId }) - store.commit('removeStatus', { timeline: 'publicAndExternal', userId }) - }) + blockUser (store, id) { + return blockUser(store, id) }, unblockUser (store, id) { - return store.rootState.api.backendInteractor.unblockUser(id) - .then((relationship) => store.commit('updateUserRelationship', [relationship])) + return unblockUser(store, id) + }, + blockUsers (store, ids = []) { + return Promise.all(ids.map(id => blockUser(store, id))) + }, + unblockUsers (store, ids = []) { + return Promise.all(ids.map(id => unblockUser(store, id))) }, fetchMutes (store) { return store.rootState.api.backendInteractor.fetchMutes() @@ -209,32 +268,34 @@ const users = { }) }, muteUser (store, id) { - return store.rootState.api.backendInteractor.muteUser(id) - .then((relationship) => store.commit('updateUserRelationship', [relationship])) + return muteUser(store, id) }, unmuteUser (store, id) { - return store.rootState.api.backendInteractor.unmuteUser(id) - .then((relationship) => store.commit('updateUserRelationship', [relationship])) + return unmuteUser(store, id) }, - addFriends ({ rootState, commit }, fetchBy) { - return new Promise((resolve, reject) => { - const user = rootState.users.usersObject[fetchBy] - const maxId = user.lastFriendId - rootState.api.backendInteractor.fetchFriends({ id: user.id, maxId }) - .then((friends) => { - commit('addFriends', { id: user.id, friends }) - resolve(friends) - }).catch(() => { - reject() - }) - }) + muteUsers (store, ids = []) { + return Promise.all(ids.map(id => muteUser(store, id))) + }, + unmuteUsers (store, ids = []) { + return Promise.all(ids.map(id => unmuteUser(store, id))) + }, + fetchFriends ({ rootState, commit }, id) { + const user = rootState.users.usersObject[id] + const maxId = last(user.friendIds) + return rootState.api.backendInteractor.fetchFriends({ id, maxId }) + .then((friends) => { + commit('addNewUsers', friends) + commit('saveFriendIds', { id, friendIds: map(friends, 'id') }) + return friends + }) }, - addFollowers ({ rootState, commit }, fetchBy) { - const user = rootState.users.usersObject[fetchBy] - const maxId = user.lastFollowerId - return rootState.api.backendInteractor.fetchFollowers({ id: user.id, maxId }) + fetchFollowers ({ rootState, commit }, id) { + const user = rootState.users.usersObject[id] + const maxId = last(user.followerIds) + return rootState.api.backendInteractor.fetchFollowers({ id, maxId }) .then((followers) => { - commit('addFollowers', { id: user.id, followers }) + commit('addNewUsers', followers) + commit('saveFollowerIds', { id, followerIds: map(followers, 'id') }) return followers }) }, @@ -244,6 +305,14 @@ const users = { clearFollowers ({ commit }, userId) { commit('clearFollowers', userId) }, + subscribeUser ({ rootState, commit }, id) { + return rootState.api.backendInteractor.subscribeUser(id) + .then((relationship) => commit('updateUserRelationship', [relationship])) + }, + unsubscribeUser ({ rootState, commit }, id) { + return rootState.api.backendInteractor.unsubscribeUser(id) + .then((relationship) => commit('updateUserRelationship', [relationship])) + }, registerPushNotifications (store) { const token = store.state.currentUser.credentials const vapidPublicKey = store.rootState.instance.vapidPublicKey @@ -257,19 +326,26 @@ const users = { unregisterPushNotifications(token) }, + addNewUsers ({ commit }, users) { + commit('addNewUsers', users) + }, addNewStatuses (store, { statuses }) { const users = map(statuses, 'user') const retweetedUsers = compact(map(statuses, 'retweeted_status.user')) store.commit('addNewUsers', users) store.commit('addNewUsers', retweetedUsers) - // Reconnect users to statuses each(statuses, (status) => { + // Reconnect users to statuses store.commit('setUserForStatus', status) + // Set pinned statuses to user + store.commit('setPinned', status) }) - // Reconnect users to retweets each(compact(map(statuses, 'retweeted_status')), (status) => { + // Reconnect users to retweets store.commit('setUserForStatus', status) + // Set pinned retweets to user + store.commit('setPinned', status) }) }, addNewNotifications (store, { notifications }) { @@ -279,60 +355,78 @@ const users = { const notificationsObject = store.rootState.statuses.notifications.idStore const relevantNotifications = Object.entries(notificationsObject) - .filter(([k, val]) => notificationIds.includes(k)) - .map(([k, val]) => val) + .filter(([k, val]) => notificationIds.includes(k)) + .map(([k, val]) => val) // Reconnect users to notifications each(relevantNotifications, (notification) => { store.commit('setUserForNotification', notification) }) }, + searchUsers (store, query) { + return store.rootState.api.backendInteractor.searchUsers(query) + .then((users) => { + store.commit('addNewUsers', users) + return users + }) + }, async signUp (store, userInfo) { store.commit('signUpPending') let rootState = store.rootState - let response = await rootState.api.backendInteractor.register(userInfo) - if (response.ok) { - const data = { - oauth: rootState.oauth, - instance: rootState.instance.server - } - let app = await oauthApi.getOrCreateApp(data) - let result = await oauthApi.getTokenWithCredentials({ - app, - instance: data.instance, - username: userInfo.username, - password: userInfo.password - }) + try { + let data = await rootState.api.backendInteractor.register(userInfo) store.commit('signUpSuccess') - store.commit('setToken', result.access_token) - store.dispatch('loginUser', result.access_token) - } else { - const data = await response.json() - let errors = JSON.parse(data.error) + store.commit('setToken', data.access_token) + store.dispatch('loginUser', data.access_token) + } catch (e) { + let errors = e.message // replace ap_id with username - if (errors.ap_id) { - errors.username = errors.ap_id - delete errors.ap_id + if (typeof errors === 'object') { + if (errors.ap_id) { + errors.username = errors.ap_id + delete errors.ap_id + } + errors = humanizeErrors(errors) } - errors = humanizeErrors(errors) store.commit('signUpFailure', errors) throw Error(errors) } }, async getCaptcha (store) { - return await store.rootState.api.backendInteractor.getCaptcha() + return store.rootState.api.backendInteractor.getCaptcha() }, logout (store) { - store.commit('clearCurrentUser') - store.dispatch('disconnectFromChat') - store.commit('setToken', false) - store.dispatch('stopFetching', 'friends') - store.commit('setBackendInteractor', backendInteractorService()) - store.dispatch('stopFetchingNotifications') - store.commit('resetStatuses') + const { oauth, instance } = store.rootState + + const data = { + ...oauth, + commit: store.commit, + instance: instance.server + } + + return oauthApi.getOrCreateApp(data) + .then((app) => { + const params = { + app, + instance: data.instance, + token: oauth.userToken + } + + return oauthApi.revokeToken(params) + }) + .then(() => { + store.commit('clearCurrentUser') + store.dispatch('disconnectFromChat') + store.commit('clearToken') + store.dispatch('stopFetching', 'friends') + store.commit('setBackendInteractor', backendInteractorService(store.getters.getToken())) + store.dispatch('stopFetching', 'notifications') + store.commit('clearNotifications') + store.commit('resetStatuses') + }) }, loginUser (store, accessToken) { return new Promise((resolve, reject) => { @@ -363,7 +457,10 @@ const users = { } // Start getting fresh posts. - store.dispatch('startFetching', { timeline: 'friends' }) + store.dispatch('startFetchingTimeline', { timeline: 'friends' }) + + // Start fetching notifications + store.dispatch('startFetchingNotifications') // Get user mutes store.dispatch('fetchMutes') @@ -376,19 +473,19 @@ const users = { // Authentication failed commit('endLogin') if (response.status === 401) { - reject('Wrong username or password') + reject(new Error('Wrong username or password')) } else { - reject('An error occurred, please try again') + reject(new Error('An error occurred, please try again')) } } commit('endLogin') resolve() }) - .catch((error) => { - console.log(error) - commit('endLogin') - reject('Failed to connect to server, try again') - }) + .catch((error) => { + console.log(error) + commit('endLogin') + reject(new Error('Failed to connect to server, try again')) + }) }) } } |
