diff --git a/api/resolvers/user.js b/api/resolvers/user.js
index 25e6a11365..8d72d47034 100644
--- a/api/resolvers/user.js
+++ b/api/resolvers/user.js
@@ -136,6 +136,28 @@ export default {
if (id) id = Number(id)
return await models.user.findUnique({ where: { id, name } })
},
+ userByMention: async (parent, { name, itemId }, { models }) => {
+ let user = null
+ if (itemId) {
+ const mentions = await models.mention.findMany({
+ where: {
+ itemId: Number(itemId)
+ },
+ include: {
+ user: true,
+ item: true
+ }
+ })
+ const matchingMention = mentions.find(mention => mention.user?.name === name)
+ if (matchingMention) {
+ user = matchingMention.user
+ }
+ }
+ if (!user) {
+ user = await models.user.findUnique({ where: { name } })
+ }
+ return user
+ },
users: async (parent, args, { models }) =>
await models.user.findMany(),
nameAvailable: async (parent, { name }, { models, me }) => {
diff --git a/api/typeDefs/user.js b/api/typeDefs/user.js
index c41bb2676f..05ebd8a036 100644
--- a/api/typeDefs/user.js
+++ b/api/typeDefs/user.js
@@ -6,6 +6,7 @@ export default gql`
me: User
settings: User
user(id: ID, name: String): User
+ userByMention(name: String!, itemId: ID): User
users: [User!]
nameAvailable(name: String!): Boolean!
topUsers(cursor: String, when: String, from: String, to: String, by: String, limit: Limit! = ${LIMIT}): UsersNullable!
diff --git a/components/text.js b/components/text.js
index d2ac1ab5d7..f464c85bc1 100644
--- a/components/text.js
+++ b/components/text.js
@@ -130,7 +130,7 @@ export default memo(function Text ({ rel = UNKNOWN_LINK_REL, imgproxyUrls, child
table: Table,
p: P,
code: Code,
- mention: Mention,
+ mention: (props) => ,
sub: Sub,
item: Item,
footnote: Footnote,
@@ -147,7 +147,7 @@ export default memo(function Text ({ rel = UNKNOWN_LINK_REL, imgproxyUrls, child
},
img: TextMediaOrLink,
embed: (props) =>
- }), [outlawed, rel, TextMediaOrLink, topLevel])
+ }), [outlawed, rel, TextMediaOrLink, topLevel, itemId])
const carousel = useCarousel()
@@ -192,15 +192,17 @@ export default memo(function Text ({ rel = UNKNOWN_LINK_REL, imgproxyUrls, child
)
}, isEqual)
-function Mention ({ children, node, href, name, id }) {
+function Mention ({ children, node, href, name, id, itemId }) {
return (
-
-
- {children}
-
+
+ {({ user }) => (
+
+ {children}
+
+ )}
)
}
diff --git a/components/user-popover.js b/components/user-popover.js
index 11d7d65bf7..3ed29acc4f 100644
--- a/components/user-popover.js
+++ b/components/user-popover.js
@@ -1,6 +1,6 @@
-import { USER } from '@/fragments/users'
+import { USER, USER_BY_MENTION } from '@/fragments/users'
import errorStyles from '@/styles/error.module.css'
-import { useLazyQuery } from '@apollo/client'
+import { useLazyQuery, useQuery } from '@apollo/client'
import classNames from 'classnames'
import Link from 'next/link'
import HoverablePopover from './hoverable-popover'
@@ -22,7 +22,16 @@ function StackingSince ({ since }) {
)
}
-export default function UserPopover ({ name, children }) {
+export default function UserPopover ({ name, itemId, children }) {
+ const { data: mentionData, loading: mentionLoading } = useQuery(
+ USER_BY_MENTION,
+ {
+ variables: { name, itemId },
+ skip: !itemId,
+ fetchPolicy: 'cache-first'
+ }
+ )
+
const [getUser, { loading, data }] = useLazyQuery(
USER,
{
@@ -31,17 +40,25 @@ export default function UserPopover ({ name, children }) {
}
)
+ const resolvedUser = mentionData?.userByMention
+ const popoverUser = resolvedUser || data?.user
+ const isLoading = loading || (itemId && mentionLoading && !resolvedUser)
+ const trigger =
+ typeof children === 'function'
+ ? children({ user: popoverUser })
+ : children
+
return (
- : !data.user
+ : !popoverUser
? USER NOT FOUND
: (
-
-
+
+
)}
/>
diff --git a/fragments/users.js b/fragments/users.js
index a1fa8cf71a..8e4b02e4d6 100644
--- a/fragments/users.js
+++ b/fragments/users.js
@@ -294,6 +294,14 @@ export const USER = gql`
}
}`
+export const USER_BY_MENTION = gql`
+ ${USER_FIELDS}
+ query UserByMention($name: String!, $itemId: ID) {
+ userByMention(name: $name, itemId: $itemId) {
+ ...UserFields
+ }
+ }`
+
export const USER_WITH_ITEMS = gql`
${USER_FIELDS}
${ITEM_FIELDS}