Add ability to follow from chat settings (#10415)
This commit is contained in:
@@ -24,11 +24,6 @@
|
|||||||
"count": 5
|
"count": 5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"src/analytics/metrics/types.ts": {
|
|
||||||
"@typescript-eslint/no-explicit-any": {
|
|
||||||
"count": 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"src/components/Button.tsx": {
|
"src/components/Button.tsx": {
|
||||||
"@typescript-eslint/no-explicit-any": {
|
"@typescript-eslint/no-explicit-any": {
|
||||||
"count": 2
|
"count": 2
|
||||||
|
|||||||
@@ -449,6 +449,7 @@ export type Events = {
|
|||||||
| 'ExploreSuggestedAccounts'
|
| 'ExploreSuggestedAccounts'
|
||||||
| 'OnboardingSuggestedAccounts'
|
| 'OnboardingSuggestedAccounts'
|
||||||
| 'FindContacts'
|
| 'FindContacts'
|
||||||
|
| 'GroupChat'
|
||||||
}
|
}
|
||||||
'profile:followers:view': {
|
'profile:followers:view': {
|
||||||
contextProfileDid: string
|
contextProfileDid: string
|
||||||
@@ -554,6 +555,7 @@ export type Events = {
|
|||||||
| 'ExploreSuggestedAccounts'
|
| 'ExploreSuggestedAccounts'
|
||||||
| 'OnboardingSuggestedAccounts'
|
| 'OnboardingSuggestedAccounts'
|
||||||
| 'FindContacts'
|
| 'FindContacts'
|
||||||
|
| 'GroupChat'
|
||||||
}
|
}
|
||||||
'chat:create': {
|
'chat:create': {
|
||||||
logContext:
|
logContext:
|
||||||
@@ -975,10 +977,10 @@ export type Events = {
|
|||||||
'thread:click:hideReplyForMe': {}
|
'thread:click:hideReplyForMe': {}
|
||||||
'thread:click:hideReplyForEveryone': {}
|
'thread:click:hideReplyForEveryone': {}
|
||||||
'thread:preferences:load': {
|
'thread:preferences:load': {
|
||||||
[key: string]: any
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
'thread:preferences:update': {
|
'thread:preferences:update': {
|
||||||
[key: string]: any
|
[key: string]: unknown
|
||||||
}
|
}
|
||||||
'thread:click:headerMenuOpen': {}
|
'thread:click:headerMenuOpen': {}
|
||||||
'thread:click:editOwnThreadgate': {}
|
'thread:click:editOwnThreadgate': {}
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {moderateProfile} from '@atproto/api'
|
import {moderateProfile} from '@atproto/api'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
|
import {logger} from '#/logger'
|
||||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {useSession} from '#/state/session'
|
import {useProfileFollowMutationQueue} from '#/state/queries/profile'
|
||||||
|
import {useRequireAuth, useSession} from '#/state/session'
|
||||||
import {atoms as a, native, useTheme, web} from '#/alf'
|
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||||
import {
|
import {
|
||||||
type ConvoWithDetails,
|
type ConvoWithDetails,
|
||||||
type GroupConvoMember,
|
type GroupConvoMember,
|
||||||
} from '#/components/dms/util'
|
} from '#/components/dms/util'
|
||||||
|
import {createStaticClick, SimpleInlineLinkText} from '#/components/Link'
|
||||||
import * as ProfileCard from '#/components/ProfileCard'
|
import * as ProfileCard from '#/components/ProfileCard'
|
||||||
|
import * as Toast from '#/components/Toast'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {MemberMenu} from './MemberMenu'
|
import {MemberMenu} from './MemberMenu'
|
||||||
import {StatusBadge} from './StatusBadge'
|
import {StatusBadge} from './StatusBadge'
|
||||||
@@ -37,6 +41,30 @@ export function Member({
|
|||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
|
|
||||||
|
const [queueFollow] = useProfileFollowMutationQueue(profile, 'GroupChat')
|
||||||
|
const requireAuth = useRequireAuth()
|
||||||
|
|
||||||
|
const isFollowing = !!profile.viewer?.following
|
||||||
|
|
||||||
|
const handleFollow = () => {
|
||||||
|
requireAuth(async () => {
|
||||||
|
try {
|
||||||
|
await queueFollow()
|
||||||
|
Toast.show(l`Following ${displayName}`, {
|
||||||
|
type: 'info',
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
const e = err as Error
|
||||||
|
if (e?.name !== 'AbortError') {
|
||||||
|
logger.error('Failed to follow', {message: String(e)})
|
||||||
|
Toast.show(l`There was an issue! ${e.toString()}`, {
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (!moderationOpts) {
|
if (!moderationOpts) {
|
||||||
return <MemberPlaceholder />
|
return <MemberPlaceholder />
|
||||||
}
|
}
|
||||||
@@ -96,6 +124,7 @@ export function Member({
|
|||||||
/>
|
/>
|
||||||
{!isProfileOwner && (
|
{!isProfileOwner && (
|
||||||
<Text
|
<Text
|
||||||
|
numberOfLines={1}
|
||||||
style={[
|
style={[
|
||||||
a.text_xs,
|
a.text_xs,
|
||||||
a.leading_snug,
|
a.leading_snug,
|
||||||
@@ -109,6 +138,14 @@ export function Member({
|
|||||||
</ProfileCard.Header>
|
</ProfileCard.Header>
|
||||||
</ProfileCard.Outer>
|
</ProfileCard.Outer>
|
||||||
</ProfileCard.Link>
|
</ProfileCard.Link>
|
||||||
|
{isSelf || isFollowing ? null : (
|
||||||
|
<SimpleInlineLinkText
|
||||||
|
label={l`Follow ${displayName}`}
|
||||||
|
{...createStaticClick(handleFollow)}
|
||||||
|
style={[a.font_medium]}>
|
||||||
|
<Trans>Follow</Trans>
|
||||||
|
</SimpleInlineLinkText>
|
||||||
|
)}
|
||||||
{statusBadge}
|
{statusBadge}
|
||||||
</View>
|
</View>
|
||||||
</SubtleHoverWrapper>
|
</SubtleHoverWrapper>
|
||||||
|
|||||||
Reference in New Issue
Block a user