Merge branch 'from/develop/tusooa/user-profile-routes' into 'develop'
Stop generating /:nickname user profile routes See merge request pleroma/pleroma-fe!1589
This commit is contained in:
		
						commit
						88a3cf8705
					
				
					 6 changed files with 94 additions and 23 deletions
				
			
		| 
						 | 
				
			
			@ -61,7 +61,7 @@ export default (store) => {
 | 
			
		|||
      component: RemoteUserResolver,
 | 
			
		||||
      beforeEnter: validateAuthenticatedRoute
 | 
			
		||||
    },
 | 
			
		||||
    { name: 'external-user-profile', path: '/users/:id', component: UserProfile },
 | 
			
		||||
    { name: 'external-user-profile', path: '/users/$:id', component: UserProfile },
 | 
			
		||||
    { name: 'interactions', path: '/users/:username/interactions', component: Interactions, beforeEnter: validateAuthenticatedRoute },
 | 
			
		||||
    { name: 'dms', path: '/users/:username/dms', component: DMs, beforeEnter: validateAuthenticatedRoute },
 | 
			
		||||
    { name: 'registration', path: '/registration', component: Registration },
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +75,8 @@ export default (store) => {
 | 
			
		|||
    { name: 'search', path: '/search', component: Search, props: (route) => ({ query: route.query.query }) },
 | 
			
		||||
    { name: 'who-to-follow', path: '/who-to-follow', component: WhoToFollow, beforeEnter: validateAuthenticatedRoute },
 | 
			
		||||
    { name: 'about', path: '/about', component: About },
 | 
			
		||||
    { name: 'user-profile', path: '/:_(users)?/:name', component: UserProfile },
 | 
			
		||||
    { name: 'user-profile', path: '/users/:name', component: UserProfile },
 | 
			
		||||
    { name: 'legacy-user-profile', path: '/:name', component: UserProfile },
 | 
			
		||||
    { name: 'lists', path: '/lists', component: Lists },
 | 
			
		||||
    { name: 'lists-timeline', path: '/lists/:id', component: ListsTimeline },
 | 
			
		||||
    { name: 'lists-edit', path: '/lists/:id/edit', component: ListsEdit }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ const UserProfile = {
 | 
			
		|||
  },
 | 
			
		||||
  created () {
 | 
			
		||||
    const routeParams = this.$route.params
 | 
			
		||||
    this.load(routeParams.name || routeParams.id)
 | 
			
		||||
    this.load({ name: routeParams.name, id: routeParams.id })
 | 
			
		||||
    this.tab = get(this.$route, 'query.tab', defaultTabKey)
 | 
			
		||||
  },
 | 
			
		||||
  unmounted () {
 | 
			
		||||
| 
						 | 
				
			
			@ -106,12 +106,17 @@ const UserProfile = {
 | 
			
		|||
      this.userId = null
 | 
			
		||||
      this.error = false
 | 
			
		||||
 | 
			
		||||
      const maybeId = userNameOrId.id
 | 
			
		||||
      const maybeName = userNameOrId.name
 | 
			
		||||
 | 
			
		||||
      // Check if user data is already loaded in store
 | 
			
		||||
      const user = this.$store.getters.findUser(userNameOrId)
 | 
			
		||||
      const user = maybeId ? this.$store.getters.findUser(maybeId) : this.$store.getters.findUserByName(maybeName)
 | 
			
		||||
      if (user) {
 | 
			
		||||
        loadById(user.id)
 | 
			
		||||
      } else {
 | 
			
		||||
        this.$store.dispatch('fetchUser', userNameOrId)
 | 
			
		||||
        (maybeId
 | 
			
		||||
          ? this.$store.dispatch('fetchUser', maybeId)
 | 
			
		||||
          : this.$store.dispatch('fetchUserByName', maybeName))
 | 
			
		||||
          .then(({ id }) => loadById(id))
 | 
			
		||||
          .catch((reason) => {
 | 
			
		||||
            const errorMessage = get(reason, 'error.error')
 | 
			
		||||
| 
						 | 
				
			
			@ -150,12 +155,12 @@ const UserProfile = {
 | 
			
		|||
  watch: {
 | 
			
		||||
    '$route.params.id': function (newVal) {
 | 
			
		||||
      if (newVal) {
 | 
			
		||||
        this.switchUser(newVal)
 | 
			
		||||
        this.switchUser({ id: newVal })
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    '$route.params.name': function (newVal) {
 | 
			
		||||
      if (newVal) {
 | 
			
		||||
        this.switchUser(newVal)
 | 
			
		||||
        this.switchUser({ name: newVal })
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    '$route.query': function (newVal) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,9 +16,6 @@ export const mergeOrAdd = (arr, obj, item) => {
 | 
			
		|||
    // This is a new item, prepare it
 | 
			
		||||
    arr.push(item)
 | 
			
		||||
    obj[item.id] = item
 | 
			
		||||
    if (item.screen_name && !item.screen_name.includes('@')) {
 | 
			
		||||
      obj[item.screen_name.toLowerCase()] = item
 | 
			
		||||
    }
 | 
			
		||||
    return { item, new: true }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -162,7 +159,11 @@ export const mutations = {
 | 
			
		|||
      if (user.relationship) {
 | 
			
		||||
        state.relationships[user.relationship.id] = user.relationship
 | 
			
		||||
      }
 | 
			
		||||
      mergeOrAdd(state.users, state.usersObject, user)
 | 
			
		||||
      const res = mergeOrAdd(state.users, state.usersObject, user)
 | 
			
		||||
      const item = res.item
 | 
			
		||||
      if (res.new && item.screen_name && !item.screen_name.includes('@')) {
 | 
			
		||||
        state.usersByNameObject[item.screen_name.toLowerCase()] = item
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  updateUserRelationship (state, relationships) {
 | 
			
		||||
| 
						 | 
				
			
			@ -239,12 +240,10 @@ export const mutations = {
 | 
			
		|||
 | 
			
		||||
export const getters = {
 | 
			
		||||
  findUser: state => query => {
 | 
			
		||||
    const result = state.usersObject[query]
 | 
			
		||||
    // In case it's a screen_name, we can try searching case-insensitive
 | 
			
		||||
    if (!result && typeof query === 'string') {
 | 
			
		||||
      return state.usersObject[query.toLowerCase()]
 | 
			
		||||
    }
 | 
			
		||||
    return result
 | 
			
		||||
    return state.usersObject[query]
 | 
			
		||||
  },
 | 
			
		||||
  findUserByName: state => query => {
 | 
			
		||||
    return state.usersByNameObject[query.toLowerCase()]
 | 
			
		||||
  },
 | 
			
		||||
  findUserByUrl: state => query => {
 | 
			
		||||
    return state.users
 | 
			
		||||
| 
						 | 
				
			
			@ -263,6 +262,7 @@ export const defaultState = {
 | 
			
		|||
  currentUser: false,
 | 
			
		||||
  users: [],
 | 
			
		||||
  usersObject: {},
 | 
			
		||||
  usersByNameObject: {},
 | 
			
		||||
  signUpPending: false,
 | 
			
		||||
  signUpErrors: [],
 | 
			
		||||
  relationships: {}
 | 
			
		||||
| 
						 | 
				
			
			@ -285,6 +285,13 @@ const users = {
 | 
			
		|||
          return user
 | 
			
		||||
        })
 | 
			
		||||
    },
 | 
			
		||||
    fetchUserByName (store, name) {
 | 
			
		||||
      return store.rootState.api.backendInteractor.fetchUserByName({ name })
 | 
			
		||||
        .then((user) => {
 | 
			
		||||
          store.commit('addNewUsers', [user])
 | 
			
		||||
          return user
 | 
			
		||||
        })
 | 
			
		||||
    },
 | 
			
		||||
    fetchUserRelationship (store, id) {
 | 
			
		||||
      if (store.state.currentUser) {
 | 
			
		||||
        store.rootState.api.backendInteractor.fetchUserRelationship({ id })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,6 +50,7 @@ const MASTODON_USER_HOME_TIMELINE_URL = '/api/v1/timelines/home'
 | 
			
		|||
const MASTODON_STATUS_URL = id => `/api/v1/statuses/${id}`
 | 
			
		||||
const MASTODON_STATUS_CONTEXT_URL = id => `/api/v1/statuses/${id}/context`
 | 
			
		||||
const MASTODON_USER_URL = '/api/v1/accounts'
 | 
			
		||||
const MASTODON_USER_LOOKUP_URL = '/api/v1/accounts/lookup'
 | 
			
		||||
const MASTODON_USER_RELATIONSHIPS_URL = '/api/v1/accounts/relationships'
 | 
			
		||||
const MASTODON_USER_TIMELINE_URL = id => `/api/v1/accounts/${id}/statuses`
 | 
			
		||||
const MASTODON_LIST_URL = id => `/api/v1/lists/${id}`
 | 
			
		||||
| 
						 | 
				
			
			@ -318,6 +319,25 @@ const fetchUser = ({ id, credentials }) => {
 | 
			
		|||
    .then((data) => parseUser(data))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const fetchUserByName = ({ name, credentials }) => {
 | 
			
		||||
  return promisedRequest({
 | 
			
		||||
    url: MASTODON_USER_LOOKUP_URL,
 | 
			
		||||
    credentials,
 | 
			
		||||
    params: { acct: name }
 | 
			
		||||
  })
 | 
			
		||||
    .then(data => data.id)
 | 
			
		||||
    .catch(error => {
 | 
			
		||||
      if (error && error.statusCode === 404) {
 | 
			
		||||
        // Either the backend does not support lookup endpoint,
 | 
			
		||||
        // or there is no user with such name. Fallback and treat name as id.
 | 
			
		||||
        return name
 | 
			
		||||
      } else {
 | 
			
		||||
        throw error
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    .then(id => fetchUser({ id, credentials }))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const fetchUserRelationship = ({ id, credentials }) => {
 | 
			
		||||
  const url = `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}`
 | 
			
		||||
  return fetch(url, { headers: authHeaders(credentials) })
 | 
			
		||||
| 
						 | 
				
			
			@ -1481,6 +1501,7 @@ const apiService = {
 | 
			
		|||
  blockUser,
 | 
			
		||||
  unblockUser,
 | 
			
		||||
  fetchUser,
 | 
			
		||||
  fetchUserByName,
 | 
			
		||||
  fetchUserRelationship,
 | 
			
		||||
  favorite,
 | 
			
		||||
  unfavorite,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,7 @@ const actions = {
 | 
			
		|||
 | 
			
		||||
const testGetters = {
 | 
			
		||||
  findUser: state => getters.findUser(state.users),
 | 
			
		||||
  findUserByName: state => getters.findUserByName(state.users),
 | 
			
		||||
  relationship: state => getters.relationship(state.users),
 | 
			
		||||
  mergedConfig: state => ({
 | 
			
		||||
    colors: '',
 | 
			
		||||
| 
						 | 
				
			
			@ -95,6 +96,7 @@ const externalProfileStore = createStore({
 | 
			
		|||
        credentials: ''
 | 
			
		||||
      },
 | 
			
		||||
      usersObject: { 100: extUser },
 | 
			
		||||
      usersByNameObject: {},
 | 
			
		||||
      users: [extUser],
 | 
			
		||||
      relationships: {}
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +165,8 @@ const localProfileStore = createStore({
 | 
			
		|||
      currentUser: {
 | 
			
		||||
        credentials: ''
 | 
			
		||||
      },
 | 
			
		||||
      usersObject: { 100: localUser, testuser: localUser },
 | 
			
		||||
      usersObject: { 100: localUser },
 | 
			
		||||
      usersByNameObject: { testuser: localUser },
 | 
			
		||||
      users: [localUser],
 | 
			
		||||
      relationships: {}
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,24 +57,27 @@ describe('The users module', () => {
 | 
			
		|||
  })
 | 
			
		||||
 | 
			
		||||
  describe('findUser', () => {
 | 
			
		||||
    it('returns user with matching screen_name', () => {
 | 
			
		||||
    it('does not return user with matching screen_name', () => {
 | 
			
		||||
      const user = { screen_name: 'Guy', id: '1' }
 | 
			
		||||
      const state = {
 | 
			
		||||
        usersObject: {
 | 
			
		||||
          1: user,
 | 
			
		||||
          1: user
 | 
			
		||||
        },
 | 
			
		||||
        usersByNameObject: {
 | 
			
		||||
          guy: user
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      const name = 'Guy'
 | 
			
		||||
      const expected = { screen_name: 'Guy', id: '1' }
 | 
			
		||||
      expect(getters.findUser(state)(name)).to.eql(expected)
 | 
			
		||||
      expect(getters.findUser(state)(name)).to.eql(undefined)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('returns user with matching id', () => {
 | 
			
		||||
      const user = { screen_name: 'Guy', id: '1' }
 | 
			
		||||
      const state = {
 | 
			
		||||
        usersObject: {
 | 
			
		||||
          1: user,
 | 
			
		||||
          1: user
 | 
			
		||||
        },
 | 
			
		||||
        usersByNameObject: {
 | 
			
		||||
          guy: user
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -83,4 +86,35 @@ describe('The users module', () => {
 | 
			
		|||
      expect(getters.findUser(state)(id)).to.eql(expected)
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  describe('findUserByName', () => {
 | 
			
		||||
    it('returns user with matching screen_name', () => {
 | 
			
		||||
      const user = { screen_name: 'Guy', id: '1' }
 | 
			
		||||
      const state = {
 | 
			
		||||
        usersObject: {
 | 
			
		||||
          1: user
 | 
			
		||||
        },
 | 
			
		||||
        usersByNameObject: {
 | 
			
		||||
          guy: user
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      const name = 'Guy'
 | 
			
		||||
      const expected = { screen_name: 'Guy', id: '1' }
 | 
			
		||||
      expect(getters.findUserByName(state)(name)).to.eql(expected)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('does not return user with matching id', () => {
 | 
			
		||||
      const user = { screen_name: 'Guy', id: '1' }
 | 
			
		||||
      const state = {
 | 
			
		||||
        usersObject: {
 | 
			
		||||
          1: user
 | 
			
		||||
        },
 | 
			
		||||
        usersByNameObject: {
 | 
			
		||||
          guy: user
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      const id = '1'
 | 
			
		||||
      expect(getters.findUserByName(state)(id)).to.eql(undefined)
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue