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}