diff --git a/__tests__/view/shell/mobile/Menu.test.tsx b/__tests__/view/shell/mobile/Menu.test.tsx
index 5eee3f12..caec5f29 100644
--- a/__tests__/view/shell/mobile/Menu.test.tsx
+++ b/__tests__/view/shell/mobile/Menu.test.tsx
@@ -57,14 +57,4 @@ describe('Menu', () => {
expect(onCloseMock).toHaveBeenCalled()
expect(mockedNavigationStore.switchTo).toHaveBeenCalledWith(1, true)
})
-
- it('presses new scene button', () => {
- const {getAllByTestId} = render(
)
-
- const menuItemButton = getAllByTestId('menuItemButton')
- fireEvent.press(menuItemButton[3])
-
- expect(onCloseMock).toHaveBeenCalled()
- expect(mockedShellStore.openModal).toHaveBeenCalled()
- })
})
diff --git a/public/img/scene-explainer.jpg b/public/img/scene-explainer.jpg
deleted file mode 100644
index 2478b055..00000000
Binary files a/public/img/scene-explainer.jpg and /dev/null differ
diff --git a/src/state/lib/api.ts b/src/state/lib/api.ts
index e701ae6f..8dc9ce5f 100644
--- a/src/state/lib/api.ts
+++ b/src/state/lib/api.ts
@@ -216,54 +216,6 @@ export async function unfollow(store: RootStoreModel, followUri: string) {
})
}
-export async function inviteToScene(
- store: RootStoreModel,
- sceneDid: string,
- subjectDid: string,
- subjectDeclarationCid: string,
-): Promise {
- const res = await store.api.app.bsky.graph.assertion.create(
- {
- did: sceneDid,
- },
- {
- subject: {
- did: subjectDid,
- declarationCid: subjectDeclarationCid,
- },
- assertion: APP_BSKY_GRAPH.AssertMember,
- createdAt: new Date().toISOString(),
- },
- )
- return res.uri
-}
-
-interface Confirmation {
- originator: {
- did: string
- declarationCid: string
- }
- assertion: {
- uri: string
- cid: string
- }
-}
-export async function acceptSceneInvite(
- store: RootStoreModel,
- details: Confirmation,
-): Promise {
- const res = await store.api.app.bsky.graph.confirmation.create(
- {
- did: store.me.did || '',
- },
- {
- ...details,
- createdAt: new Date().toISOString(),
- },
- )
- return res.uri
-}
-
interface FetchHandlerResponse {
status: number
headers: Record
diff --git a/src/state/models/feed-view.ts b/src/state/models/feed-view.ts
index 5f2b9721..c39daf87 100644
--- a/src/state/models/feed-view.ts
+++ b/src/state/models/feed-view.ts
@@ -6,7 +6,6 @@ import {
AppBskyFeedGetAuthorFeed as GetAuthorFeed,
} from '@atproto/api'
type FeedViewPost = AppBskyFeedFeedViewPost.Main
-type ReasonTrend = AppBskyFeedFeedViewPost.ReasonTrend
type ReasonRepost = AppBskyFeedFeedViewPost.ReasonRepost
type PostView = AppBskyFeedPost.View
import {AtUri} from '../../third-party/uri'
@@ -94,12 +93,6 @@ export class FeedItemModel {
}
}
- get reasonTrend(): ReasonTrend | undefined {
- if (this.reason?.$type === 'app.bsky.feed.feedViewPost#reasonTrend') {
- return this.reason as ReasonTrend
- }
- }
-
async toggleUpvote() {
const wasUpvoted = !!this.post.viewer.upvote
const wasDownvoted = !!this.post.viewer.downvote
@@ -494,10 +487,9 @@ export class FeedModel {
private _updateAll(res: GetTimeline.Response | GetAuthorFeed.Response) {
for (const item of res.data.feed) {
const existingItem = this.feed.find(
- // HACK: need to find the reposts and trends item, so we have to check for that -prf
+ // HACK: need to find the reposts' item, so we have to check for that -prf
item2 =>
item.post.uri === item2.post.uri &&
- item.reason?.$trend === item2.reason?.$trend &&
// @ts-ignore todo
item.reason?.by?.did === item2.reason?.by?.did,
)
diff --git a/src/state/models/me.ts b/src/state/models/me.ts
index 0ae52db8..201ce04c 100644
--- a/src/state/models/me.ts
+++ b/src/state/models/me.ts
@@ -1,7 +1,6 @@
import {makeAutoObservable, runInAction} from 'mobx'
import {RootStoreModel} from './root-store'
import {FeedModel} from './feed-view'
-import {MembershipsViewModel} from './memberships-view'
import {NotificationsViewModel} from './notifications-view'
import {isObj, hasProp} from '../lib/type-guards'
@@ -12,7 +11,6 @@ export class MeModel {
description: string = ''
avatar: string = ''
notificationCount: number = 0
- memberships?: MembershipsViewModel
mainFeed: FeedModel
notifications: NotificationsViewModel
@@ -35,7 +33,6 @@ export class MeModel {
this.description = ''
this.avatar = ''
this.notificationCount = 0
- this.memberships = undefined
}
serialize(): unknown {
@@ -99,13 +96,7 @@ export class MeModel {
algorithm: 'reverse-chronological',
})
this.notifications = new NotificationsViewModel(this.rootStore, {})
- this.memberships = new MembershipsViewModel(this.rootStore, {
- actor: this.did,
- })
await Promise.all([
- this.memberships?.setup().catch(e => {
- this.rootStore.log.error('Failed to setup memberships model', e)
- }),
this.mainFeed.setup().catch(e => {
this.rootStore.log.error('Failed to setup main feed model', e)
}),
@@ -133,8 +124,4 @@ export class MeModel {
}
})
}
-
- async refreshMemberships() {
- return this.memberships?.refresh()
- }
}
diff --git a/src/state/models/members-view.ts b/src/state/models/members-view.ts
deleted file mode 100644
index 73295f47..00000000
--- a/src/state/models/members-view.ts
+++ /dev/null
@@ -1,149 +0,0 @@
-import {makeAutoObservable, runInAction} from 'mobx'
-import {
- AppBskyGraphGetMembers as GetMembers,
- AppBskyActorRef as ActorRef,
- APP_BSKY_GRAPH,
-} from '@atproto/api'
-import {AtUri} from '../../third-party/uri'
-import {RootStoreModel} from './root-store'
-
-export type MemberItem = GetMembers.Member & {
- _reactKey: string
-}
-
-export class MembersViewModel {
- // state
- isLoading = false
- isRefreshing = false
- hasLoaded = false
- error = ''
- params: GetMembers.QueryParams
-
- // data
- subject: ActorRef.WithInfo = {
- did: '',
- handle: '',
- displayName: '',
- declaration: {cid: '', actorType: ''},
- avatar: undefined,
- }
- members: MemberItem[] = []
-
- constructor(
- public rootStore: RootStoreModel,
- params: GetMembers.QueryParams,
- ) {
- makeAutoObservable(
- this,
- {
- rootStore: false,
- params: false,
- },
- {autoBind: true},
- )
- this.params = params
- }
-
- get hasContent() {
- return this.members.length !== 0
- }
-
- get hasError() {
- return this.error !== ''
- }
-
- get isEmpty() {
- return this.hasLoaded && !this.hasContent
- }
-
- isMember(did: string) {
- return this.members.find(member => member.did === did)
- }
-
- // public api
- // =
-
- async setup() {
- await this._fetch()
- }
-
- async refresh() {
- await this._fetch(true)
- }
-
- async loadMore() {
- // 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
- // =
-
- private _xLoading(isRefreshing = false) {
- this.isLoading = true
- this.isRefreshing = isRefreshing
- this.error = ''
- }
-
- private _xIdle(err?: any) {
- this.isLoading = false
- this.isRefreshing = false
- this.hasLoaded = true
- this.error = err ? err.toString() : ''
- if (err) {
- this.rootStore.log.error('Failed to fetch members', err)
- }
- }
-
- // loader functions
- // =
-
- private async _fetch(isRefreshing = false) {
- this._xLoading(isRefreshing)
- try {
- const res = await this.rootStore.api.app.bsky.graph.getMembers(
- this.params,
- )
- this._replaceAll(res)
- this._xIdle()
- } catch (e: any) {
- this._xIdle(e)
- }
- }
-
- private _replaceAll(res: GetMembers.Response) {
- 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.subject.avatar = res.data.subject.avatar
- this.members.length = 0
- let counter = 0
- for (const item of res.data.members) {
- this._append({_reactKey: `item-${counter++}`, ...item})
- }
- }
-
- private _append(item: MemberItem) {
- this.members.push(item)
- }
-}
diff --git a/src/state/models/memberships-view.ts b/src/state/models/memberships-view.ts
deleted file mode 100644
index 661b3f6a..00000000
--- a/src/state/models/memberships-view.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-import {makeAutoObservable} from 'mobx'
-import {
- AppBskyGraphGetMemberships as GetMemberships,
- AppBskyActorRef as ActorRef,
-} from '@atproto/api'
-import {RootStoreModel} from './root-store'
-
-export type MembershipItem = GetMemberships.Membership & {
- _reactKey: string
-}
-
-export class MembershipsViewModel {
- // state
- isLoading = false
- isRefreshing = false
- hasLoaded = false
- error = ''
- params: GetMemberships.QueryParams
-
- // data
- subject: ActorRef.WithInfo = {
- did: '',
- handle: '',
- displayName: '',
- declaration: {cid: '', actorType: ''},
- avatar: undefined,
- }
- memberships: MembershipItem[] = []
-
- constructor(
- public rootStore: RootStoreModel,
- params: GetMemberships.QueryParams,
- ) {
- makeAutoObservable(
- this,
- {
- rootStore: false,
- params: false,
- },
- {autoBind: true},
- )
- this.params = params
- }
-
- get hasContent() {
- return this.memberships.length !== 0
- }
-
- get hasError() {
- return this.error !== ''
- }
-
- get isEmpty() {
- return this.hasLoaded && !this.hasContent
- }
-
- isMemberOf(did: string) {
- return !!this.memberships.find(m => m.did === did)
- }
-
- // public api
- // =
-
- async setup() {
- await this._fetch()
- }
-
- async refresh() {
- await this._fetch(true)
- }
-
- async loadMore() {
- // TODO
- }
-
- // state transitions
- // =
-
- private _xLoading(isRefreshing = false) {
- this.isLoading = true
- this.isRefreshing = isRefreshing
- this.error = ''
- }
-
- private _xIdle(err?: any) {
- this.isLoading = false
- this.isRefreshing = false
- this.hasLoaded = true
- this.error = err ? err.toString() : ''
- if (err) {
- this.rootStore.log.error('Failed to fetch memberships', err)
- }
- }
-
- // loader functions
- // =
-
- private async _fetch(isRefreshing = false) {
- this._xLoading(isRefreshing)
- try {
- const res = await this.rootStore.api.app.bsky.graph.getMemberships(
- this.params,
- )
- this._replaceAll(res)
- this._xIdle()
- } catch (e: any) {
- this._xIdle(e)
- }
- }
-
- private _replaceAll(res: GetMemberships.Response) {
- 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.subject.avatar = res.data.subject.avatar
- this.memberships.length = 0
- let counter = 0
- for (const item of res.data.memberships) {
- this._append({_reactKey: `item-${counter++}`, ...item})
- }
- }
-
- private _append(item: MembershipItem) {
- this.memberships.push(item)
- }
-}
diff --git a/src/state/models/notifications-view.ts b/src/state/models/notifications-view.ts
index c169a995..c4d2b2df 100644
--- a/src/state/models/notifications-view.ts
+++ b/src/state/models/notifications-view.ts
@@ -4,17 +4,15 @@ import {
AppBskyActorRef as ActorRef,
AppBskyFeedPost,
AppBskyFeedRepost,
- AppBskyFeedTrend,
AppBskyFeedVote,
AppBskyGraphAssertion,
AppBskyGraphFollow,
- APP_BSKY_GRAPH,
} from '@atproto/api'
import {RootStoreModel} from './root-store'
import {PostThreadViewModel} from './post-thread-view'
import {cleanError} from '../../lib/strings'
-const UNGROUPABLE_REASONS = ['trend', 'assertion']
+const UNGROUPABLE_REASONS = ['assertion']
const PAGE_SIZE = 30
const MS_60MIN = 1e3 * 60 * 60
@@ -27,7 +25,6 @@ export interface GroupedNotification extends ListNotifications.Notification {
type SupportedRecord =
| AppBskyFeedPost.Record
| AppBskyFeedRepost.Record
- | AppBskyFeedTrend.Record
| AppBskyFeedVote.Record
| AppBskyGraphAssertion.Record
| AppBskyGraphFollow.Record
@@ -94,10 +91,6 @@ export class NotificationsViewItemModel {
return this.reason === 'repost'
}
- get isTrend() {
- return this.reason === 'trend'
- }
-
get isMention() {
return this.reason === 'mention'
}
@@ -115,26 +108,12 @@ export class NotificationsViewItemModel {
}
get needsAdditionalData() {
- if (
- this.isUpvote ||
- this.isRepost ||
- this.isTrend ||
- this.isReply ||
- this.isMention
- ) {
+ if (this.isUpvote || this.isRepost || this.isReply || this.isMention) {
return !this.additionalPost
}
return false
}
- get isInvite() {
- return (
- this.isAssertion &&
- AppBskyGraphAssertion.isRecord(this.record) &&
- this.record.assertion === APP_BSKY_GRAPH.AssertMember
- )
- }
-
get subjectUri(): string {
if (this.reasonSubject) {
return this.reasonSubject
@@ -142,7 +121,6 @@ export class NotificationsViewItemModel {
const record = this.record
if (
AppBskyFeedRepost.isRecord(record) ||
- AppBskyFeedTrend.isRecord(record) ||
AppBskyFeedVote.isRecord(record)
) {
return record.subject.uri
@@ -154,7 +132,6 @@ export class NotificationsViewItemModel {
for (const ns of [
AppBskyFeedPost,
AppBskyFeedRepost,
- AppBskyFeedTrend,
AppBskyFeedVote,
AppBskyGraphAssertion,
AppBskyGraphFollow,
@@ -185,7 +162,7 @@ export class NotificationsViewItemModel {
let postUri
if (this.isReply || this.isMention) {
postUri = this.uri
- } else if (this.isUpvote || this.isRepost || this.isTrend) {
+ } else if (this.isUpvote || this.isRepost) {
postUri = this.subjectUri
}
if (postUri) {
diff --git a/src/state/models/profile-ui.ts b/src/state/models/profile-ui.ts
index fb90fb69..55fb2506 100644
--- a/src/state/models/profile-ui.ts
+++ b/src/state/models/profile-ui.ts
@@ -1,24 +1,14 @@
import {makeAutoObservable} from 'mobx'
import {RootStoreModel} from './root-store'
import {ProfileViewModel} from './profile-view'
-import {MembersViewModel} from './members-view'
-import {MembershipsViewModel} from './memberships-view'
import {FeedModel} from './feed-view'
export enum Sections {
Posts = 'Posts',
PostsWithReplies = 'Posts & replies',
- Scenes = 'Scenes',
- Trending = 'Trending',
- Members = 'Members',
}
-const USER_SELECTOR_ITEMS = [
- Sections.Posts,
- Sections.PostsWithReplies,
- Sections.Scenes,
-]
-const SCENE_SELECTOR_ITEMS = [Sections.Trending, Sections.Members]
+const USER_SELECTOR_ITEMS = [Sections.Posts, Sections.PostsWithReplies]
export interface ProfileUiParams {
user: string
@@ -28,8 +18,6 @@ export class ProfileUiModel {
// data
profile: ProfileViewModel
feed: FeedModel
- memberships: MembershipsViewModel
- members: MembersViewModel
// ui state
selectedViewIndex = 0
@@ -51,24 +39,15 @@ export class ProfileUiModel {
author: params.user,
limit: 10,
})
- this.memberships = new MembershipsViewModel(rootStore, {actor: params.user})
- this.members = new MembersViewModel(rootStore, {actor: params.user})
}
- get currentView(): FeedModel | MembershipsViewModel | MembersViewModel {
+ get currentView(): FeedModel {
if (
this.selectedView === Sections.Posts ||
- this.selectedView === Sections.PostsWithReplies ||
- this.selectedView === Sections.Trending
+ this.selectedView === Sections.PostsWithReplies
) {
return this.feed
}
- if (this.selectedView === Sections.Scenes) {
- return this.memberships
- }
- if (this.selectedView === Sections.Members) {
- return this.members
- }
throw new Error(`Invalid selector value: ${this.selectedViewIndex}`)
}
@@ -85,15 +64,9 @@ export class ProfileUiModel {
return this.profile.isUser
}
- get isScene() {
- return this.profile.isScene
- }
-
get selectorItems() {
if (this.isUser) {
return USER_SELECTOR_ITEMS
- } else if (this.isScene) {
- return SCENE_SELECTOR_ITEMS
} else {
return USER_SELECTOR_ITEMS
}
@@ -119,16 +92,6 @@ export class ProfileUiModel {
.setup()
.catch(err => this.rootStore.log.error('Failed to fetch feed', err)),
])
- if (this.isUser) {
- await this.memberships
- .setup()
- .catch(err => this.rootStore.log.error('Failed to fetch members', err))
- }
- if (this.isScene) {
- await this.members
- .setup()
- .catch(err => this.rootStore.log.error('Failed to fetch members', err))
- }
}
async update() {
diff --git a/src/state/models/profile-view.ts b/src/state/models/profile-view.ts
index 2670627c..a1535693 100644
--- a/src/state/models/profile-view.ts
+++ b/src/state/models/profile-view.ts
@@ -13,11 +13,9 @@ import {RootStoreModel} from './root-store'
import * as apilib from '../lib/api'
export const ACTOR_TYPE_USER = 'app.bsky.system.actorUser'
-export const ACTOR_TYPE_SCENE = 'app.bsky.system.actorScene'
export class ProfileViewMyStateModel {
follow?: string
- member?: string
muted?: boolean
constructor() {
@@ -47,7 +45,6 @@ export class ProfileViewModel {
banner?: string
followersCount: number = 0
followsCount: number = 0
- membersCount: number = 0
postsCount: number = 0
myState = new ProfileViewMyStateModel()
@@ -85,10 +82,6 @@ export class ProfileViewModel {
return this.declaration.actorType === ACTOR_TYPE_USER
}
- get isScene() {
- return this.declaration.actorType === ACTOR_TYPE_SCENE
- }
-
// public api
// =
@@ -216,7 +209,6 @@ export class ProfileViewModel {
this.banner = res.data.banner
this.followersCount = res.data.followersCount
this.followsCount = res.data.followsCount
- this.membersCount = res.data.membersCount
this.postsCount = res.data.postsCount
if (res.data.myState) {
Object.assign(this.myState, res.data.myState)
diff --git a/src/state/models/shell-ui.ts b/src/state/models/shell-ui.ts
index 52d08168..1af74f56 100644
--- a/src/state/models/shell-ui.ts
+++ b/src/state/models/shell-ui.ts
@@ -25,22 +25,6 @@ export class EditProfileModal {
}
}
-export class CreateSceneModal {
- name = 'create-scene'
-
- constructor() {
- makeAutoObservable(this)
- }
-}
-
-export class InviteToSceneModal {
- name = 'invite-to-scene'
-
- constructor(public profileView: ProfileViewModel) {
- makeAutoObservable(this)
- }
-}
-
export class ServerInputModal {
name = 'server-input'
@@ -143,7 +127,6 @@ export class ShellUiModel {
activeModal:
| ConfirmModal
| EditProfileModal
- | CreateSceneModal
| ServerInputModal
| ReportPostModal
| ReportAccountModal
@@ -191,7 +174,6 @@ export class ShellUiModel {
modal:
| ConfirmModal
| EditProfileModal
- | CreateSceneModal
| ServerInputModal
| ReportPostModal
| ReportAccountModal,
diff --git a/src/state/models/suggested-invites-view.ts b/src/state/models/suggested-invites-view.ts
deleted file mode 100644
index fadc956c..00000000
--- a/src/state/models/suggested-invites-view.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import {makeAutoObservable, runInAction} from 'mobx'
-import {RootStoreModel} from './root-store'
-import {UserFollowsViewModel, FollowItem} from './user-follows-view'
-import {GetAssertionsView} from './get-assertions-view'
-import {APP_BSKY_SYSTEM, APP_BSKY_GRAPH} from '@atproto/api'
-
-export interface SuggestedInvitesViewParams {
- sceneDid: string
-}
-
-export class SuggestedInvitesView {
- // state
- isLoading = false
- isRefreshing = false
- hasLoaded = false
- error = ''
- params: SuggestedInvitesViewParams
- sceneAssertionsView: GetAssertionsView
- myFollowsView: UserFollowsViewModel
-
- // data
- suggestions: FollowItem[] = []
-
- constructor(
- public rootStore: RootStoreModel,
- params: SuggestedInvitesViewParams,
- ) {
- makeAutoObservable(
- this,
- {
- rootStore: false,
- params: false,
- },
- {autoBind: true},
- )
- this.params = params
- this.sceneAssertionsView = new GetAssertionsView(rootStore, {
- author: params.sceneDid,
- assertion: APP_BSKY_GRAPH.AssertMember,
- })
- this.myFollowsView = new UserFollowsViewModel(rootStore, {
- user: rootStore.me.did || '',
- })
- }
-
- get hasContent() {
- return this.suggestions.length > 0
- }
-
- get hasError() {
- return this.error !== ''
- }
-
- get isEmpty() {
- return this.hasLoaded && !this.hasContent
- }
-
- get unconfirmed() {
- return this.sceneAssertionsView.unconfirmed
- }
-
- // public api
- // =
-
- async setup() {
- await this._fetch(false)
- }
-
- async refresh() {
- await this._fetch(true)
- }
-
- async loadMore() {
- // TODO
- }
-
- // state transitions
- // =
-
- private _xLoading(isRefreshing = false) {
- this.isLoading = true
- this.isRefreshing = isRefreshing
- this.error = ''
- }
-
- private _xIdle(err?: any) {
- this.isLoading = false
- this.isRefreshing = false
- this.hasLoaded = true
- this.error = err ? err.toString() : ''
- if (err) {
- this.rootStore.log.error('Failed to fetch suggested invites', err)
- }
- }
-
- // loader functions
- // =
-
- private async _fetch(isRefreshing = false) {
- this._xLoading(isRefreshing)
- try {
- // TODO need to fetch all!
- await this.sceneAssertionsView.setup()
- } catch (e: any) {
- this.rootStore.log.error(
- 'Failed to fetch current scene members in suggested invites',
- e,
- )
- this._xIdle(
- 'Failed to fetch the current scene members. Check your internet connection and try again.',
- )
- return
- }
- try {
- await this.myFollowsView.setup()
- } catch (e: any) {
- this.rootStore.log.error(
- 'Failed to fetch current followers in suggested invites',
- e,
- )
- this._xIdle(
- 'Failed to fetch the your current followers. Check your internet connection and try again.',
- )
- return
- }
-
- // collect all followed users that arent already in the scene
- const newSuggestions: FollowItem[] = []
- for (const follow of this.myFollowsView.follows) {
- if (follow.declaration.actorType !== APP_BSKY_SYSTEM.ActorUser) {
- continue
- }
- if (!this.sceneAssertionsView.getBySubject(follow.did)) {
- newSuggestions.push(follow)
- }
- }
- runInAction(() => {
- this.suggestions = newSuggestions
- })
- this._xIdle()
- }
-}
diff --git a/src/view/com/modals/CreateScene.tsx b/src/view/com/modals/CreateScene.tsx
deleted file mode 100644
index d92fe2e3..00000000
--- a/src/view/com/modals/CreateScene.tsx
+++ /dev/null
@@ -1,243 +0,0 @@
-import React, {useState} from 'react'
-import * as Toast from '../util/Toast'
-import {
- ActivityIndicator,
- StyleSheet,
- TouchableOpacity,
- View,
-} from 'react-native'
-import LinearGradient from 'react-native-linear-gradient'
-import {BottomSheetScrollView, BottomSheetTextInput} from '@gorhom/bottom-sheet'
-import {AppBskyActorCreateScene} from '@atproto/api'
-import {ErrorMessage} from '../util/error/ErrorMessage'
-import {Text} from '../util/text/Text'
-import {useStores} from '../../../state'
-import {s, colors, gradients} from '../../lib/styles'
-import {
- makeValidHandle,
- createFullHandle,
- enforceLen,
- MAX_DISPLAY_NAME,
- MAX_DESCRIPTION,
-} from '../../../lib/strings'
-
-export const snapPoints = ['60%']
-
-export function Component({}: {}) {
- const store = useStores()
- const [error, setError] = useState('')
- const [isProcessing, setIsProcessing] = useState(false)
- const [handle, setHandle] = useState('')
- const [displayName, setDisplayName] = useState('')
- const [description, setDescription] = useState('')
- const onPressSave = async () => {
- setIsProcessing(true)
- if (error) {
- setError('')
- }
- try {
- if (!store.me.did) {
- return
- }
- const desc = await store.api.com.atproto.server.getAccountsConfig()
- const fullHandle = createFullHandle(
- handle,
- desc.data.availableUserDomains[0],
- )
- // create scene actor
- const createSceneRes = await store.api.app.bsky.actor.createScene({
- handle: fullHandle,
- })
- // set the scene profile
- await store.api.app.bsky.actor
- .updateProfile({
- did: createSceneRes.data.did,
- displayName,
- description,
- })
- .catch(e =>
- // an error here is not critical
- store.log.error('Failed to update scene profile during creation', e),
- )
- // follow the scene
- await store.api.app.bsky.graph.follow
- .create(
- {
- did: store.me.did,
- },
- {
- subject: {
- did: createSceneRes.data.did,
- declarationCid: createSceneRes.data.declaration.cid,
- },
- createdAt: new Date().toISOString(),
- },
- )
- .catch(e =>
- // an error here is not critical
- store.log.error('Failed to follow scene after creation', e),
- )
- Toast.show('Scene created')
- store.shell.closeModal()
- store.nav.navigate(`/profile/${fullHandle}`)
- } catch (e: any) {
- if (e instanceof AppBskyActorCreateScene.InvalidHandleError) {
- setError(
- 'The handle can only contain letters, numbers, and dashes, and must start with a letter.',
- )
- } else if (e instanceof AppBskyActorCreateScene.HandleNotAvailableError) {
- setError(`The handle "${handle}" is not available.`)
- } else {
- store.log.error('Failed to create scene', e)
- setError(
- 'Failed to create the scene. Check your internet connection and try again.',
- )
- }
- setIsProcessing(false)
- }
- }
- const onPressCancel = () => {
- store.shell.closeModal()
- }
-
- return (
-
-
- Create a scene
-
- Scenes are invite-only groups which aggregate what's popular with
- members.
-
-
-
- Scene Handle
- setHandle(makeValidHandle(str))}
- />
-
-
- Scene Display Name
-
- setDisplayName(enforceLen(v, MAX_DISPLAY_NAME))
- }
- />
-
-
- Scene Description
- setDescription(enforceLen(v, MAX_DESCRIPTION))}
- />
-
- {error !== '' && (
-
-
-
- )}
- {handle.length >= 2 && !isProcessing ? (
-
-
- Create Scene
-
-
- ) : (
-
-
- {isProcessing ? (
-
- ) : (
- Create Scene
- )}
-
-
- )}
-
-
- Cancel
-
-
-
-
-
- )
-}
-
-const styles = StyleSheet.create({
- outer: {
- flex: 1,
- // paddingTop: 20,
- },
- title: {
- textAlign: 'center',
- fontWeight: 'bold',
- fontSize: 24,
- marginBottom: 12,
- },
- description: {
- textAlign: 'center',
- fontSize: 17,
- paddingHorizontal: 22,
- color: colors.gray5,
- marginBottom: 10,
- },
- inner: {
- padding: 14,
- height: 350,
- },
- group: {
- marginBottom: 10,
- },
- label: {
- fontSize: 16,
- fontWeight: 'bold',
- paddingHorizontal: 4,
- paddingBottom: 4,
- },
- textInput: {
- borderWidth: 1,
- borderColor: colors.gray3,
- borderRadius: 6,
- paddingHorizontal: 14,
- paddingVertical: 10,
- fontSize: 16,
- color: colors.black,
- },
- textArea: {
- borderWidth: 1,
- borderColor: colors.gray3,
- borderRadius: 6,
- paddingHorizontal: 12,
- paddingTop: 10,
- fontSize: 16,
- color: colors.black,
- height: 70,
- textAlignVertical: 'top',
- },
- btn: {
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'center',
- width: '100%',
- borderRadius: 32,
- padding: 14,
- backgroundColor: colors.gray1,
- },
-})
diff --git a/src/view/com/modals/InviteToScene.tsx b/src/view/com/modals/InviteToScene.tsx
deleted file mode 100644
index 2b4d0ac2..00000000
--- a/src/view/com/modals/InviteToScene.tsx
+++ /dev/null
@@ -1,308 +0,0 @@
-import React, {useState, useEffect, useMemo} from 'react'
-import {observer} from 'mobx-react-lite'
-import * as Toast from '../util/Toast'
-import {
- ActivityIndicator,
- FlatList,
- StyleSheet,
- useWindowDimensions,
- View,
-} from 'react-native'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {
- TabView,
- SceneMap,
- Route,
- TabBar,
- TabBarProps,
-} from 'react-native-tab-view'
-import _omit from 'lodash.omit'
-import {AtUri} from '../../../third-party/uri'
-import {ProfileCard} from '../profile/ProfileCard'
-import {ErrorMessage} from '../util/error/ErrorMessage'
-import {Text} from '../util/text/Text'
-import {useStores} from '../../../state'
-import * as apilib from '../../../state/lib/api'
-import {ProfileViewModel} from '../../../state/models/profile-view'
-import {SuggestedInvitesView} from '../../../state/models/suggested-invites-view'
-import {Assertion} from '../../../state/models/get-assertions-view'
-import {FollowItem} from '../../../state/models/user-follows-view'
-import {s, colors} from '../../lib/styles'
-
-export const snapPoints = ['70%']
-
-export const Component = observer(function Component({
- profileView,
-}: {
- profileView: ProfileViewModel
-}) {
- const store = useStores()
- const layout = useWindowDimensions()
- const [index, setIndex] = useState(0)
- const tabRoutes = [
- {key: 'suggestions', title: 'Suggestions'},
- {key: 'pending', title: 'Pending Invites'},
- ]
- const [hasSetup, setHasSetup] = useState(false)
- const [error, setError] = useState('')
- const suggestions = useMemo(
- () => new SuggestedInvitesView(store, {sceneDid: profileView.did}),
- [profileView.did],
- )
- const [createdInvites, setCreatedInvites] = useState>(
- {},
- )
- // TODO: it would be much better if we just used the suggestions view for the deleted pending invites
- // but mobx isnt picking up on the state change in suggestions.unconfirmed and I dont have
- // time to debug that right now -prf
- const [deletedPendingInvites, setDeletedPendingInvites] = useState<
- Record
- >({})
-
- useEffect(() => {
- let aborted = false
- if (hasSetup) {
- return
- }
- suggestions.setup().then(() => {
- if (aborted) return
- setHasSetup(true)
- })
- return () => {
- aborted = true
- }
- }, [profileView.did])
-
- const onPressInvite = async (follow: FollowItem) => {
- setError('')
- try {
- const assertionUri = await apilib.inviteToScene(
- store,
- profileView.did,
- follow.did,
- follow.declaration.cid,
- )
- setCreatedInvites({[follow.did]: assertionUri, ...createdInvites})
- Toast.show('Invite sent')
- } catch (e: any) {
- setError('There was an issue with the invite. Please try again.')
- store.log.error('Failed to invite user to scene', e)
- }
- }
- const onPressUndo = async (subjectDid: string, assertionUri: string) => {
- setError('')
- const urip = new AtUri(assertionUri)
- try {
- await store.api.app.bsky.graph.assertion.delete({
- did: profileView.did,
- rkey: urip.rkey,
- })
- setCreatedInvites(_omit(createdInvites, [subjectDid]))
- } catch (e: any) {
- setError('There was an issue with the invite. Please try again.')
- store.log.error('Failed to delete a scene invite', e)
- }
- }
-
- const onPressDeleteInvite = async (assertion: Assertion) => {
- setError('')
- const urip = new AtUri(assertion.uri)
- try {
- await store.api.app.bsky.graph.assertion.delete({
- did: profileView.did,
- rkey: urip.rkey,
- })
- setDeletedPendingInvites({
- [assertion.uri]: true,
- ...deletedPendingInvites,
- })
- Toast.show('Invite removed')
- } catch (e: any) {
- setError('There was an issue with the invite. Please try again.')
- store.log.error('Failed to delete an invite', e)
- }
- }
-
- const renderSuggestionItem = ({item}: {item: FollowItem}) => {
- const createdInvite = createdInvites[item.did]
- return (
-
- !createdInvite ? (
- <>
-
- Invite
- >
- ) : (
- <>
-
- Undo invite
- >
- )
- }
- onPressButton={() =>
- !createdInvite
- ? onPressInvite(item)
- : onPressUndo(item.did, createdInvite)
- }
- />
- )
- }
-
- const renderPendingInviteItem = ({item}: {item: Assertion}) => {
- const wasDeleted = deletedPendingInvites[item.uri]
- if (wasDeleted) {
- return
- }
- return (
- (
- <>
-
- Undo invite
- >
- )}
- onPressButton={() => onPressDeleteInvite(item)}
- />
- )
- }
-
- const Suggestions = () => (
-
- {hasSetup ? (
-
-
-
- User search is still being implemented. For now, you can pick from
- your follows below.
-
-
- {!suggestions.hasContent ? (
-
- {suggestions.myFollowsView.follows.length
- ? 'Sorry! You dont follow anybody for us to suggest.'
- : 'Sorry! All of the users you follow are members already.'}
-
- ) : (
- item._reactKey}
- renderItem={renderSuggestionItem}
- style={s.flex1}
- />
- )}
-
- ) : !error ? (
-
- ) : undefined}
-
- )
-
- const PendingInvites = () => (
-
- {suggestions.sceneAssertionsView.isLoading ? (
-
- ) : undefined}
-
- {!suggestions.unconfirmed.length ? (
-
- No pending invites.
-
- ) : (
- item._reactKey}
- renderItem={renderPendingInviteItem}
- style={s.flex1}
- />
- )}
-
-
- )
-
- const renderScene = SceneMap({
- suggestions: Suggestions,
- pending: PendingInvites,
- })
-
- const renderTabBar = (props: TabBarProps) => (
-
- )
-
- return (
-
-
- Invite to {profileView.displayName || profileView.handle}
-
- {error !== '' ? (
-
-
-
- ) : undefined}
-
-
- )
-})
-
-const styles = StyleSheet.create({
- title: {
- textAlign: 'center',
- fontWeight: 'bold',
- fontSize: 18,
- marginBottom: 4,
- },
- todoContainer: {
- backgroundColor: colors.pink1,
- margin: 10,
- padding: 10,
- borderRadius: 6,
- },
- todoLabel: {
- color: colors.pink5,
- textAlign: 'center',
- },
-
- tabBar: {
- flexDirection: 'row',
- },
- tabItem: {
- alignItems: 'center',
- padding: 16,
- flex: 1,
- },
-})
diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx
index 43271c96..e0e18d54 100644
--- a/src/view/com/modals/Modal.tsx
+++ b/src/view/com/modals/Modal.tsx
@@ -9,8 +9,6 @@ import * as models from '../../../state/models/shell-ui'
import * as ConfirmModal from './Confirm'
import * as EditProfileModal from './EditProfile'
-import * as CreateSceneModal from './CreateScene'
-import * as InviteToSceneModal from './InviteToScene'
import * as ServerInputModal from './ServerInput'
import * as ReportPostModal from './ReportPost'
import * as ReportAccountModal from './ReportAccount'
@@ -55,16 +53,6 @@ export const Modal = observer(function Modal() {
{...(store.shell.activeModal as models.EditProfileModal)}
/>
)
- } else if (store.shell.activeModal?.name === 'create-scene') {
- snapPoints = CreateSceneModal.snapPoints
- element =
- } else if (store.shell.activeModal?.name === 'invite-to-scene') {
- snapPoints = InviteToSceneModal.snapPoints
- element = (
-
- )
} else if (store.shell.activeModal?.name === 'server-input') {
snapPoints = ServerInputModal.snapPoints
element = (
diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx
index c578b712..73948785 100644
--- a/src/view/com/notifications/FeedItem.tsx
+++ b/src/view/com/notifications/FeedItem.tsx
@@ -14,7 +14,6 @@ import {UserAvatar} from '../util/UserAvatar'
import {ErrorMessage} from '../util/error/ErrorMessage'
import {Post} from '../post/Post'
import {Link} from '../util/Link'
-import {InviteAccepter} from './InviteAccepter'
import {usePalette} from '../../lib/hooks/usePalette'
const MAX_AUTHORS = 8
@@ -26,7 +25,7 @@ export const FeedItem = observer(function FeedItem({
}) {
const pal = usePalette('default')
const itemHref = useMemo(() => {
- if (item.isUpvote || item.isRepost || item.isTrend) {
+ if (item.isUpvote || item.isRepost) {
const urip = new AtUri(item.subjectUri)
return `/profile/${urip.host}/post/${urip.rkey}`
} else if (item.isFollow || item.isAssertion) {
@@ -82,10 +81,6 @@ export const FeedItem = observer(function FeedItem({
action = 'reposted your post'
icon = 'retweet'
iconStyle = [s.green3]
- } else if (item.isTrend) {
- action = 'Your post is trending with'
- icon = 'arrow-trend-up'
- iconStyle = [s.red3]
} else if (item.isReply) {
action = 'replied to your post'
icon = ['far', 'comment']
@@ -93,10 +88,6 @@ export const FeedItem = observer(function FeedItem({
action = 'followed you'
icon = 'user-plus'
iconStyle = [s.blue3]
- } else if (item.isInvite) {
- icon = 'users'
- iconStyle = [s.blue3]
- action = 'invited you to join their scene'
} else {
return <>>
}
@@ -173,9 +164,6 @@ export const FeedItem = observer(function FeedItem({
) : undefined}
- {item.isTrend && (
- {action}
- )}
>
) : undefined}
- {!item.isTrend && (
- {action}
- )}
{ago(item.indexedAt)}
- {item.isUpvote || item.isRepost || item.isTrend ? (
+ {item.isUpvote || item.isRepost ? (
) : (
<>>
)}
- {item.isInvite && (
-
-
-
- )}
)
})
diff --git a/src/view/com/notifications/InviteAccepter.tsx b/src/view/com/notifications/InviteAccepter.tsx
deleted file mode 100644
index a8789b17..00000000
--- a/src/view/com/notifications/InviteAccepter.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import React from 'react'
-import {StyleSheet, TouchableOpacity, View} from 'react-native'
-import LinearGradient from 'react-native-linear-gradient'
-import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import * as apilib from '../../../state/lib/api'
-import {NotificationsViewItemModel} from '../../../state/models/notifications-view'
-import {ConfirmModal} from '../../../state/models/shell-ui'
-import {useStores} from '../../../state'
-import {ProfileCard} from '../profile/ProfileCard'
-import * as Toast from '../util/Toast'
-import {Text} from '../util/text/Text'
-import {s, colors, gradients} from '../../lib/styles'
-
-export function InviteAccepter({item}: {item: NotificationsViewItemModel}) {
- const store = useStores()
- // Using default import (React.use...) instead of named import (use...) to be able to mock store's data in jest environment
- const [confirmationUri, setConfirmationUri] = React.useState('')
- const isMember =
- confirmationUri !== '' || store.me.memberships?.isMemberOf(item.author.did)
- const onPressAccept = async () => {
- store.shell.openModal(
- new ConfirmModal(
- 'Join this scene?',
- () => (
-
-
-
-
-
- ),
- onPressConfirmAccept,
- ),
- )
- }
- const onPressConfirmAccept = async () => {
- const uri = await apilib.acceptSceneInvite(store, {
- originator: {
- did: item.author.did,
- declarationCid: item.author.declaration.cid,
- },
- assertion: {
- uri: item.uri,
- cid: item.cid,
- },
- })
- store.me.refreshMemberships()
- Toast.show('Invite accepted')
- setConfirmationUri(uri)
- }
- return (
-
- {!isMember ? (
-
-
- Accept Invite
-
-
- ) : (
-
-
- Invite accepted
-
- )}
-
- )
-}
-
-const styles = StyleSheet.create({
- container: {
- flexDirection: 'row',
- },
- btn: {
- borderRadius: 32,
- paddingHorizontal: 18,
- paddingVertical: 8,
- backgroundColor: colors.gray1,
- },
- profileCardContainer: {
- borderWidth: 1,
- borderColor: colors.gray3,
- borderRadius: 6,
- },
- inviteAccepted: {
- flexDirection: 'row',
- alignItems: 'center',
- },
-})
diff --git a/src/view/com/onboard/FeatureExplainer.tsx b/src/view/com/onboard/FeatureExplainer.tsx
index ecc1b969..78ace518 100644
--- a/src/view/com/onboard/FeatureExplainer.tsx
+++ b/src/view/com/onboard/FeatureExplainer.tsx
@@ -11,10 +11,9 @@ import {
import {TabView, SceneMap, Route, TabBarProps} from 'react-native-tab-view'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {Text} from '../util/text/Text'
-import {UserGroupIcon} from '../../lib/icons'
import {useStores} from '../../../state'
import {s} from '../../lib/styles'
-import {SCENE_EXPLAINER, TABS_EXPLAINER} from '../../lib/assets'
+import {TABS_EXPLAINER} from '../../lib/assets'
import {TABS_ENABLED} from '../../../build-flags'
const Intro = () => (
@@ -28,25 +27,7 @@ const Intro = () => (
Welcome to Bluesky
- Let's do a quick tour through the new features.
-
-
-)
-
-const Scenes = () => (
-
-
-
-
-
-
- Scenes
-
- Scenes are invite-only groups of users. Follow them to see what's trending
- with the scene's members.
-
-
-
+ This is an early beta. Your feedback is appreciated!
)
@@ -74,7 +55,6 @@ const Tabs = () => (
const SCENE_MAP = {
intro: Intro,
- scenes: Scenes,
tabs: Tabs,
}
const renderScene = SceneMap(SCENE_MAP)
@@ -85,7 +65,6 @@ export const FeatureExplainer = () => {
const [index, setIndex] = useState(0)
const routes = [
{key: 'intro', title: 'Intro'},
- {key: 'scenes', title: 'Scenes'},
TABS_ENABLED ? {key: 'tabs', title: 'Tabs'} : undefined,
].filter(Boolean)
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index 80e08ae7..f5536907 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -155,23 +155,6 @@ export const FeedItem = observer(function ({
)}
- {item.reasonTrend && (
-
-
-
- Trending with{' '}
- {item.reasonTrend.by.displayName || item.reasonTrend.by.handle}
-
-
- )}
diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx
index 4fd76695..663290a2 100644
--- a/src/view/com/profile/ProfileHeader.tsx
+++ b/src/view/com/profile/ProfileHeader.tsx
@@ -1,15 +1,12 @@
-import React, {useMemo} from 'react'
+import React from 'react'
import {observer} from 'mobx-react-lite'
import {StyleSheet, TouchableOpacity, View} from 'react-native'
import LinearGradient from 'react-native-linear-gradient'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {AtUri} from '../../../third-party/uri'
import {ProfileViewModel} from '../../../state/models/profile-view'
import {useStores} from '../../../state'
import {
- ConfirmModal,
EditProfileModal,
- InviteToSceneModal,
ReportAccountModal,
ProfileImageLightbox,
} from '../../../state/models/shell-ui'
@@ -23,7 +20,6 @@ import {Text} from '../util/text/Text'
import {RichText} from '../util/text/RichText'
import {UserAvatar} from '../util/UserAvatar'
import {UserBanner} from '../util/UserBanner'
-import {UserInfoText} from '../util/UserInfoText'
import {usePalette} from '../../lib/hooks/usePalette'
export const ProfileHeader = observer(function ProfileHeader({
@@ -35,10 +31,6 @@ export const ProfileHeader = observer(function ProfileHeader({
}) {
const pal = usePalette('default')
const store = useStores()
- const isMember = useMemo(
- () => view.isScene && view.myState.member,
- [view.myState.member],
- )
const onPressAvi = () => {
store.shell.openLightbox(new ProfileImageLightbox(view))
@@ -64,31 +56,6 @@ export const ProfileHeader = observer(function ProfileHeader({
const onPressFollows = () => {
store.nav.navigate(`/profile/${view.handle}/follows`)
}
- const onPressMembers = () => {
- store.nav.navigate(`/profile/${view.handle}/members`)
- }
- const onPressInviteMembers = () => {
- store.shell.openModal(new InviteToSceneModal(view))
- }
- const onPressLeaveScene = () => {
- store.shell.openModal(
- new ConfirmModal(
- 'Leave this scene?',
- `You'll be able to come back unless your invite is revoked.`,
- onPressConfirmLeaveScene,
- ),
- )
- }
- const onPressConfirmLeaveScene = async () => {
- if (view.myState.member) {
- await store.api.app.bsky.graph.confirmation.delete({
- did: store.me.did || '',
- rkey: new AtUri(view.myState.member).rkey,
- })
- Toast.show(`Scene left`)
- }
- onRefreshAll()
- }
const onPressMuteAccount = async () => {
try {
await view.muteAccount()
@@ -157,7 +124,6 @@ export const ProfileHeader = observer(function ProfileHeader({
// =
const gradient = getGradient(view.handle)
const isMe = store.me.did === view.did
- const isCreator = view.isScene && view.creator === store.me.did
let dropdownItems: DropdownItem[] | undefined
if (!isMe) {
dropdownItems = dropdownItems || []
@@ -170,21 +136,6 @@ export const ProfileHeader = observer(function ProfileHeader({
onPress: onPressReportAccount,
})
}
- if (isCreator || isMember) {
- dropdownItems = dropdownItems || []
- if (isCreator) {
- dropdownItems.push({
- label: 'Edit Profile',
- onPress: onPressEditProfile,
- })
- }
- if (isMember) {
- dropdownItems.push({
- label: 'Leave Scene...',
- onPress: onPressLeaveScene,
- })
- }
- }
return (
@@ -247,15 +198,6 @@ export const ProfileHeader = observer(function ProfileHeader({
- {view.isScene ? (
-
- Scene
-
- ) : undefined}
@{view.handle}
@@ -283,19 +225,6 @@ export const ProfileHeader = observer(function ProfileHeader({
) : undefined}
- {view.isScene ? (
-
-
- {view.membersCount}
-
-
- {pluralize(view.membersCount, 'member')}
-
-
- ) : undefined}
{view.postsCount}
@@ -313,35 +242,6 @@ export const ProfileHeader = observer(function ProfileHeader({
entities={view.descriptionEntities}
/>
) : undefined}
- {view.isScene && view.creator ? (
-
-
-
- Created by
-
-
-
- ) : undefined}
- {view.isScene && view.myState.member ? (
-
-
-
- You are a member
-
-
- ) : undefined}
{view.myState.muted ? (
) : undefined}
- {view.isScene && view.creator === store.me.did ? (
-
-
-
-
-
- Invite Members
-
-
-
-
- ) : undefined}
()
-
- useEffect(() => {
- if (view?.params.actor === name) {
- return // no change needed? or trigger refresh?
- }
- const newView = new MembersViewModel(store, {actor: name})
- setView(newView)
- newView
- .setup()
- .catch(err => store.log.error('Failed to fetch members', err))
- }, [name, view?.params.actor, store])
-
- const onRefresh = () => {
- view?.refresh()
- }
-
- // loading
- // =
- if (
- !view ||
- (view.isLoading && !view.isRefreshing) ||
- view.params.actor !== name
- ) {
- return (
-
-
-
- )
- }
-
- // error
- // =
- if (view.hasError) {
- return (
-
-
-
- )
- }
-
- // loaded
- // =
- const renderItem = ({item}: {item: MemberItem}) => (
-
- )
- return (
-
- item._reactKey}
- renderItem={renderItem}
- />
-
- )
-})
diff --git a/src/view/index.ts b/src/view/index.ts
index 5602784f..8ffd5957 100644
--- a/src/view/index.ts
+++ b/src/view/index.ts
@@ -12,7 +12,6 @@ import {faArrowRightFromBracket} from '@fortawesome/free-solid-svg-icons'
import {faArrowUpFromBracket} from '@fortawesome/free-solid-svg-icons/faArrowUpFromBracket'
import {faArrowUpRightFromSquare} from '@fortawesome/free-solid-svg-icons/faArrowUpRightFromSquare'
import {faArrowsRotate} from '@fortawesome/free-solid-svg-icons/faArrowsRotate'
-import {faArrowTrendUp} from '@fortawesome/free-solid-svg-icons/faArrowTrendUp'
import {faAt} from '@fortawesome/free-solid-svg-icons/faAt'
import {faBars} from '@fortawesome/free-solid-svg-icons/faBars'
import {faBell} from '@fortawesome/free-solid-svg-icons/faBell'
@@ -81,7 +80,6 @@ export function setup() {
faArrowUpFromBracket,
faArrowUpRightFromSquare,
faArrowsRotate,
- faArrowTrendUp,
faAt,
faBars,
faBell,
diff --git a/src/view/lib/assets.native.ts b/src/view/lib/assets.native.ts
index 4b5c3efc..609f8e01 100644
--- a/src/view/lib/assets.native.ts
+++ b/src/view/lib/assets.native.ts
@@ -1,5 +1,4 @@
import {ImageSourcePropType} from 'react-native'
export const DEF_AVATAR: ImageSourcePropType = require('../../../public/img/default-avatar.jpg')
-export const SCENE_EXPLAINER: ImageSourcePropType = require('../../../public/img/scene-explainer.jpg')
export const TABS_EXPLAINER: ImageSourcePropType = require('../../../public/img/tabs-explainer.jpg')
diff --git a/src/view/lib/assets.ts b/src/view/lib/assets.ts
index 04c36808..9e937d4d 100644
--- a/src/view/lib/assets.ts
+++ b/src/view/lib/assets.ts
@@ -1,9 +1,6 @@
import {ImageSourcePropType} from 'react-native'
export const DEF_AVATAR: ImageSourcePropType = {uri: '/img/default-avatar.jpg'}
-export const SCENE_EXPLAINER: ImageSourcePropType = {
- uri: '/img/scene-explainer.jpg',
-}
export const TABS_EXPLAINER: ImageSourcePropType = {
uri: '/img/tabs-explainer.jpg',
}
diff --git a/src/view/routes.ts b/src/view/routes.ts
index 0a2883e6..7d5a06ac 100644
--- a/src/view/routes.ts
+++ b/src/view/routes.ts
@@ -13,7 +13,6 @@ import {PostRepostedBy} from './screens/PostRepostedBy'
import {Profile} from './screens/Profile'
import {ProfileFollowers} from './screens/ProfileFollowers'
import {ProfileFollows} from './screens/ProfileFollows'
-import {ProfileMembers} from './screens/ProfileMembers'
import {Settings} from './screens/Settings'
import {Debug} from './screens/Debug'
import {Log} from './screens/Log'
@@ -48,7 +47,6 @@ export const routes: Route[] = [
r('/profile/(?[^/]+)/followers'),
],
[ProfileFollows, 'Follows', 'users', r('/profile/(?[^/]+)/follows')],
- [ProfileMembers, 'Members', 'users', r('/profile/(?[^/]+)/members')],
[
PostThread,
'Post',
diff --git a/src/view/screens/Notifications.tsx b/src/view/screens/Notifications.tsx
index 7c9fac40..dd6e0761 100644
--- a/src/view/screens/Notifications.tsx
+++ b/src/view/screens/Notifications.tsx
@@ -15,7 +15,6 @@ export const Notifications = ({navIdx, visible}: ScreenParams) => {
return
}
store.log.debug('Updating notifications feed')
- store.me.refreshMemberships() // needed for the invite notifications
store.me.notifications
.update()
.catch(e => {
diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx
index 64bb4f04..454ae8ad 100644
--- a/src/view/screens/Profile.tsx
+++ b/src/view/screens/Profile.tsx
@@ -1,16 +1,13 @@
import React, {useEffect, useState} from 'react'
import {ActivityIndicator, StyleSheet, 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 {ConfirmModal} from '../../state/models/shell-ui'
import {ProfileHeader} from '../com/profile/ProfileHeader'
import {FeedItem} from '../com/posts/FeedItem'
-import {ProfileCard} from '../com/profile/ProfileCard'
import {PostFeedLoadingPlaceholder} from '../com/util/LoadingPlaceholder'
import {ErrorScreen} from '../com/util/error/ErrorScreen'
import {ErrorMessage} from '../com/util/error/ErrorMessage'
@@ -77,18 +74,6 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => {
const onPressTryAgain = () => {
uiState.setup()
}
- const onPressRemoveMember = (membership: MembershipItem) => {
- store.shell.openModal(
- new ConfirmModal(
- `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`)
- },
- ),
- )
- }
const onPressCompose = () => {
store.shell.openComposer({})
@@ -97,9 +82,6 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => {
// rendering
// =
- const isSceneCreator =
- uiState.isScene && store.me.did === uiState.profile.creator
-
const renderHeader = () => {
if (!uiState) {
return
@@ -131,8 +113,7 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => {
} else {
if (
uiState.selectedView === Sections.Posts ||
- uiState.selectedView === Sections.PostsWithReplies ||
- uiState.selectedView === Sections.Trending
+ uiState.selectedView === Sections.PostsWithReplies
) {
if (uiState.feed.hasContent) {
if (uiState.selectedView === Sections.Posts) {
@@ -152,81 +133,12 @@ export const Profile = observer(({navIdx, visible, params}: ScreenParams) => {
return
}
} else if (uiState.feed.isEmpty) {
- items = items.concat([EMPTY_ITEM])
- if (uiState.profile.isScene) {
- renderItem = () => (
-
- )
- } else {
- renderItem = () => (
-
- )
- }
- }
- } else if (uiState.selectedView === Sections.Scenes) {
- if (uiState.memberships.hasContent) {
- items = uiState.memberships.memberships.slice()
- renderItem = (item: any) => {
- return (
-
- )
- }
- } else if (uiState.memberships.isEmpty) {
items = items.concat([EMPTY_ITEM])
renderItem = () => (
- )
- }
- } else if (uiState.selectedView === Sections.Members) {
- 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)}
- />
- )
- }
- } else if (uiState.members.isEmpty) {
- items = items.concat([EMPTY_ITEM])
- renderItem = () => (
-
)
}
diff --git a/src/view/screens/ProfileMembers.tsx b/src/view/screens/ProfileMembers.tsx
deleted file mode 100644
index 9d6723fe..00000000
--- a/src/view/screens/ProfileMembers.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React, {useEffect} from 'react'
-import {View} from 'react-native'
-import {ViewHeader} from '../com/util/ViewHeader'
-import {ProfileMembers as ProfileMembersComponent} from '../com/profile/ProfileMembers'
-import {ScreenParams} from '../routes'
-import {useStores} from '../../state'
-
-export const ProfileMembers = ({navIdx, visible, params}: ScreenParams) => {
- const store = useStores()
- const {name} = params
-
- useEffect(() => {
- if (visible) {
- store.nav.setTitle(navIdx, `Members of ${name}`)
- store.shell.setMinimalShellMode(false)
- }
- }, [store, visible, name])
-
- return (
-
-
-
-
- )
-}
diff --git a/src/view/shell/mobile/Menu.tsx b/src/view/shell/mobile/Menu.tsx
index 6a673d25..3a6bbbc0 100644
--- a/src/view/shell/mobile/Menu.tsx
+++ b/src/view/shell/mobile/Menu.tsx
@@ -1,4 +1,4 @@
-import React, {useEffect} from 'react'
+import React from 'react'
import {
ScrollView,
StyleProp,
@@ -11,17 +11,10 @@ import {observer} from 'mobx-react-lite'
import VersionNumber from 'react-native-version-number'
import {s, colors} from '../../lib/styles'
import {useStores} from '../../../state'
-import {
- HomeIcon,
- UserGroupIcon,
- BellIcon,
- CogIcon,
- MagnifyingGlassIcon,
-} from '../../lib/icons'
+import {HomeIcon, BellIcon, CogIcon, MagnifyingGlassIcon} from '../../lib/icons'
import {UserAvatar} from '../../com/util/UserAvatar'
import {Text} from '../../com/util/text/Text'
import {ToggleButton} from '../../com/util/forms/ToggleButton'
-import {CreateSceneModal} from '../../../state/models/shell-ui'
import {usePalette} from '../../lib/hooks/usePalette'
export const Menu = observer(
@@ -29,14 +22,6 @@ export const Menu = observer(
const pal = usePalette('default')
const store = useStores()
- useEffect(() => {
- if (visible) {
- // trigger a refresh in case memberships have changed recently
- // TODO this impacts performance, need to find the right time to do this
- // store.me.refreshMemberships()
- }
- }, [store, visible])
-
// events
// =
@@ -51,10 +36,6 @@ export const Menu = observer(
}
}
}
- const onPressCreateScene = () => {
- onClose()
- store.shell.openModal(new CreateSceneModal())
- }
// rendering
// =
@@ -152,40 +133,6 @@ export const Menu = observer(
url="/notifications"
count={store.me.notificationCount}
/>
-
-
-
- Scenes
-
- {store.me.memberships
- ? store.me.memberships.memberships.map((membership, i) => (
-
- }
- label={membership.displayName || membership.handle}
- url={`/profile/${membership.handle}`}
- />
- ))
- : undefined}
-
-
-