diff --git a/src/state/models/members-view.ts b/src/state/models/members-view.ts
index 370b6b431e..19101afcae 100644
--- a/src/state/models/members-view.ts
+++ b/src/state/models/members-view.ts
@@ -1,5 +1,7 @@
-import {makeAutoObservable} from 'mobx'
+import {makeAutoObservable, runInAction} from 'mobx'
import * as GetMembers from '../../third-party/api/src/client/types/app/bsky/graph/getMembers'
+import {APP_BSKY_GRAPH} from '../../third-party/api'
+import {AtUri} from '../../third-party/uri'
import {RootStoreModel} from './root-store'
type Subject = GetMembers.OutputSchema['subject']
@@ -16,7 +18,12 @@ export class MembersViewModel {
params: GetMembers.QueryParams
// data
- subject: Subject = {did: '', handle: '', displayName: ''}
+ subject: Subject = {
+ did: '',
+ handle: '',
+ displayName: '',
+ declaration: {cid: '', actorType: ''},
+ }
members: MemberItem[] = []
constructor(
@@ -65,6 +72,26 @@ export class MembersViewModel {
// TODO
}
+ async removeMember(did: string) {
+ const assertsRes = await this.rootStore.api.app.bsky.graph.getAssertions({
+ author: this.subject.did,
+ subject: did,
+ assertion: APP_BSKY_GRAPH.AssertMember,
+ })
+ if (assertsRes.data.assertions.length < 1) {
+ throw new Error('Could not find membership record')
+ }
+ for (const assert of assertsRes.data.assertions) {
+ await this.rootStore.api.app.bsky.graph.assertion.delete({
+ did: this.subject.did,
+ rkey: new AtUri(assert.uri).rkey,
+ })
+ }
+ runInAction(() => {
+ this.members = this.members.filter(m => m.did !== did)
+ })
+ }
+
// state transitions
// =
@@ -101,6 +128,7 @@ export class MembersViewModel {
this.subject.did = res.data.subject.did
this.subject.handle = res.data.subject.handle
this.subject.displayName = res.data.subject.displayName
+ this.subject.declaration = res.data.subject.declaration
this.members.length = 0
let counter = 0
for (const item of res.data.members) {
diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx
index 7fb3a5fb73..5dbe290606 100644
--- a/src/view/screens/Profile.tsx
+++ b/src/view/screens/Profile.tsx
@@ -1,15 +1,19 @@
import React, {useEffect, useState, useMemo} from 'react'
import {StyleSheet, Text, View} from 'react-native'
import {observer} from 'mobx-react-lite'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {ViewSelector} from '../com/util/ViewSelector'
import {ScreenParams} from '../routes'
import {ProfileUiModel, Sections} from '../../state/models/profile-ui'
+import {MembershipItem} from '../../state/models/memberships-view'
import {useStores} from '../../state'
+import {ConfirmModel} from '../../state/models/shell-ui'
import {ProfileHeader} from '../com/profile/ProfileHeader'
import {FeedItem} from '../com/posts/FeedItem'
import {ProfileCard} from '../com/profile/ProfileCard'
import {ErrorScreen} from '../com/util/ErrorScreen'
import {ErrorMessage} from '../com/util/ErrorMessage'
+import Toast from '../com/util/Toast'
import {s, colors} from '../lib/styles'
import {UserGroupIcon} from '../lib/icons'
@@ -65,10 +69,28 @@ export const Profile = observer(({visible, params}: ScreenParams) => {
const onPressTryAgain = () => {
uiState.setup()
}
+ const onPressRemoveMember = (membership: MembershipItem) => {
+ store.shell.openModal(
+ new ConfirmModel(
+ `Remove ${membership.displayName || membership.handle}?`,
+ `You'll be able to invite them again if you change your mind.`,
+ async () => {
+ await uiState.members.removeMember(membership.did)
+ Toast.show(`User removed`, {
+ duration: Toast.durations.LONG,
+ position: Toast.positions.TOP,
+ })
+ },
+ ),
+ )
+ }
// rendering
// =
+ const isSceneCreator =
+ uiState.isScene && store.me.did === uiState.profile.creator
+
const renderHeader = () => {
if (!uiState) {
return
@@ -155,11 +177,26 @@ export const Profile = observer(({visible, params}: ScreenParams) => {
if (uiState.members.hasContent) {
items = uiState.members.members.slice()
renderItem = (item: any) => {
+ const shouldAdmin = isSceneCreator && item.did !== store.me.did
+ const renderButton = shouldAdmin
+ ? () => (
+ <>
+
+ Remove
+ >
+ )
+ : undefined
return (
onPressRemoveMember(item)}
/>
)
}
diff --git a/todos.txt b/todos.txt
index 9f40fac75c..11e5e7b922 100644
--- a/todos.txt
+++ b/todos.txt
@@ -18,9 +18,10 @@ Paul's todo list
- User search
- Use pagination to make sure there are suggestions
- User profile
+ - User
+ - Invite to scene
- Scene
> Edit profile
- > Remove member
- Reply gating
- Composer
- View on post