From bf1092ad86ef8e5829db29a17f33380dabab8535 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Tue, 17 Jan 2023 10:11:30 -0600 Subject: [PATCH] Remove scenes (#36) * Remove scenes from the main menu * Remove scenes from the profile view * Remove 'scenes explainer' from onboarding flow * Remove scene-related modals * Remove member/membership code * Remove all scenes-related items from notifications * Remove scene-related code from posts feed * Remove scene-related API helpers * Update tests --- __tests__/view/shell/mobile/Menu.test.tsx | 10 - public/img/scene-explainer.jpg | Bin 125195 -> 0 bytes src/state/lib/api.ts | 48 --- src/state/models/feed-view.ts | 10 +- src/state/models/me.ts | 13 - src/state/models/members-view.ts | 149 --------- src/state/models/memberships-view.ts | 127 -------- src/state/models/notifications-view.ts | 29 +- src/state/models/profile-ui.ts | 43 +-- src/state/models/profile-view.ts | 8 - src/state/models/shell-ui.ts | 18 - src/state/models/suggested-invites-view.ts | 142 -------- src/view/com/modals/CreateScene.tsx | 243 -------------- src/view/com/modals/InviteToScene.tsx | 308 ------------------ src/view/com/modals/Modal.tsx | 12 - src/view/com/notifications/FeedItem.tsx | 24 +- src/view/com/notifications/InviteAccepter.tsx | 96 ------ src/view/com/onboard/FeatureExplainer.tsx | 25 +- src/view/com/posts/FeedItem.tsx | 17 - src/view/com/profile/ProfileHeader.tsx | 143 +------- src/view/com/profile/ProfileMembers.tsx | 80 ----- src/view/index.ts | 2 - src/view/lib/assets.native.ts | 1 - src/view/lib/assets.ts | 3 - src/view/routes.ts | 2 - src/view/screens/Notifications.tsx | 1 - src/view/screens/Profile.tsx | 96 +----- src/view/screens/ProfileMembers.tsx | 25 -- src/view/shell/mobile/Menu.tsx | 57 +--- 29 files changed, 18 insertions(+), 1714 deletions(-) delete mode 100644 public/img/scene-explainer.jpg delete mode 100644 src/state/models/members-view.ts delete mode 100644 src/state/models/memberships-view.ts delete mode 100644 src/state/models/suggested-invites-view.ts delete mode 100644 src/view/com/modals/CreateScene.tsx delete mode 100644 src/view/com/modals/InviteToScene.tsx delete mode 100644 src/view/com/notifications/InviteAccepter.tsx delete mode 100644 src/view/com/profile/ProfileMembers.tsx delete mode 100644 src/view/screens/ProfileMembers.tsx 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 2478b0552d3892775d6d747cb553a617b21e4382..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 125195 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 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} - - - } - size="30" - /> - } - label="Create a scene" - onPress={onPressCreateScene} - />