Merge branch 'mastoapi/user-stuff' into shigusegubu
* mastoapi/user-stuff: whoops レインせんぱいにサンキュー fix embedded relationship card parsing actually use embedded relationship if it's present instead of filtering nulls, let's just not have them in the first place fixed tests, review fixes, now storing local users with downcase screen name for better compatibility fix error some test fixes, disabled one test for now since logic now is even more async in general attempt at fixing switching to user TL fix reply-to marker, also whoops console log revert some stuff, turns out it's actually breaking. Fixed some local user things Since BE doesn't support fetching user by screen name over MastoAPI we'll gonna just fetching it over QvitterAPI real quick :DDDDDDDDD switch to mastoapi for user timeline Partially transitioned user data to MastoAPI. Added support for fetching relationship data. Upgraded code to be more resilient to nulls caused by missing data in either APIs
This commit is contained in:
commit
c0908e238f
13 changed files with 153 additions and 107 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -145,11 +145,11 @@ const Status = {
|
||||||
return !!(this.status.in_reply_to_status_id && this.status.in_reply_to_user_id)
|
return !!(this.status.in_reply_to_status_id && this.status.in_reply_to_user_id)
|
||||||
},
|
},
|
||||||
replyToName () {
|
replyToName () {
|
||||||
const user = this.$store.state.users.usersObject[this.status.in_reply_to_user_id]
|
if (this.status.in_reply_to_screen_name) {
|
||||||
if (user) {
|
|
||||||
return user.screen_name
|
|
||||||
} else {
|
|
||||||
return this.status.in_reply_to_screen_name
|
return this.status.in_reply_to_screen_name
|
||||||
|
} else {
|
||||||
|
const user = this.$store.getters.findUser(this.status.in_reply_to_user_id)
|
||||||
|
return user && user.screen_name
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hideReply () {
|
hideReply () {
|
||||||
|
|
|
@ -15,6 +15,9 @@ export default {
|
||||||
betterShadow: this.$store.state.interface.browserSupport.cssFilter
|
betterShadow: this.$store.state.interface.browserSupport.cssFilter
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created () {
|
||||||
|
this.$store.dispatch('fetchUserRelationship', this.user.id)
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
classes () {
|
classes () {
|
||||||
return [{
|
return [{
|
||||||
|
|
|
@ -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,28 +31,16 @@ 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)
|
this.fetchUserId()
|
||||||
.catch((reason) => {
|
.then(() => this.startUp())
|
||||||
const errorMessage = get(reason, 'error.error')
|
|
||||||
if (errorMessage === 'No user with such user_id') { // Known error
|
|
||||||
this.error = this.$t('user_profile.profile_does_not_exist')
|
|
||||||
} else if (errorMessage) {
|
|
||||||
this.error = errorMessage
|
|
||||||
} else {
|
} else {
|
||||||
this.error = this.$t('user_profile.profile_loading_error')
|
this.startUp()
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroyed () {
|
destroyed () {
|
||||||
|
@ -69,7 +57,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
|
||||||
|
@ -79,10 +67,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.id)
|
||||||
}
|
|
||||||
return this.$store.getters.userByName(this.userName)
|
|
||||||
},
|
},
|
||||||
user () {
|
user () {
|
||||||
if (this.timeline.statuses[0]) {
|
if (this.timeline.statuses[0]) {
|
||||||
|
@ -93,9 +79,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'
|
||||||
},
|
},
|
||||||
|
@ -109,14 +92,38 @@ 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 })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
fetchUserId () {
|
||||||
|
let fetchPromise
|
||||||
|
if (this.userId && !this.$route.params.name) {
|
||||||
|
fetchPromise = this.$store.dispatch('fetchUser', this.userId)
|
||||||
|
} else {
|
||||||
|
fetchPromise = this.$store.dispatch('fetchUser', this.userName)
|
||||||
|
.then(({ id }) => {
|
||||||
|
this.fetchedUserId = id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return fetchPromise
|
||||||
|
.catch((reason) => {
|
||||||
|
const errorMessage = get(reason, 'error.error')
|
||||||
|
if (errorMessage === 'No user with such user_id') { // Known error
|
||||||
|
this.error = this.$t('user_profile.profile_does_not_exist')
|
||||||
|
} else if (errorMessage) {
|
||||||
|
this.error = errorMessage
|
||||||
|
} else {
|
||||||
|
this.error = this.$t('user_profile.profile_loading_error')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => this.startUp())
|
||||||
|
},
|
||||||
startUp () {
|
startUp () {
|
||||||
this.$store.dispatch('startFetching', { timeline: 'user', userId: this.fetchBy })
|
if (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 () {
|
||||||
this.$store.dispatch('stopFetching', 'user')
|
this.$store.dispatch('stopFetching', 'user')
|
||||||
|
@ -128,19 +135,19 @@ const UserProfile = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
userName () {
|
// userId can be undefined if we don't know it yet
|
||||||
if (this.isExternal) {
|
userId (newVal) {
|
||||||
return
|
if (newVal) {
|
||||||
}
|
|
||||||
this.cleanUp()
|
this.cleanUp()
|
||||||
this.startUp()
|
this.startUp()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
userId () {
|
userName () {
|
||||||
if (!this.isExternal) {
|
if (this.$route.params.name) {
|
||||||
return
|
this.fetchUserId()
|
||||||
}
|
|
||||||
this.cleanUp()
|
this.cleanUp()
|
||||||
this.startUp()
|
this.startUp()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
$route () {
|
$route () {
|
||||||
this.$refs.tabSwitcher.activateTab(0)()
|
this.$refs.tabSwitcher.activateTab(0)()
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { remove, slice, each, find, maxBy, minBy, merge, first, last, isArray } from 'lodash'
|
import { remove, slice, each, find, maxBy, minBy, merge, first, last, isArray, omitBy } from 'lodash'
|
||||||
import apiService from '../services/api/api.service.js'
|
import apiService from '../services/api/api.service.js'
|
||||||
// import parse from '../services/status_parser/status_parser.js'
|
// import parse from '../services/status_parser/status_parser.js'
|
||||||
|
|
||||||
|
@ -72,7 +72,9 @@ const mergeOrAdd = (arr, obj, item) => {
|
||||||
|
|
||||||
if (oldItem) {
|
if (oldItem) {
|
||||||
// We already have this, so only merge the new info.
|
// We already have this, so only merge the new info.
|
||||||
merge(oldItem, item)
|
// We ignore null values to avoid overwriting existing properties with missing data
|
||||||
|
// we also skip 'user' because that is handled by users module
|
||||||
|
merge(oldItem, omitBy(item, (v, k) => v === null || k === 'user'))
|
||||||
// Reactivity fix.
|
// Reactivity fix.
|
||||||
oldItem.attachments.splice(oldItem.attachments.length)
|
oldItem.attachments.splice(oldItem.attachments.length)
|
||||||
return {item: oldItem, new: false}
|
return {item: oldItem, new: false}
|
||||||
|
|
|
@ -18,7 +18,7 @@ export const mergeOrAdd = (arr, obj, item) => {
|
||||||
arr.push(item)
|
arr.push(item)
|
||||||
obj[item.id] = item
|
obj[item.id] = item
|
||||||
if (item.screen_name && !item.screen_name.includes('@')) {
|
if (item.screen_name && !item.screen_name.includes('@')) {
|
||||||
obj[item.screen_name] = item
|
obj[item.screen_name.toLowerCase()] = item
|
||||||
}
|
}
|
||||||
return { item, new: true }
|
return { item, new: true }
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,16 @@ export const mutations = {
|
||||||
addNewUsers (state, users) {
|
addNewUsers (state, users) {
|
||||||
each(users, (user) => mergeOrAdd(state.users, state.usersObject, user))
|
each(users, (user) => mergeOrAdd(state.users, state.usersObject, user))
|
||||||
},
|
},
|
||||||
|
updateUserRelationship (state, relationships) {
|
||||||
|
relationships.forEach((relationship) => {
|
||||||
|
const user = state.usersObject[relationship.id]
|
||||||
|
|
||||||
|
user.follows_you = relationship.followed_by
|
||||||
|
user.following = relationship.following
|
||||||
|
user.muted = relationship.muting
|
||||||
|
user.statusnet_blocking = relationship.blocking
|
||||||
|
})
|
||||||
|
},
|
||||||
saveBlocks (state, blockIds) {
|
saveBlocks (state, blockIds) {
|
||||||
state.currentUser.blockIds = blockIds
|
state.currentUser.blockIds = blockIds
|
||||||
},
|
},
|
||||||
|
@ -122,12 +132,7 @@ export const mutations = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getters = {
|
export const getters = {
|
||||||
userById: state => id =>
|
findUser: state => query => state.usersObject[typeof query === 'string' ? query.toLowerCase() : 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 = {
|
||||||
|
@ -147,7 +152,14 @@ const users = {
|
||||||
actions: {
|
actions: {
|
||||||
fetchUser (store, id) {
|
fetchUser (store, id) {
|
||||||
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])
|
||||||
|
return user
|
||||||
|
})
|
||||||
|
},
|
||||||
|
fetchUserRelationship (store, id) {
|
||||||
|
return store.rootState.api.backendInteractor.fetchUserRelationship({ id })
|
||||||
|
.then((relationships) => store.commit('updateUserRelationship', relationships))
|
||||||
},
|
},
|
||||||
fetchBlocks (store) {
|
fetchBlocks (store) {
|
||||||
return store.rootState.api.backendInteractor.fetchBlocks()
|
return store.rootState.api.backendInteractor.fetchBlocks()
|
||||||
|
|
|
@ -28,12 +28,10 @@ const BG_UPDATE_URL = '/api/qvitter/update_background_image.json'
|
||||||
const BANNER_UPDATE_URL = '/api/account/update_profile_banner.json'
|
const BANNER_UPDATE_URL = '/api/account/update_profile_banner.json'
|
||||||
const PROFILE_UPDATE_URL = '/api/account/update_profile.json'
|
const PROFILE_UPDATE_URL = '/api/account/update_profile.json'
|
||||||
const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json'
|
const EXTERNAL_PROFILE_URL = '/api/externalprofile/show.json'
|
||||||
const QVITTER_USER_TIMELINE_URL = '/api/qvitter/statuses/user_timeline.json'
|
|
||||||
const QVITTER_USER_NOTIFICATIONS_URL = '/api/qvitter/statuses/notifications.json'
|
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'
|
||||||
|
@ -43,6 +41,9 @@ 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_RELATIONSHIPS_URL = '/api/v1/accounts/relationships'
|
||||||
|
const MASTODON_USER_TIMELINE_URL = id => `/api/v1/accounts/${id}/statuses`
|
||||||
|
|
||||||
import { each, map } from 'lodash'
|
import { each, map } from 'lodash'
|
||||||
import { parseStatus, parseUser, parseNotification } from '../entity_normalizer/entity_normalizer.service.js'
|
import { parseStatus, parseUser, parseNotification } from '../entity_normalizer/entity_normalizer.service.js'
|
||||||
|
@ -243,7 +244,7 @@ const denyUser = ({id, credentials}) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchUser = ({id, credentials}) => {
|
const fetchUser = ({id, credentials}) => {
|
||||||
let url = `${USER_URL}?user_id=${id}`
|
let url = `${MASTODON_USER_URL}/${id}`
|
||||||
return fetch(url, { headers: authHeaders(credentials) })
|
return fetch(url, { headers: authHeaders(credentials) })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return new Promise((resolve, reject) => response.json()
|
return new Promise((resolve, reject) => response.json()
|
||||||
|
@ -257,6 +258,20 @@ const fetchUser = ({id, credentials}) => {
|
||||||
.then((data) => parseUser(data))
|
.then((data) => parseUser(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fetchUserRelationship = ({id, credentials}) => {
|
||||||
|
let url = `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}`
|
||||||
|
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)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -347,8 +362,8 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
|
||||||
dms: DM_TIMELINE_URL,
|
dms: DM_TIMELINE_URL,
|
||||||
notifications: QVITTER_USER_NOTIFICATIONS_URL,
|
notifications: QVITTER_USER_NOTIFICATIONS_URL,
|
||||||
'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL,
|
'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL,
|
||||||
user: QVITTER_USER_TIMELINE_URL,
|
user: MASTODON_USER_TIMELINE_URL,
|
||||||
media: QVITTER_USER_TIMELINE_URL,
|
media: MASTODON_USER_TIMELINE_URL,
|
||||||
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
|
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
|
||||||
tag: TAG_TIMELINE_URL
|
tag: TAG_TIMELINE_URL
|
||||||
}
|
}
|
||||||
|
@ -357,15 +372,16 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
|
||||||
|
|
||||||
let url = timelineUrls[timeline]
|
let url = timelineUrls[timeline]
|
||||||
|
|
||||||
|
if (timeline === 'user' || timeline === 'media') {
|
||||||
|
url = url(userId)
|
||||||
|
}
|
||||||
|
|
||||||
if (since) {
|
if (since) {
|
||||||
params.push(['since_id', since])
|
params.push(['since_id', since])
|
||||||
}
|
}
|
||||||
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`
|
||||||
}
|
}
|
||||||
|
@ -587,6 +603,7 @@ const apiService = {
|
||||||
blockUser,
|
blockUser,
|
||||||
unblockUser,
|
unblockUser,
|
||||||
fetchUser,
|
fetchUser,
|
||||||
|
fetchUserRelationship,
|
||||||
favorite,
|
favorite,
|
||||||
unfavorite,
|
unfavorite,
|
||||||
retweet,
|
retweet,
|
||||||
|
|
|
@ -30,6 +30,10 @@ const backendInteractorService = (credentials) => {
|
||||||
return apiService.fetchUser({id, credentials})
|
return apiService.fetchUser({id, credentials})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fetchUserRelationship = ({id}) => {
|
||||||
|
return apiService.fetchUserRelationship({id, credentials})
|
||||||
|
}
|
||||||
|
|
||||||
const followUser = (id) => {
|
const followUser = (id) => {
|
||||||
return apiService.followUser({credentials, id})
|
return apiService.followUser({credentials, id})
|
||||||
}
|
}
|
||||||
|
@ -92,6 +96,7 @@ const backendInteractorService = (credentials) => {
|
||||||
blockUser,
|
blockUser,
|
||||||
unblockUser,
|
unblockUser,
|
||||||
fetchUser,
|
fetchUser,
|
||||||
|
fetchUserRelationship,
|
||||||
fetchAllFollowing,
|
fetchAllFollowing,
|
||||||
verifyCredentials: apiService.verifyCredentials,
|
verifyCredentials: apiService.verifyCredentials,
|
||||||
startFetching,
|
startFetching,
|
||||||
|
|
|
@ -39,10 +39,10 @@ export const parseUser = (data) => {
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
output.name = null // missing
|
// output.name = ??? missing
|
||||||
output.name_html = data.display_name
|
output.name_html = data.display_name
|
||||||
|
|
||||||
output.description = null // missing
|
// output.description = ??? missing
|
||||||
output.description_html = data.note
|
output.description_html = data.note
|
||||||
|
|
||||||
// Utilize avatar_static for gif avatars?
|
// Utilize avatar_static for gif avatars?
|
||||||
|
@ -59,10 +59,14 @@ export const parseUser = (data) => {
|
||||||
output.statusnet_profile_url = data.url
|
output.statusnet_profile_url = data.url
|
||||||
|
|
||||||
if (data.pleroma) {
|
if (data.pleroma) {
|
||||||
const pleroma = data.pleroma
|
const relationship = data.pleroma.relationship
|
||||||
output.follows_you = pleroma.follows_you
|
|
||||||
output.statusnet_blocking = pleroma.statusnet_blocking
|
if (relationship) {
|
||||||
output.muted = pleroma.muted
|
output.follows_you = relationship.followed_by
|
||||||
|
output.following = relationship.following
|
||||||
|
output.statusnet_blocking = relationship.blocking
|
||||||
|
output.muted = relationship.muting
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Missing, trying to recover
|
// Missing, trying to recover
|
||||||
|
@ -83,7 +87,7 @@ export const parseUser = (data) => {
|
||||||
|
|
||||||
output.friends_count = data.friends_count
|
output.friends_count = data.friends_count
|
||||||
|
|
||||||
output.bot = null // missing
|
// output.bot = ??? missing
|
||||||
|
|
||||||
output.statusnet_profile_url = data.statusnet_profile_url
|
output.statusnet_profile_url = data.statusnet_profile_url
|
||||||
|
|
||||||
|
@ -134,7 +138,7 @@ const parseAttachment = (data) => {
|
||||||
output.meta = data.meta // not present in BE yet
|
output.meta = data.meta // not present in BE yet
|
||||||
} else {
|
} else {
|
||||||
output.mimetype = data.mimetype
|
output.mimetype = data.mimetype
|
||||||
output.meta = null // missing
|
// output.meta = ??? missing
|
||||||
}
|
}
|
||||||
|
|
||||||
output.url = data.url
|
output.url = data.url
|
||||||
|
@ -166,7 +170,7 @@ export const parseStatus = (data) => {
|
||||||
output.in_reply_to_user_id = data.in_reply_to_account_id
|
output.in_reply_to_user_id = data.in_reply_to_account_id
|
||||||
|
|
||||||
// Missing!! fix in UI?
|
// Missing!! fix in UI?
|
||||||
output.in_reply_to_screen_name = null
|
// output.in_reply_to_screen_name = ???
|
||||||
|
|
||||||
// Not exactly the same but works
|
// Not exactly the same but works
|
||||||
output.statusnet_conversation_id = data.id
|
output.statusnet_conversation_id = data.id
|
||||||
|
@ -179,8 +183,7 @@ export const parseStatus = (data) => {
|
||||||
output.summary_html = data.spoiler_text
|
output.summary_html = data.spoiler_text
|
||||||
output.external_url = data.url
|
output.external_url = data.url
|
||||||
|
|
||||||
// FIXME missing!!
|
// output.is_local = ??? missing
|
||||||
output.is_local = false
|
|
||||||
} else {
|
} else {
|
||||||
output.favorited = data.favorited
|
output.favorited = data.favorited
|
||||||
output.fave_num = data.fave_num
|
output.fave_num = data.fave_num
|
||||||
|
@ -259,7 +262,7 @@ export const parseNotification = (data) => {
|
||||||
|
|
||||||
if (masto) {
|
if (masto) {
|
||||||
output.type = mastoDict[data.type] || data.type
|
output.type = mastoDict[data.type] || data.type
|
||||||
output.seen = null // missing
|
// output.seen = ??? missing
|
||||||
output.status = parseStatus(data.status)
|
output.status = parseStatus(data.status)
|
||||||
output.action = output.status // not sure
|
output.action = output.status // not sure
|
||||||
output.from_profile = parseUser(data.account)
|
output.from_profile = parseUser(data.account)
|
||||||
|
|
|
@ -12,9 +12,13 @@ const mutations = {
|
||||||
setError: () => {}
|
setError: () => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
fetchUser: () => {},
|
||||||
|
fetchUserByScreenName: () => {}
|
||||||
|
}
|
||||||
|
|
||||||
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 = {
|
||||||
|
@ -31,6 +35,7 @@ const extUser = {
|
||||||
|
|
||||||
const externalProfileStore = new Vuex.Store({
|
const externalProfileStore = new Vuex.Store({
|
||||||
mutations,
|
mutations,
|
||||||
|
actions,
|
||||||
getters: testGetters,
|
getters: testGetters,
|
||||||
state: {
|
state: {
|
||||||
api: {
|
api: {
|
||||||
|
@ -89,7 +94,7 @@ const externalProfileStore = new Vuex.Store({
|
||||||
currentUser: {
|
currentUser: {
|
||||||
credentials: ''
|
credentials: ''
|
||||||
},
|
},
|
||||||
usersObject: [extUser],
|
usersObject: { 100: extUser },
|
||||||
users: [extUser]
|
users: [extUser]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,6 +102,7 @@ const externalProfileStore = new Vuex.Store({
|
||||||
|
|
||||||
const localProfileStore = new Vuex.Store({
|
const localProfileStore = new Vuex.Store({
|
||||||
mutations,
|
mutations,
|
||||||
|
actions,
|
||||||
getters: testGetters,
|
getters: testGetters,
|
||||||
state: {
|
state: {
|
||||||
api: {
|
api: {
|
||||||
|
@ -155,7 +161,7 @@ const localProfileStore = new Vuex.Store({
|
||||||
currentUser: {
|
currentUser: {
|
||||||
credentials: ''
|
credentials: ''
|
||||||
},
|
},
|
||||||
usersObject: [localUser],
|
usersObject: { 100: localUser, 'testuser': localUser },
|
||||||
users: [localUser]
|
users: [localUser]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,40 +34,31 @@ describe('The users module', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('getUserByName', () => {
|
describe('findUser', () => {
|
||||||
it('returns user with matching screen_name', () => {
|
it('returns user with matching screen_name', () => {
|
||||||
|
const user = { screen_name: 'Guy', id: '1' }
|
||||||
const state = {
|
const state = {
|
||||||
users: [
|
usersObject: {
|
||||||
{ screen_name: 'Guy', id: '1' }
|
1: user,
|
||||||
]
|
guy: user
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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', () => {
|
|
||||||
const state = {
|
|
||||||
users: [
|
|
||||||
{ screen_name: 'guy', id: '1' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
const name = 'Guy'
|
|
||||||
const expected = { screen_name: 'guy', id: '1' }
|
|
||||||
expect(getters.userByName(state)(name)).to.eql(expected)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('getUserById', () => {
|
|
||||||
it('returns user with matching id', () => {
|
it('returns user with matching id', () => {
|
||||||
|
const user = { screen_name: 'Guy', id: '1' }
|
||||||
const state = {
|
const state = {
|
||||||
users: [
|
usersObject: {
|
||||||
{ screen_name: 'Guy', id: '1' }
|
1: user,
|
||||||
]
|
guy: user
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue