Skip to content

Commit 4639417

Browse files
committed
fix(Mention): Maintain mention after nym change
1 parent 288892e commit 4639417

File tree

5 files changed

+68
-18
lines changed

5 files changed

+68
-18
lines changed

api/resolvers/user.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,29 @@ export default {
136136
if (id) id = Number(id)
137137
return await models.user.findUnique({ where: { id, name } })
138138
},
139+
userByMention: async (parent, { name, itemId }, { models }) => {
140+
let user = await models.user.findUnique({ where: { name } })
141+
if (!user && itemId) {
142+
const mentions = await models.mention.findMany({
143+
where: {
144+
itemId: Number(itemId)
145+
},
146+
include: {
147+
user: true,
148+
item: true
149+
}
150+
})
151+
const matchingMention = mentions.find(mention => {
152+
const text = mention.item?.text || ''
153+
const mentionRegex = new RegExp(`\\B@${name}(?![\\w_])`, 'gi')
154+
return mentionRegex.test(text)
155+
})
156+
if (matchingMention) {
157+
user = matchingMention.user
158+
}
159+
}
160+
return user
161+
},
139162
users: async (parent, args, { models }) =>
140163
await models.user.findMany(),
141164
nameAvailable: async (parent, { name }, { models, me }) => {

api/typeDefs/user.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export default gql`
66
me: User
77
settings: User
88
user(id: ID, name: String): User
9+
userByMention(name: String!, itemId: ID): User
910
users: [User!]
1011
nameAvailable(name: String!): Boolean!
1112
topUsers(cursor: String, when: String, from: String, to: String, by: String, limit: Limit! = ${LIMIT}): UsersNullable!

components/text.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export default memo(function Text ({ rel = UNKNOWN_LINK_REL, imgproxyUrls, child
130130
table: Table,
131131
p: P,
132132
code: Code,
133-
mention: Mention,
133+
mention: (props) => <Mention {...props} itemId={itemId} />,
134134
sub: Sub,
135135
item: Item,
136136
footnote: Footnote,
@@ -147,7 +147,7 @@ export default memo(function Text ({ rel = UNKNOWN_LINK_REL, imgproxyUrls, child
147147
},
148148
img: TextMediaOrLink,
149149
embed: (props) => <Embed {...props} topLevel={topLevel} />
150-
}), [outlawed, rel, TextMediaOrLink, topLevel])
150+
}), [outlawed, rel, TextMediaOrLink, topLevel, itemId])
151151

152152
const carousel = useCarousel()
153153

@@ -192,15 +192,17 @@ export default memo(function Text ({ rel = UNKNOWN_LINK_REL, imgproxyUrls, child
192192
)
193193
}, isEqual)
194194

195-
function Mention ({ children, node, href, name, id }) {
195+
function Mention ({ children, node, href, name, id, itemId }) {
196196
return (
197-
<UserPopover name={name}>
198-
<Link
199-
id={id}
200-
href={href}
201-
>
202-
{children}
203-
</Link>
197+
<UserPopover name={name} itemId={itemId}>
198+
{({ user }) => (
199+
<Link
200+
id={id}
201+
href={user ? `/${user.name}` : href}
202+
>
203+
{children}
204+
</Link>
205+
)}
204206
</UserPopover>
205207
)
206208
}

components/user-popover.js

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { USER } from '@/fragments/users'
1+
import { USER, USER_BY_MENTION } from '@/fragments/users'
22
import errorStyles from '@/styles/error.module.css'
3-
import { useLazyQuery } from '@apollo/client'
3+
import { useLazyQuery, useQuery } from '@apollo/client'
44
import classNames from 'classnames'
55
import Link from 'next/link'
66
import HoverablePopover from './hoverable-popover'
@@ -22,7 +22,16 @@ function StackingSince ({ since }) {
2222
)
2323
}
2424

25-
export default function UserPopover ({ name, children }) {
25+
export default function UserPopover ({ name, itemId, children }) {
26+
const { data: mentionData } = useQuery(
27+
USER_BY_MENTION,
28+
{
29+
variables: { name, itemId },
30+
skip: !itemId,
31+
fetchPolicy: 'cache-first'
32+
}
33+
)
34+
2635
const [getUser, { loading, data }] = useLazyQuery(
2736
USER,
2837
{
@@ -31,17 +40,24 @@ export default function UserPopover ({ name, children }) {
3140
}
3241
)
3342

43+
const resolvedUser = mentionData?.userByMention
44+
const popoverUser = data?.user || resolvedUser
45+
const trigger =
46+
typeof children === 'function'
47+
? children({ user: resolvedUser })
48+
: children
49+
3450
return (
3551
<HoverablePopover
3652
onShow={getUser}
37-
trigger={children}
38-
body={!data || loading
53+
trigger={trigger}
54+
body={!data && loading
3955
? <UserSkeleton />
40-
: !data.user
56+
: !popoverUser
4157
? <h1 className={classNames(errorStyles.status, errorStyles.describe)}>USER NOT FOUND</h1>
4258
: (
43-
<UserBase user={data.user} className='mb-0 pb-0'>
44-
<StackingSince since={data.user.since} />
59+
<UserBase user={popoverUser} className='mb-0 pb-0'>
60+
<StackingSince since={popoverUser.since} />
4561
</UserBase>
4662
)}
4763
/>

fragments/users.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,14 @@ export const USER = gql`
294294
}
295295
}`
296296

297+
export const USER_BY_MENTION = gql`
298+
${USER_FIELDS}
299+
query UserByMention($name: String!, $itemId: ID) {
300+
userByMention(name: $name, itemId: $itemId) {
301+
...UserFields
302+
}
303+
}`
304+
297305
export const USER_WITH_ITEMS = gql`
298306
${USER_FIELDS}
299307
${ITEM_FIELDS}

0 commit comments

Comments
 (0)