Since BE doesn't support fetching user by screen name over MastoAPI we'll gonna

just fetching it over QvitterAPI real quick :DDDDDDDDD
This commit is contained in:
Henry Jameson 2019-03-08 22:40:57 +02:00
parent 853e0bc26f
commit 4f3a220487
10 changed files with 65 additions and 56 deletions

View file

@ -9,7 +9,7 @@ const BlockCard = {
}, },
computed: { computed: {
user () { user () {
return this.$store.getters.userById(this.userId) return this.$store.getters.findUser(this.userId)
}, },
blocked () { blocked () {
return this.user.statusnet_blocking return this.user.statusnet_blocking

View file

@ -9,7 +9,7 @@ const MuteCard = {
}, },
computed: { computed: {
user () { user () {
return this.$store.getters.userById(this.userId) return this.$store.getters.findUser(this.userId)
}, },
muted () { muted () {
return this.user.muted return this.user.muted

View file

@ -9,7 +9,7 @@ import withList from '../../hocs/with_list/with_list'
const FollowerList = compose( const FollowerList = compose(
withLoadMore({ withLoadMore({
fetch: (props, $store) => $store.dispatch('addFollowers', props.userId), fetch: (props, $store) => $store.dispatch('addFollowers', props.userId),
select: (props, $store) => get($store.getters.userById(props.userId), 'followers', []), select: (props, $store) => get($store.getters.findUser(props.userId), 'followers', []),
destory: (props, $store) => $store.dispatch('clearFollowers', props.userId), destory: (props, $store) => $store.dispatch('clearFollowers', props.userId),
childPropName: 'entries', childPropName: 'entries',
additionalPropNames: ['userId'] additionalPropNames: ['userId']
@ -20,7 +20,7 @@ const FollowerList = compose(
const FriendList = compose( const FriendList = compose(
withLoadMore({ withLoadMore({
fetch: (props, $store) => $store.dispatch('addFriends', props.userId), fetch: (props, $store) => $store.dispatch('addFriends', props.userId),
select: (props, $store) => get($store.getters.userById(props.userId), 'friends', []), select: (props, $store) => get($store.getters.findUser(props.userId), 'friends', []),
destory: (props, $store) => $store.dispatch('clearFriends', props.userId), destory: (props, $store) => $store.dispatch('clearFriends', props.userId),
childPropName: 'entries', childPropName: 'entries',
additionalPropNames: ['userId'] additionalPropNames: ['userId']
@ -31,19 +31,22 @@ const FriendList = compose(
const UserProfile = { const UserProfile = {
data () { data () {
return { return {
error: false error: false,
fetchedUserId: null
} }
}, },
created () { created () {
this.$store.commit('clearTimeline', { timeline: 'user' })
this.$store.commit('clearTimeline', { timeline: 'favorites' })
this.$store.commit('clearTimeline', { timeline: 'media' })
this.$store.dispatch('startFetching', { timeline: 'user', userId: this.fetchBy })
this.$store.dispatch('startFetching', { timeline: 'media', userId: this.fetchBy })
this.startFetchFavorites()
if (!this.user.id) { if (!this.user.id) {
this.$store.dispatch('fetchUser', this.fetchBy) let fetchPromise
.then(() => this.$store.dispatch('fetchUserRelationship', this.fetchBy)) if (this.userId) {
fetchPromise = this.$store.dispatch('fetchUser', this.userId)
} else {
fetchPromise = this.$store.dispatch('fetchUserByScreenName', this.userName)
.then(userId => {
this.fetchedUserId = userId
})
}
fetchPromise
.catch((reason) => { .catch((reason) => {
const errorMessage = get(reason, 'error.error') const errorMessage = get(reason, 'error.error')
if (errorMessage === 'No user with such user_id') { // Known error if (errorMessage === 'No user with such user_id') { // Known error
@ -54,8 +57,7 @@ const UserProfile = {
this.error = this.$t('user_profile.profile_loading_error') this.error = this.$t('user_profile.profile_loading_error')
} }
}) })
} else if (typeof this.user.following === 'undefined' || this.user.following === null) { .then(() => this.startUp())
this.$store.dispatch('fetchUserRelationship', this.fetchBy)
} }
}, },
destroyed () { destroyed () {
@ -72,7 +74,7 @@ const UserProfile = {
return this.$store.state.statuses.timelines.media return this.$store.state.statuses.timelines.media
}, },
userId () { userId () {
return this.$route.params.id || this.user.id return this.$route.params.id || this.user.id || this.fetchedUserId
}, },
userName () { userName () {
return this.$route.params.name || this.user.screen_name return this.$route.params.name || this.user.screen_name
@ -82,10 +84,8 @@ const UserProfile = {
this.userId === this.$store.state.users.currentUser.id this.userId === this.$store.state.users.currentUser.id
}, },
userInStore () { userInStore () {
if (this.isExternal) { const routeParams = this.$route.params
return this.$store.getters.userById(this.userId) return this.$store.getters.findUser(routeParams.name || routeParams.iid)
}
return this.$store.getters.userByName(this.userName)
}, },
user () { user () {
if (this.timeline.statuses[0]) { if (this.timeline.statuses[0]) {
@ -96,9 +96,6 @@ const UserProfile = {
} }
return {} return {}
}, },
fetchBy () {
return this.isExternal ? this.userId : this.userName
},
isExternal () { isExternal () {
return this.$route.name === 'external-user-profile' return this.$route.name === 'external-user-profile'
}, },
@ -112,13 +109,13 @@ const UserProfile = {
methods: { methods: {
startFetchFavorites () { startFetchFavorites () {
if (this.isUs) { if (this.isUs) {
this.$store.dispatch('startFetching', { timeline: 'favorites', userId: this.fetchBy }) this.$store.dispatch('startFetching', { timeline: 'favorites', userId: this.userId })
} }
}, },
startUp () { startUp () {
this.$store.dispatch('startFetching', { timeline: 'user', userId: this.fetchBy }) this.$store.dispatch('fetchUserRelationship', this.userId)
this.$store.dispatch('startFetching', { timeline: 'media', userId: this.fetchBy }) this.$store.dispatch('startFetching', { timeline: 'user', userId: this.userId })
this.$store.dispatch('startFetching', { timeline: 'media', userId: this.userId })
this.startFetchFavorites() this.startFetchFavorites()
}, },
cleanUp () { cleanUp () {
@ -131,19 +128,11 @@ const UserProfile = {
} }
}, },
watch: { watch: {
userName () { userId (newVal, oldVal) {
if (this.isExternal) { if (newVal) {
return this.cleanUp()
this.startUp()
} }
this.cleanUp()
this.startUp()
},
userId () {
if (!this.isExternal) {
return
}
this.cleanUp()
this.startUp()
}, },
$route () { $route () {
this.$refs.tabSwitcher.activateTab(0)() this.$refs.tabSwitcher.activateTab(0)()

View file

@ -11,7 +11,7 @@
:title="$t('user_profile.timeline_title')" :title="$t('user_profile.timeline_title')"
:timeline="timeline" :timeline="timeline"
:timeline-name="'user'" :timeline-name="'user'"
:user-id="fetchBy" :user-id="userId"
/> />
<div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count"> <div :label="$t('user_card.followees')" v-if="followsTabVisible" :disabled="!user.friends_count">
<FriendList :userId="userId" /> <FriendList :userId="userId" />
@ -25,7 +25,7 @@
:embedded="true" :title="$t('user_card.media')" :embedded="true" :title="$t('user_card.media')"
timeline-name="media" timeline-name="media"
:timeline="media" :timeline="media"
:user-id="fetchBy" :user-id="userId"
/> />
<Timeline <Timeline
v-if="isUs" v-if="isUs"

View file

@ -135,6 +135,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
// This makes sure that user timeline won't get data meant for other // This makes sure that user timeline won't get data meant for other
// user. I.e. opening different user profiles makes request which could // user. I.e. opening different user profiles makes request which could
// return data late after user already viewing different user profile // return data late after user already viewing different user profile
console.log('TIMEINLINE', timelineObject.userId)
if ((timeline === 'user' || timeline === 'media') && timelineObject.userId !== userId) { if ((timeline === 'user' || timeline === 'media') && timelineObject.userId !== userId) {
return return
} }

View file

@ -138,12 +138,7 @@ export const mutations = {
} }
export const getters = { export const getters = {
userById: state => id => findUser: state => query => state.usersObject[query]
state.users.find(user => user.id === id),
userByName: state => name =>
state.users.find(user => user.screen_name &&
(user.screen_name.toLowerCase() === name.toLowerCase())
)
} }
export const defaultState = { export const defaultState = {
@ -165,6 +160,11 @@ const users = {
return store.rootState.api.backendInteractor.fetchUser({ id }) return store.rootState.api.backendInteractor.fetchUser({ id })
.then((user) => store.commit('addNewUsers', [user])) .then((user) => store.commit('addNewUsers', [user]))
}, },
fetchUserByScreenName (store, screenName) {
return store.rootState.api.backendInteractor.figureOutUserId({ screenName })
.then((qvitterUserData) => store.rootState.api.backendInteractor.fetchUser({ id: qvitterUserData.id }))
.then((user) => store.commit('addNewUsers', [user]) || user.id)
},
fetchUserRelationship (store, id) { fetchUserRelationship (store, id) {
return store.rootState.api.backendInteractor.fetchUserRelationship({ id }) return store.rootState.api.backendInteractor.fetchUserRelationship({ id })
.then((relationships) => store.commit('updateUserRelationship', relationships)) .then((relationships) => store.commit('updateUserRelationship', relationships))

View file

@ -32,6 +32,7 @@ const QVITTER_USER_NOTIFICATIONS_URL = '/api/qvitter/statuses/notifications.json
const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json' const QVITTER_USER_NOTIFICATIONS_READ_URL = '/api/qvitter/statuses/notifications/read.json'
const BLOCKING_URL = '/api/blocks/create.json' const BLOCKING_URL = '/api/blocks/create.json'
const UNBLOCKING_URL = '/api/blocks/destroy.json' const UNBLOCKING_URL = '/api/blocks/destroy.json'
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'
@ -41,7 +42,7 @@ const DENY_USER_URL = '/api/pleroma/friendships/deny'
const SUGGESTIONS_URL = '/api/v1/suggestions' const SUGGESTIONS_URL = '/api/v1/suggestions'
const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites' const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites'
const MASTODON_USER_URL = '/api/v1/accounts/' const MASTODON_USER_URL = '/api/v1/accounts'
const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships' const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships'
const MASTODON_USER_TIMELINE_URL = id => `/api/v1/accounts/${id}/statuses` const MASTODON_USER_TIMELINE_URL = id => `/api/v1/accounts/${id}/statuses`
@ -272,6 +273,22 @@ const fetchUserRelationship = ({id, credentials}) => {
}) })
} }
// TODO remove once MastoAPI supports screen_name in fetchUser one
const figureOutUserId = ({screenName, credentials}) => {
let url = `${USER_URL}/?user_id=${screenName}`
return fetch(url, { headers: authHeaders(credentials) })
.then((response) => {
return new Promise((resolve, reject) => response.json()
.then((json) => {
if (!response.ok) {
return reject(new StatusCodeError(response.status, json, { url }, response))
}
return resolve(json)
}))
})
.then((data) => parseUser(data))
}
const fetchFriends = ({id, page, credentials}) => { const fetchFriends = ({id, page, credentials}) => {
let url = `${FRIENDS_URL}?user_id=${id}` let url = `${FRIENDS_URL}?user_id=${id}`
if (page) { if (page) {
@ -382,9 +399,6 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
if (until) { if (until) {
params.push(['max_id', until]) params.push(['max_id', until])
} }
if (userId) {
params.push(['user_id', userId])
}
if (tag) { if (tag) {
url += `/${tag}.json` url += `/${tag}.json`
} }
@ -608,6 +622,7 @@ const apiService = {
unblockUser, unblockUser,
fetchUser, fetchUser,
fetchUserRelationship, fetchUserRelationship,
figureOutUserId,
favorite, favorite,
unfavorite, unfavorite,
retweet, retweet,

View file

@ -26,6 +26,10 @@ const backendInteractorService = (credentials) => {
return apiService.fetchAllFollowing({username, credentials}) return apiService.fetchAllFollowing({username, credentials})
} }
const figureOutUserId = ({screenName}) => {
return apiService.figureOutUserId({screenName, credentials})
}
const fetchUser = ({id}) => { const fetchUser = ({id}) => {
return apiService.fetchUser({id, credentials}) return apiService.fetchUser({id, credentials})
} }
@ -95,6 +99,7 @@ const backendInteractorService = (credentials) => {
unfollowUser, unfollowUser,
blockUser, blockUser,
unblockUser, unblockUser,
figureOutUserId,
fetchUser, fetchUser,
fetchUserRelationship, fetchUserRelationship,
fetchAllFollowing, fetchAllFollowing,

View file

@ -13,8 +13,7 @@ const mutations = {
} }
const testGetters = { const testGetters = {
userByName: state => getters.userByName(state.users), findUser: state => getters.findUser(state.users)
userById: state => getters.userById(state.users)
} }
const localUser = { const localUser = {

View file

@ -43,7 +43,7 @@ describe('The users module', () => {
} }
const name = 'Guy' const name = 'Guy'
const expected = { screen_name: 'Guy', id: '1' } const expected = { screen_name: 'Guy', id: '1' }
expect(getters.userByName(state)(name)).to.eql(expected) expect(getters.findUser(state)(name)).to.eql(expected)
}) })
it('returns user with matching screen_name with different case', () => { it('returns user with matching screen_name with different case', () => {
@ -54,7 +54,7 @@ describe('The users module', () => {
} }
const name = 'Guy' const name = 'Guy'
const expected = { screen_name: 'guy', id: '1' } const expected = { screen_name: 'guy', id: '1' }
expect(getters.userByName(state)(name)).to.eql(expected) expect(getters.findUser(state)(name)).to.eql(expected)
}) })
}) })
@ -67,7 +67,7 @@ describe('The users module', () => {
} }
const id = '1' const id = '1'
const expected = { screen_name: 'Guy', id: '1' } const expected = { screen_name: 'Guy', id: '1' }
expect(getters.userById(state)(id)).to.eql(expected) expect(getters.findUser(state)(id)).to.eql(expected)
}) })
}) })
}) })