better fetchUserIfMissing

This commit is contained in:
Henry Jameson 2026-08-10 16:22:33 +03:00
commit 92ef3b1cd1
5 changed files with 96 additions and 37 deletions

View file

@ -47,8 +47,8 @@ const ListsNew = {
.fetchListAccounts({ listId: this.id })
.then(() => {
this.membersUserIds = this.findListAccounts(this.id)
this.membersUserIds.forEach((userId) => {
useUsersStore().fetchUserIfMissing(userId)
this.membersUserIds.forEach((id) => {
useUsersStore().fetchUserIfMissing({ id })
})
})
},

View file

@ -9,8 +9,8 @@ import { useUsersStore } from 'src/stores/users.js'
const StaffPanel = {
created() {
const nicknames = useInstanceStore().staffAccounts
nicknames.forEach((nickname) =>
useUsersStore().fetchUserIfMissing(nickname),
nicknames.forEach((name) =>
useUsersStore().fetchUserIfMissing({ name }),
)
},
components: {

View file

@ -155,7 +155,7 @@ const StatusBody = {
mounted() {
this.status.attentions?.forEach((attn) => {
const { id } = attn
useUsersStore().fetchUserIfMissing(id)
useUsersStore().fetchUserIfMissing({ id })
})
},
methods: {
@ -172,7 +172,7 @@ const StatusBody = {
if (!cleanedString.startsWith('@')) return
const handle = cleanedString.slice(1)
const host = url.replace(/^https?:\/\//, '').replace(/\/.+?$/, '')
useUsersStore().fetchUserIfMissing(`${handle}@${host}`)
useUsersStore().fetchUserIfMissing({ name: `${handle}@${host}` })
})
/* This is a bit of a hack to make current tall status detector work
* with rich mentions. Invisible mentions are detected at RichContent level

View file

@ -20,7 +20,7 @@ const UserProfileAdminView = {
}
},
created() {
useUsersStore().fetchUserIfMissing(this.userId)
useUsersStore().fetchUserIfMissing({ id: this.userId })
useInterfaceStore().setForeignProfileBackground(this.user?.background_image)
},
updated() {

View file

@ -69,6 +69,8 @@ export const useUsersStore = defineStore('users', {
usersByURL: new Map(),
relationships: new Map(),
timestamps: new WeakMap(),
fetchesIds: new Map(),
fetchesNames: new Map(),
}),
getters: {
loggedIn: (state) => !!state.currentUser,
@ -102,7 +104,7 @@ export const useUsersStore = defineStore('users', {
user.rights = newRights
},
async updateUserAdminData({ user }) {
const localUser = await this.fetchUserIfMissing(user.id)
const localUser = await this.fetchUserIfMissing({ id: user.id })
localUser.adminData = user
localUser.deactivated = !user.is_active
@ -227,39 +229,98 @@ export const useUsersStore = defineStore('users', {
}
notification.from_profile = this.users.get(notification.from_profile.id)
},
async fetchUserIfMissing(id) {
const user = this.findUser(id)
async fetchUserIfMissing({ id, name }) {
let findFunc
let fetchFunc
let map
let otherMap
let identifier
if (id) {
findFunc = this.findUser
fetchFunc = this.fetchUser
map = this.fetchesIds
identifier = id
} else if (name) {
findFunc = this.findUserByName
fetchFunc = this.fetchUserByName
map = this.fetchesNames
identifier = name
} else {
throw new TypeError('No identifier provided')
}
const user = findFunc(identifier)
if (!user) {
return this.fetchUser(id)
let promise
if (map.has(identifier)) {
promise = map.get(identifier)
} else {
promise = fetchFunc(identifier)
}
map.set(identifier, promise)
const result = await promise
if (result?.data) {
const { id, screen_name } = result.data
this.fetchesIds.set(id, promise)
this.fetchesNames.set(screen_name, promise)
this.addNewUsers(result)
return this.users.get(id)
} else {
return null
}
} else {
return user
}
},
fetchUser(id) {
return fetchUser({
id,
credentials: useOAuthStore().token,
})
.then(({ data: user }) => {
this.addNewUsers([user])
return user
})
.catch((error) => {
if (error.statusCode === 404) {
console.warn(`User ${id} not found`)
} else {
throw error
}
async fetchUser(id) {
try {
const result = await fetchUser({
id,
credentials: useOAuthStore().token,
})
this.addNewUsers(result)
return this.users.get(result.data.id)
} catch(error) {
if (
error.name === 'StatusCodeError' &&
error.statusCode === 404
) {
console.warn(`User ${id} not found`)
return null
} else {
throw error
}
}
},
fetchUserByName(name) {
return fetchUserByName({
name,
credentials: useOAuthStore().token,
}).then(({ data: user }) => {
this.addNewUsers([user])
return user
})
async fetchUserByName(name) {
try {
const result = fetchUserByName({
name,
credentials: useOAuthStore().token,
})
this.addNewUsers(result)
return this.users.get(result.data.id)
} catch(error) {
if (
error.name === 'StatusCodeError' &&
error.statusCode === 404
) {
console.warn(`User ${id} not found`)
return null
} else {
throw error
}
}
},
fetchUserRelationship(id) {
if (this.currentUser) {
@ -682,8 +743,6 @@ export const useUsersStore = defineStore('users', {
},
},
persist: {
afterLoad({ lastLoginName }) {
return { lastLoginName }
},
paths: ['lastLoginName'],
},
})