diff --git a/eslint-suppressions.json b/eslint-suppressions.json
index f192be24e6..3e3fd54262 100644
--- a/eslint-suppressions.json
+++ b/eslint-suppressions.json
@@ -24,11 +24,6 @@
"count": 5
}
},
- "src/analytics/metrics/types.ts": {
- "@typescript-eslint/no-explicit-any": {
- "count": 2
- }
- },
"src/components/Button.tsx": {
"@typescript-eslint/no-explicit-any": {
"count": 2
diff --git a/src/analytics/metrics/types.ts b/src/analytics/metrics/types.ts
index 40da5021c5..91bbefd13a 100644
--- a/src/analytics/metrics/types.ts
+++ b/src/analytics/metrics/types.ts
@@ -449,6 +449,7 @@ export type Events = {
| 'ExploreSuggestedAccounts'
| 'OnboardingSuggestedAccounts'
| 'FindContacts'
+ | 'GroupChat'
}
'profile:followers:view': {
contextProfileDid: string
@@ -554,6 +555,7 @@ export type Events = {
| 'ExploreSuggestedAccounts'
| 'OnboardingSuggestedAccounts'
| 'FindContacts'
+ | 'GroupChat'
}
'chat:create': {
logContext:
@@ -975,10 +977,10 @@ export type Events = {
'thread:click:hideReplyForMe': {}
'thread:click:hideReplyForEveryone': {}
'thread:preferences:load': {
- [key: string]: any
+ [key: string]: unknown
}
'thread:preferences:update': {
- [key: string]: any
+ [key: string]: unknown
}
'thread:click:headerMenuOpen': {}
'thread:click:editOwnThreadgate': {}
diff --git a/src/screens/Messages/ConversationSettings/Member.tsx b/src/screens/Messages/ConversationSettings/Member.tsx
index 828bec8eaf..a7703f4dc0 100644
--- a/src/screens/Messages/ConversationSettings/Member.tsx
+++ b/src/screens/Messages/ConversationSettings/Member.tsx
@@ -1,17 +1,21 @@
import {View} from 'react-native'
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 {logger} from '#/logger'
import {useProfileShadow} from '#/state/cache/profile-shadow'
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 {
type ConvoWithDetails,
type GroupConvoMember,
} from '#/components/dms/util'
+import {createStaticClick, SimpleInlineLinkText} from '#/components/Link'
import * as ProfileCard from '#/components/ProfileCard'
+import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {MemberMenu} from './MemberMenu'
import {StatusBadge} from './StatusBadge'
@@ -37,6 +41,30 @@ export function Member({
const {currentAccount} = useSession()
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) {
return
}
@@ -96,6 +124,7 @@ export function Member({
/>
{!isProfileOwner && (
+ {isSelf || isFollowing ? null : (
+
+ Follow
+
+ )}
{statusBadge}