Reorganize state models for clarity (#378)
parent
9652d994dd
commit
2045c615a8
|
@ -2,7 +2,7 @@ import {LikelyType, LinkMeta} from './link-meta'
|
||||||
// import {match as matchRoute} from 'view/routes'
|
// import {match as matchRoute} from 'view/routes'
|
||||||
import {convertBskyAppUrlIfNeeded, makeRecordUri} from '../strings/url-helpers'
|
import {convertBskyAppUrlIfNeeded, makeRecordUri} from '../strings/url-helpers'
|
||||||
import {RootStoreModel} from 'state/index'
|
import {RootStoreModel} from 'state/index'
|
||||||
import {PostThreadViewModel} from 'state/models/post-thread-view'
|
import {PostThreadModel} from 'state/models/content/post-thread'
|
||||||
import {ComposerOptsQuote} from 'state/models/ui/shell'
|
import {ComposerOptsQuote} from 'state/models/ui/shell'
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -108,7 +108,7 @@ export async function getPostAsQuote(
|
||||||
const [_0, user, _1, rkey] = url.split('/').filter(Boolean)
|
const [_0, user, _1, rkey] = url.split('/').filter(Boolean)
|
||||||
const threadUri = makeRecordUri(user, 'app.bsky.feed.post', rkey)
|
const threadUri = makeRecordUri(user, 'app.bsky.feed.post', rkey)
|
||||||
|
|
||||||
const threadView = new PostThreadViewModel(store, {
|
const threadView = new PostThreadModel(store, {
|
||||||
uri: threadUri,
|
uri: threadUri,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import notifee, {EventType} from '@notifee/react-native'
|
import notifee, {EventType} from '@notifee/react-native'
|
||||||
import {AppBskyEmbedImages} from '@atproto/api'
|
import {AppBskyEmbedImages} from '@atproto/api'
|
||||||
import {RootStoreModel} from 'state/models/root-store'
|
import {RootStoreModel} from 'state/models/root-store'
|
||||||
import {NotificationsViewItemModel} from 'state/models/notifications-view'
|
import {NotificationsFeedItemModel} from 'state/models/feeds/notifications'
|
||||||
import {enforceLen} from 'lib/strings/helpers'
|
import {enforceLen} from 'lib/strings/helpers'
|
||||||
import {resetToTab} from '../Navigation'
|
import {resetToTab} from '../Navigation'
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ export function displayNotification(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function displayNotificationFromModel(
|
export function displayNotificationFromModel(
|
||||||
notif: NotificationsViewItemModel,
|
notif: NotificationsFeedItemModel,
|
||||||
) {
|
) {
|
||||||
let author = notif.author.displayName || notif.author.handle
|
let author = notif.author.displayName || notif.author.handle
|
||||||
let title: string
|
let title: string
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import {makeAutoObservable} from 'mobx'
|
import {makeAutoObservable} from 'mobx'
|
||||||
import {LRUMap} from 'lru_map'
|
import {LRUMap} from 'lru_map'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {AppBskyActorGetProfile as GetProfile} from '@atproto/api'
|
import {AppBskyActorGetProfile as GetProfile} from '@atproto/api'
|
||||||
|
|
||||||
type CacheValue = Promise<GetProfile.Response> | GetProfile.Response
|
type CacheValue = Promise<GetProfile.Response> | GetProfile.Response
|
||||||
export class ProfilesViewModel {
|
export class ProfilesCache {
|
||||||
cache: LRUMap<string, CacheValue> = new LRUMap(100)
|
cache: LRUMap<string, CacheValue> = new LRUMap(100)
|
||||||
|
|
||||||
constructor(public rootStore: RootStoreModel) {
|
constructor(public rootStore: RootStoreModel) {
|
|
@ -5,8 +5,8 @@ import {
|
||||||
AppBskyFeedDefs,
|
AppBskyFeedDefs,
|
||||||
RichText,
|
RichText,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {AtUri} from '../../third-party/uri'
|
import {AtUri} from '../../../third-party/uri'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import * as apilib from 'lib/api/index'
|
import * as apilib from 'lib/api/index'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ function* reactKeyGenerator(): Generator<string> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PostThreadViewPostModel {
|
export class PostThreadItemModel {
|
||||||
// ui state
|
// ui state
|
||||||
_reactKey: string = ''
|
_reactKey: string = ''
|
||||||
_depth = 0
|
_depth = 0
|
||||||
|
@ -29,8 +29,8 @@ export class PostThreadViewPostModel {
|
||||||
// data
|
// data
|
||||||
post: AppBskyFeedDefs.PostView
|
post: AppBskyFeedDefs.PostView
|
||||||
postRecord?: FeedPost.Record
|
postRecord?: FeedPost.Record
|
||||||
parent?: PostThreadViewPostModel | AppBskyFeedDefs.NotFoundPost
|
parent?: PostThreadItemModel | AppBskyFeedDefs.NotFoundPost
|
||||||
replies?: (PostThreadViewPostModel | AppBskyFeedDefs.NotFoundPost)[]
|
replies?: (PostThreadItemModel | AppBskyFeedDefs.NotFoundPost)[]
|
||||||
richText?: RichText
|
richText?: RichText
|
||||||
|
|
||||||
get uri() {
|
get uri() {
|
||||||
|
@ -79,7 +79,7 @@ export class PostThreadViewPostModel {
|
||||||
// parents
|
// parents
|
||||||
if (includeParent && v.parent) {
|
if (includeParent && v.parent) {
|
||||||
if (AppBskyFeedDefs.isThreadViewPost(v.parent)) {
|
if (AppBskyFeedDefs.isThreadViewPost(v.parent)) {
|
||||||
const parentModel = new PostThreadViewPostModel(
|
const parentModel = new PostThreadItemModel(
|
||||||
this.rootStore,
|
this.rootStore,
|
||||||
keyGen.next().value,
|
keyGen.next().value,
|
||||||
v.parent,
|
v.parent,
|
||||||
|
@ -106,7 +106,7 @@ export class PostThreadViewPostModel {
|
||||||
const replies = []
|
const replies = []
|
||||||
for (const item of v.replies) {
|
for (const item of v.replies) {
|
||||||
if (AppBskyFeedDefs.isThreadViewPost(item)) {
|
if (AppBskyFeedDefs.isThreadViewPost(item)) {
|
||||||
const itemModel = new PostThreadViewPostModel(
|
const itemModel = new PostThreadItemModel(
|
||||||
this.rootStore,
|
this.rootStore,
|
||||||
keyGen.next().value,
|
keyGen.next().value,
|
||||||
item,
|
item,
|
||||||
|
@ -182,7 +182,7 @@ export class PostThreadViewPostModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PostThreadViewModel {
|
export class PostThreadModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
|
@ -193,7 +193,7 @@ export class PostThreadViewModel {
|
||||||
params: GetPostThread.QueryParams
|
params: GetPostThread.QueryParams
|
||||||
|
|
||||||
// data
|
// data
|
||||||
thread?: PostThreadViewPostModel
|
thread?: PostThreadItemModel
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public rootStore: RootStoreModel,
|
public rootStore: RootStoreModel,
|
||||||
|
@ -321,7 +321,7 @@ export class PostThreadViewModel {
|
||||||
_replaceAll(res: GetPostThread.Response) {
|
_replaceAll(res: GetPostThread.Response) {
|
||||||
sortThread(res.data.thread)
|
sortThread(res.data.thread)
|
||||||
const keyGen = reactKeyGenerator()
|
const keyGen = reactKeyGenerator()
|
||||||
const thread = new PostThreadViewPostModel(
|
const thread = new PostThreadItemModel(
|
||||||
this.rootStore,
|
this.rootStore,
|
||||||
keyGen.next().value,
|
keyGen.next().value,
|
||||||
res.data.thread as AppBskyFeedDefs.ThreadViewPost,
|
res.data.thread as AppBskyFeedDefs.ThreadViewPost,
|
|
@ -1,7 +1,7 @@
|
||||||
import {makeAutoObservable} from 'mobx'
|
import {makeAutoObservable} from 'mobx'
|
||||||
import {AppBskyFeedPost as Post} from '@atproto/api'
|
import {AppBskyFeedPost as Post} from '@atproto/api'
|
||||||
import {AtUri} from '../../third-party/uri'
|
import {AtUri} from '../../../third-party/uri'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
|
|
||||||
type RemoveIndex<T> = {
|
type RemoveIndex<T> = {
|
|
@ -5,13 +5,13 @@ import {
|
||||||
AppBskyActorProfile,
|
AppBskyActorProfile,
|
||||||
RichText,
|
RichText,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import * as apilib from 'lib/api/index'
|
import * as apilib from 'lib/api/index'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
|
|
||||||
export const ACTOR_TYPE_USER = 'app.bsky.system.actorUser'
|
export const ACTOR_TYPE_USER = 'app.bsky.system.actorUser'
|
||||||
|
|
||||||
export class ProfileViewViewerModel {
|
export class ProfileViewerModel {
|
||||||
muted?: boolean
|
muted?: boolean
|
||||||
following?: string
|
following?: string
|
||||||
followedBy?: string
|
followedBy?: string
|
||||||
|
@ -21,7 +21,7 @@ export class ProfileViewViewerModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ProfileViewModel {
|
export class ProfileModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
|
@ -40,7 +40,7 @@ export class ProfileViewModel {
|
||||||
followersCount: number = 0
|
followersCount: number = 0
|
||||||
followsCount: number = 0
|
followsCount: number = 0
|
||||||
postsCount: number = 0
|
postsCount: number = 0
|
||||||
viewer = new ProfileViewViewerModel()
|
viewer = new ProfileViewerModel()
|
||||||
|
|
||||||
// added data
|
// added data
|
||||||
descriptionRichText?: RichText = new RichText({text: ''})
|
descriptionRichText?: RichText = new RichText({text: ''})
|
|
@ -1,6 +1,6 @@
|
||||||
import {makeAutoObservable, runInAction} from 'mobx'
|
import {makeAutoObservable, runInAction} from 'mobx'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {FeedItemModel} from './feed-view'
|
import {PostsFeedItemModel} from '../feeds/posts'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
import {TEAM_HANDLES} from 'lib/constants'
|
import {TEAM_HANDLES} from 'lib/constants'
|
||||||
import {
|
import {
|
||||||
|
@ -8,14 +8,14 @@ import {
|
||||||
mergePosts,
|
mergePosts,
|
||||||
} from 'lib/api/build-suggested-posts'
|
} from 'lib/api/build-suggested-posts'
|
||||||
|
|
||||||
export class SuggestedPostsView {
|
export class SuggestedPostsModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
hasLoaded = false
|
hasLoaded = false
|
||||||
error = ''
|
error = ''
|
||||||
|
|
||||||
// data
|
// data
|
||||||
posts: FeedItemModel[] = []
|
posts: PostsFeedItemModel[] = []
|
||||||
|
|
||||||
constructor(public rootStore: RootStoreModel) {
|
constructor(public rootStore: RootStoreModel) {
|
||||||
makeAutoObservable(
|
makeAutoObservable(
|
||||||
|
@ -57,7 +57,7 @@ export class SuggestedPostsView {
|
||||||
this.posts = finalPosts.map((post, i) => {
|
this.posts = finalPosts.map((post, i) => {
|
||||||
// strip the reasons to hide that these are reposts
|
// strip the reasons to hide that these are reposts
|
||||||
delete post.reason
|
delete post.reason
|
||||||
return new FeedItemModel(this.rootStore, `post-${i}`, post)
|
return new PostsFeedItemModel(this.rootStore, `post-${i}`, post)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
this._xIdle()
|
this._xIdle()
|
|
@ -1,9 +1,9 @@
|
||||||
import {makeAutoObservable, runInAction} from 'mobx'
|
import {makeAutoObservable, runInAction} from 'mobx'
|
||||||
import {AppBskyActorDefs} from '@atproto/api'
|
import {AppBskyActorDefs} from '@atproto/api'
|
||||||
import AwaitLock from 'await-lock'
|
import AwaitLock from 'await-lock'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
|
|
||||||
export class UserAutocompleteViewModel {
|
export class UserAutocompleteModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isActive = false
|
isActive = false
|
|
@ -9,8 +9,8 @@ import {
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import AwaitLock from 'await-lock'
|
import AwaitLock from 'await-lock'
|
||||||
import {bundleAsync} from 'lib/async/bundle'
|
import {bundleAsync} from 'lib/async/bundle'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {PostThreadViewModel} from './post-thread-view'
|
import {PostThreadModel} from '../content/post-thread'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
|
|
||||||
const GROUPABLE_REASONS = ['like', 'repost', 'follow']
|
const GROUPABLE_REASONS = ['like', 'repost', 'follow']
|
||||||
|
@ -30,7 +30,7 @@ type SupportedRecord =
|
||||||
| AppBskyFeedLike.Record
|
| AppBskyFeedLike.Record
|
||||||
| AppBskyGraphFollow.Record
|
| AppBskyGraphFollow.Record
|
||||||
|
|
||||||
export class NotificationsViewItemModel {
|
export class NotificationsFeedItemModel {
|
||||||
// ui state
|
// ui state
|
||||||
_reactKey: string = ''
|
_reactKey: string = ''
|
||||||
|
|
||||||
|
@ -47,10 +47,10 @@ export class NotificationsViewItemModel {
|
||||||
record?: SupportedRecord
|
record?: SupportedRecord
|
||||||
isRead: boolean = false
|
isRead: boolean = false
|
||||||
indexedAt: string = ''
|
indexedAt: string = ''
|
||||||
additional?: NotificationsViewItemModel[]
|
additional?: NotificationsFeedItemModel[]
|
||||||
|
|
||||||
// additional data
|
// additional data
|
||||||
additionalPost?: PostThreadViewModel
|
additionalPost?: PostThreadModel
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public rootStore: RootStoreModel,
|
public rootStore: RootStoreModel,
|
||||||
|
@ -75,7 +75,7 @@ export class NotificationsViewItemModel {
|
||||||
this.additional = []
|
this.additional = []
|
||||||
for (const add of v.additional) {
|
for (const add of v.additional) {
|
||||||
this.additional.push(
|
this.additional.push(
|
||||||
new NotificationsViewItemModel(this.rootStore, '', add),
|
new NotificationsFeedItemModel(this.rootStore, '', add),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (!preserve) {
|
} else if (!preserve) {
|
||||||
|
@ -171,7 +171,7 @@ export class NotificationsViewItemModel {
|
||||||
postUri = this.subjectUri
|
postUri = this.subjectUri
|
||||||
}
|
}
|
||||||
if (postUri) {
|
if (postUri) {
|
||||||
this.additionalPost = new PostThreadViewModel(this.rootStore, {
|
this.additionalPost = new PostThreadModel(this.rootStore, {
|
||||||
uri: postUri,
|
uri: postUri,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
})
|
})
|
||||||
|
@ -185,7 +185,7 @@ export class NotificationsViewItemModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NotificationsViewModel {
|
export class NotificationsFeedModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
|
@ -199,7 +199,7 @@ export class NotificationsViewModel {
|
||||||
lock = new AwaitLock()
|
lock = new AwaitLock()
|
||||||
|
|
||||||
// data
|
// data
|
||||||
notifications: NotificationsViewItemModel[] = []
|
notifications: NotificationsFeedItemModel[] = []
|
||||||
unreadCount = 0
|
unreadCount = 0
|
||||||
|
|
||||||
// this is used to help trigger push notifications
|
// this is used to help trigger push notifications
|
||||||
|
@ -416,7 +416,7 @@ export class NotificationsViewModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getNewMostRecent(): Promise<NotificationsViewItemModel | undefined> {
|
async getNewMostRecent(): Promise<NotificationsFeedItemModel | undefined> {
|
||||||
let old = this.mostRecentNotificationUri
|
let old = this.mostRecentNotificationUri
|
||||||
const res = await this.rootStore.agent.listNotifications({
|
const res = await this.rootStore.agent.listNotifications({
|
||||||
limit: 1,
|
limit: 1,
|
||||||
|
@ -425,7 +425,7 @@ export class NotificationsViewModel {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.mostRecentNotificationUri = res.data.notifications[0].uri
|
this.mostRecentNotificationUri = res.data.notifications[0].uri
|
||||||
const notif = new NotificationsViewItemModel(
|
const notif = new NotificationsFeedItemModel(
|
||||||
this.rootStore,
|
this.rootStore,
|
||||||
'mostRecent',
|
'mostRecent',
|
||||||
res.data.notifications[0],
|
res.data.notifications[0],
|
||||||
|
@ -467,9 +467,9 @@ export class NotificationsViewModel {
|
||||||
this.loadMoreCursor = res.data.cursor
|
this.loadMoreCursor = res.data.cursor
|
||||||
this.hasMore = !!this.loadMoreCursor
|
this.hasMore = !!this.loadMoreCursor
|
||||||
const promises = []
|
const promises = []
|
||||||
const itemModels: NotificationsViewItemModel[] = []
|
const itemModels: NotificationsFeedItemModel[] = []
|
||||||
for (const item of groupNotifications(res.data.notifications)) {
|
for (const item of groupNotifications(res.data.notifications)) {
|
||||||
const itemModel = new NotificationsViewItemModel(
|
const itemModel = new NotificationsFeedItemModel(
|
||||||
this.rootStore,
|
this.rootStore,
|
||||||
`item-${_idCounter++}`,
|
`item-${_idCounter++}`,
|
||||||
item,
|
item,
|
||||||
|
@ -496,7 +496,7 @@ export class NotificationsViewModel {
|
||||||
|
|
||||||
async _prependAll(res: ListNotifications.Response) {
|
async _prependAll(res: ListNotifications.Response) {
|
||||||
const promises = []
|
const promises = []
|
||||||
const itemModels: NotificationsViewItemModel[] = []
|
const itemModels: NotificationsFeedItemModel[] = []
|
||||||
const dedupedNotifs = res.data.notifications.filter(
|
const dedupedNotifs = res.data.notifications.filter(
|
||||||
n1 =>
|
n1 =>
|
||||||
!this.notifications.find(
|
!this.notifications.find(
|
||||||
|
@ -504,7 +504,7 @@ export class NotificationsViewModel {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
for (const item of groupNotifications(dedupedNotifs)) {
|
for (const item of groupNotifications(dedupedNotifs)) {
|
||||||
const itemModel = new NotificationsViewItemModel(
|
const itemModel = new NotificationsFeedItemModel(
|
||||||
this.rootStore,
|
this.rootStore,
|
||||||
`item-${_idCounter++}`,
|
`item-${_idCounter++}`,
|
||||||
item,
|
item,
|
||||||
|
@ -565,7 +565,7 @@ function groupNotifications(
|
||||||
return items2
|
return items2
|
||||||
}
|
}
|
||||||
|
|
||||||
type N = ListNotifications.Notification | NotificationsViewItemModel
|
type N = ListNotifications.Notification | NotificationsFeedItemModel
|
||||||
function isEq(a: N, b: N) {
|
function isEq(a: N, b: N) {
|
||||||
// this function has a key subtlety- the indexedAt comparison
|
// this function has a key subtlety- the indexedAt comparison
|
||||||
// the reason for this is reposts: they set the URI of the original post, not of the repost record
|
// the reason for this is reposts: they set the URI of the original post, not of the repost record
|
|
@ -10,7 +10,7 @@ import {
|
||||||
import AwaitLock from 'await-lock'
|
import AwaitLock from 'await-lock'
|
||||||
import {bundleAsync} from 'lib/async/bundle'
|
import {bundleAsync} from 'lib/async/bundle'
|
||||||
import sampleSize from 'lodash.samplesize'
|
import sampleSize from 'lodash.samplesize'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
import {SUGGESTED_FOLLOWS} from 'lib/constants'
|
import {SUGGESTED_FOLLOWS} from 'lib/constants'
|
||||||
import {
|
import {
|
||||||
|
@ -27,7 +27,7 @@ type PostView = AppBskyFeedDefs.PostView
|
||||||
const PAGE_SIZE = 30
|
const PAGE_SIZE = 30
|
||||||
let _idCounter = 0
|
let _idCounter = 0
|
||||||
|
|
||||||
export class FeedItemModel {
|
export class PostsFeedItemModel {
|
||||||
// ui state
|
// ui state
|
||||||
_reactKey: string = ''
|
_reactKey: string = ''
|
||||||
|
|
||||||
|
@ -139,12 +139,12 @@ export class FeedItemModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FeedSliceModel {
|
export class PostsFeedSliceModel {
|
||||||
// ui state
|
// ui state
|
||||||
_reactKey: string = ''
|
_reactKey: string = ''
|
||||||
|
|
||||||
// data
|
// data
|
||||||
items: FeedItemModel[] = []
|
items: PostsFeedItemModel[] = []
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public rootStore: RootStoreModel,
|
public rootStore: RootStoreModel,
|
||||||
|
@ -154,7 +154,7 @@ export class FeedSliceModel {
|
||||||
this._reactKey = reactKey
|
this._reactKey = reactKey
|
||||||
for (const item of slice.items) {
|
for (const item of slice.items) {
|
||||||
this.items.push(
|
this.items.push(
|
||||||
new FeedItemModel(rootStore, `item-${_idCounter++}`, item),
|
new PostsFeedItemModel(rootStore, `item-${_idCounter++}`, item),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
makeAutoObservable(this, {rootStore: false})
|
makeAutoObservable(this, {rootStore: false})
|
||||||
|
@ -206,7 +206,7 @@ export class FeedSliceModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FeedModel {
|
export class PostsFeedModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
|
@ -223,8 +223,8 @@ export class FeedModel {
|
||||||
lock = new AwaitLock()
|
lock = new AwaitLock()
|
||||||
|
|
||||||
// data
|
// data
|
||||||
slices: FeedSliceModel[] = []
|
slices: PostsFeedSliceModel[] = []
|
||||||
nextSlices: FeedSliceModel[] = []
|
nextSlices: PostsFeedSliceModel[] = []
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public rootStore: RootStoreModel,
|
public rootStore: RootStoreModel,
|
||||||
|
@ -445,7 +445,11 @@ export class FeedModel {
|
||||||
if (nextSlices[0]?.uri !== this.slices[0]?.uri) {
|
if (nextSlices[0]?.uri !== this.slices[0]?.uri) {
|
||||||
const nextSlicesModels = nextSlices.map(
|
const nextSlicesModels = nextSlices.map(
|
||||||
slice =>
|
slice =>
|
||||||
new FeedSliceModel(this.rootStore, `item-${_idCounter++}`, slice),
|
new PostsFeedSliceModel(
|
||||||
|
this.rootStore,
|
||||||
|
`item-${_idCounter++}`,
|
||||||
|
slice,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
if (autoPrepend) {
|
if (autoPrepend) {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
|
@ -526,9 +530,9 @@ export class FeedModel {
|
||||||
|
|
||||||
const slices = this.tuner.tune(res.data.feed, this.feedTuners)
|
const slices = this.tuner.tune(res.data.feed, this.feedTuners)
|
||||||
|
|
||||||
const toAppend: FeedSliceModel[] = []
|
const toAppend: PostsFeedSliceModel[] = []
|
||||||
for (const slice of slices) {
|
for (const slice of slices) {
|
||||||
const sliceModel = new FeedSliceModel(
|
const sliceModel = new PostsFeedSliceModel(
|
||||||
this.rootStore,
|
this.rootStore,
|
||||||
`item-${_idCounter++}`,
|
`item-${_idCounter++}`,
|
||||||
slice,
|
slice,
|
|
@ -1,7 +1,7 @@
|
||||||
import {makeAutoObservable, runInAction} from 'mobx'
|
import {makeAutoObservable, runInAction} from 'mobx'
|
||||||
import {AtUri} from '../../third-party/uri'
|
import {AtUri} from '../../../third-party/uri'
|
||||||
import {AppBskyFeedGetLikes as GetLikes} from '@atproto/api'
|
import {AppBskyFeedGetLikes as GetLikes} from '@atproto/api'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
import {bundleAsync} from 'lib/async/bundle'
|
import {bundleAsync} from 'lib/async/bundle'
|
||||||
import * as apilib from 'lib/api/index'
|
import * as apilib from 'lib/api/index'
|
||||||
|
@ -10,7 +10,7 @@ const PAGE_SIZE = 30
|
||||||
|
|
||||||
export type LikeItem = GetLikes.Like
|
export type LikeItem = GetLikes.Like
|
||||||
|
|
||||||
export class LikesViewModel {
|
export class LikesModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isRefreshing = false
|
isRefreshing = false
|
|
@ -1,10 +1,10 @@
|
||||||
import {makeAutoObservable, runInAction} from 'mobx'
|
import {makeAutoObservable, runInAction} from 'mobx'
|
||||||
import {AtUri} from '../../third-party/uri'
|
import {AtUri} from '../../../third-party/uri'
|
||||||
import {
|
import {
|
||||||
AppBskyFeedGetRepostedBy as GetRepostedBy,
|
AppBskyFeedGetRepostedBy as GetRepostedBy,
|
||||||
AppBskyActorDefs,
|
AppBskyActorDefs,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {bundleAsync} from 'lib/async/bundle'
|
import {bundleAsync} from 'lib/async/bundle'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
import * as apilib from 'lib/api/index'
|
import * as apilib from 'lib/api/index'
|
||||||
|
@ -13,7 +13,7 @@ const PAGE_SIZE = 30
|
||||||
|
|
||||||
export type RepostedByItem = AppBskyActorDefs.ProfileViewBasic
|
export type RepostedByItem = AppBskyActorDefs.ProfileViewBasic
|
||||||
|
|
||||||
export class RepostedByViewModel {
|
export class RepostedByModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isRefreshing = false
|
isRefreshing = false
|
|
@ -3,7 +3,7 @@ import {
|
||||||
AppBskyGraphGetFollowers as GetFollowers,
|
AppBskyGraphGetFollowers as GetFollowers,
|
||||||
AppBskyActorDefs as ActorDefs,
|
AppBskyActorDefs as ActorDefs,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
import {bundleAsync} from 'lib/async/bundle'
|
import {bundleAsync} from 'lib/async/bundle'
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ const PAGE_SIZE = 30
|
||||||
|
|
||||||
export type FollowerItem = ActorDefs.ProfileViewBasic
|
export type FollowerItem = ActorDefs.ProfileViewBasic
|
||||||
|
|
||||||
export class UserFollowersViewModel {
|
export class UserFollowersModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isRefreshing = false
|
isRefreshing = false
|
|
@ -3,7 +3,7 @@ import {
|
||||||
AppBskyGraphGetFollows as GetFollows,
|
AppBskyGraphGetFollows as GetFollows,
|
||||||
AppBskyActorDefs as ActorDefs,
|
AppBskyActorDefs as ActorDefs,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {cleanError} from 'lib/strings/errors'
|
import {cleanError} from 'lib/strings/errors'
|
||||||
import {bundleAsync} from 'lib/async/bundle'
|
import {bundleAsync} from 'lib/async/bundle'
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ const PAGE_SIZE = 30
|
||||||
|
|
||||||
export type FollowItem = ActorDefs.ProfileViewBasic
|
export type FollowItem = ActorDefs.ProfileViewBasic
|
||||||
|
|
||||||
export class UserFollowsViewModel {
|
export class UserFollowsModel {
|
||||||
// state
|
// state
|
||||||
isLoading = false
|
isLoading = false
|
||||||
isRefreshing = false
|
isRefreshing = false
|
|
@ -1,7 +1,7 @@
|
||||||
import {makeAutoObservable, runInAction} from 'mobx'
|
import {makeAutoObservable, runInAction} from 'mobx'
|
||||||
import {RootStoreModel} from './root-store'
|
import {RootStoreModel} from './root-store'
|
||||||
import {FeedModel} from './feed-view'
|
import {PostsFeedModel} from './feeds/posts'
|
||||||
import {NotificationsViewModel} from './notifications-view'
|
import {NotificationsFeedModel} from './feeds/notifications'
|
||||||
import {MyFollowsCache} from './cache/my-follows'
|
import {MyFollowsCache} from './cache/my-follows'
|
||||||
import {isObj, hasProp} from 'lib/type-guards'
|
import {isObj, hasProp} from 'lib/type-guards'
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ export class MeModel {
|
||||||
avatar: string = ''
|
avatar: string = ''
|
||||||
followsCount: number | undefined
|
followsCount: number | undefined
|
||||||
followersCount: number | undefined
|
followersCount: number | undefined
|
||||||
mainFeed: FeedModel
|
mainFeed: PostsFeedModel
|
||||||
notifications: NotificationsViewModel
|
notifications: NotificationsFeedModel
|
||||||
follows: MyFollowsCache
|
follows: MyFollowsCache
|
||||||
|
|
||||||
constructor(public rootStore: RootStoreModel) {
|
constructor(public rootStore: RootStoreModel) {
|
||||||
|
@ -23,10 +23,10 @@ export class MeModel {
|
||||||
{rootStore: false, serialize: false, hydrate: false},
|
{rootStore: false, serialize: false, hydrate: false},
|
||||||
{autoBind: true},
|
{autoBind: true},
|
||||||
)
|
)
|
||||||
this.mainFeed = new FeedModel(this.rootStore, 'home', {
|
this.mainFeed = new PostsFeedModel(this.rootStore, 'home', {
|
||||||
algorithm: 'reverse-chronological',
|
algorithm: 'reverse-chronological',
|
||||||
})
|
})
|
||||||
this.notifications = new NotificationsViewModel(this.rootStore, {})
|
this.notifications = new NotificationsFeedModel(this.rootStore, {})
|
||||||
this.follows = new MyFollowsCache(this.rootStore)
|
this.follows = new MyFollowsCache(this.rootStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@ import {isObj, hasProp} from 'lib/type-guards'
|
||||||
import {LogModel} from './log'
|
import {LogModel} from './log'
|
||||||
import {SessionModel} from './session'
|
import {SessionModel} from './session'
|
||||||
import {ShellUiModel} from './ui/shell'
|
import {ShellUiModel} from './ui/shell'
|
||||||
import {ProfilesViewModel} from './profiles-view'
|
import {ProfilesCache} from './cache/profiles-view'
|
||||||
import {LinkMetasCache} from './cache/link-metas'
|
import {LinkMetasCache} from './cache/link-metas'
|
||||||
import {NotificationsViewItemModel} from './notifications-view'
|
import {NotificationsFeedItemModel} from './feeds/notifications'
|
||||||
import {MeModel} from './me'
|
import {MeModel} from './me'
|
||||||
import {PreferencesModel} from './ui/preferences'
|
import {PreferencesModel} from './ui/preferences'
|
||||||
import {resetToTab} from '../../Navigation'
|
import {resetToTab} from '../../Navigation'
|
||||||
|
@ -36,7 +36,7 @@ export class RootStoreModel {
|
||||||
shell = new ShellUiModel(this)
|
shell = new ShellUiModel(this)
|
||||||
preferences = new PreferencesModel()
|
preferences = new PreferencesModel()
|
||||||
me = new MeModel(this)
|
me = new MeModel(this)
|
||||||
profiles = new ProfilesViewModel(this)
|
profiles = new ProfilesCache(this)
|
||||||
linkMetas = new LinkMetasCache(this)
|
linkMetas = new LinkMetasCache(this)
|
||||||
imageSizes = new ImageSizesCache()
|
imageSizes = new ImageSizesCache()
|
||||||
|
|
||||||
|
@ -205,11 +205,11 @@ export class RootStoreModel {
|
||||||
|
|
||||||
// a notification has been queued for push
|
// a notification has been queued for push
|
||||||
onPushNotification(
|
onPushNotification(
|
||||||
handler: (notif: NotificationsViewItemModel) => void,
|
handler: (notif: NotificationsFeedItemModel) => void,
|
||||||
): EmitterSubscription {
|
): EmitterSubscription {
|
||||||
return DeviceEventEmitter.addListener('push-notification', handler)
|
return DeviceEventEmitter.addListener('push-notification', handler)
|
||||||
}
|
}
|
||||||
emitPushNotification(notif: NotificationsViewItemModel) {
|
emitPushNotification(notif: NotificationsFeedItemModel) {
|
||||||
DeviceEventEmitter.emit('push-notification', notif)
|
DeviceEventEmitter.emit('push-notification', notif)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {makeAutoObservable} from 'mobx'
|
import {makeAutoObservable} from 'mobx'
|
||||||
import {RootStoreModel} from '../root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {ProfileViewModel} from '../profile-view'
|
import {ProfileModel} from '../content/profile'
|
||||||
import {FeedModel} from '../feed-view'
|
import {PostsFeedModel} from '../feeds/posts'
|
||||||
|
|
||||||
export enum Sections {
|
export enum Sections {
|
||||||
Posts = 'Posts',
|
Posts = 'Posts',
|
||||||
|
@ -20,8 +20,8 @@ export class ProfileUiModel {
|
||||||
static EMPTY_ITEM = {_reactKey: '__empty__'}
|
static EMPTY_ITEM = {_reactKey: '__empty__'}
|
||||||
|
|
||||||
// data
|
// data
|
||||||
profile: ProfileViewModel
|
profile: ProfileModel
|
||||||
feed: FeedModel
|
feed: PostsFeedModel
|
||||||
|
|
||||||
// ui state
|
// ui state
|
||||||
selectedViewIndex = 0
|
selectedViewIndex = 0
|
||||||
|
@ -38,14 +38,14 @@ export class ProfileUiModel {
|
||||||
},
|
},
|
||||||
{autoBind: true},
|
{autoBind: true},
|
||||||
)
|
)
|
||||||
this.profile = new ProfileViewModel(rootStore, {actor: params.user})
|
this.profile = new ProfileModel(rootStore, {actor: params.user})
|
||||||
this.feed = new FeedModel(rootStore, 'author', {
|
this.feed = new PostsFeedModel(rootStore, 'author', {
|
||||||
actor: params.user,
|
actor: params.user,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentView(): FeedModel {
|
get currentView(): PostsFeedModel {
|
||||||
if (
|
if (
|
||||||
this.selectedView === Sections.Posts ||
|
this.selectedView === Sections.Posts ||
|
||||||
this.selectedView === Sections.PostsWithReplies
|
this.selectedView === Sections.PostsWithReplies
|
||||||
|
@ -137,7 +137,7 @@ export class ProfileUiModel {
|
||||||
|
|
||||||
async update() {
|
async update() {
|
||||||
const view = this.currentView
|
const view = this.currentView
|
||||||
if (view instanceof FeedModel) {
|
if (view instanceof PostsFeedModel) {
|
||||||
await view.update()
|
await view.update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {AppBskyEmbedRecord} from '@atproto/api'
|
import {AppBskyEmbedRecord} from '@atproto/api'
|
||||||
import {RootStoreModel} from '../root-store'
|
import {RootStoreModel} from '../root-store'
|
||||||
import {makeAutoObservable} from 'mobx'
|
import {makeAutoObservable} from 'mobx'
|
||||||
import {ProfileViewModel} from '../profile-view'
|
import {ProfileModel} from '../content/profile'
|
||||||
import {isObj, hasProp} from 'lib/type-guards'
|
import {isObj, hasProp} from 'lib/type-guards'
|
||||||
import {PickedMedia} from 'lib/media/types'
|
import {PickedMedia} from 'lib/media/types'
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ export interface ConfirmModal {
|
||||||
|
|
||||||
export interface EditProfileModal {
|
export interface EditProfileModal {
|
||||||
name: 'edit-profile'
|
name: 'edit-profile'
|
||||||
profileView: ProfileViewModel
|
profileView: ProfileModel
|
||||||
onUpdate?: () => void
|
onUpdate?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ interface LightboxModel {}
|
||||||
|
|
||||||
export class ProfileImageLightbox implements LightboxModel {
|
export class ProfileImageLightbox implements LightboxModel {
|
||||||
name = 'profile-image'
|
name = 'profile-image'
|
||||||
constructor(public profileView: ProfileViewModel) {
|
constructor(public profileView: ProfileModel) {
|
||||||
makeAutoObservable(this)
|
makeAutoObservable(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import LinearGradient from 'react-native-linear-gradient'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
import {RichText} from '@atproto/api'
|
import {RichText} from '@atproto/api'
|
||||||
import {useAnalytics} from 'lib/analytics'
|
import {useAnalytics} from 'lib/analytics'
|
||||||
import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view'
|
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||||
import {ExternalEmbed} from './ExternalEmbed'
|
import {ExternalEmbed} from './ExternalEmbed'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
import * as Toast from '../util/Toast'
|
import * as Toast from '../util/Toast'
|
||||||
|
@ -69,8 +69,8 @@ export const ComposePost = observer(function ComposePost({
|
||||||
)
|
)
|
||||||
const [selectedPhotos, setSelectedPhotos] = React.useState<string[]>([])
|
const [selectedPhotos, setSelectedPhotos] = React.useState<string[]>([])
|
||||||
|
|
||||||
const autocompleteView = React.useMemo<UserAutocompleteViewModel>(
|
const autocompleteView = React.useMemo<UserAutocompleteModel>(
|
||||||
() => new UserAutocompleteViewModel(store),
|
() => new UserAutocompleteModel(store),
|
||||||
[store],
|
[store],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import PasteInput, {
|
||||||
} from '@mattermost/react-native-paste-input'
|
} from '@mattermost/react-native-paste-input'
|
||||||
import {AppBskyRichtextFacet, RichText} from '@atproto/api'
|
import {AppBskyRichtextFacet, RichText} from '@atproto/api'
|
||||||
import isEqual from 'lodash.isequal'
|
import isEqual from 'lodash.isequal'
|
||||||
import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view'
|
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||||
import {Autocomplete} from './mobile/Autocomplete'
|
import {Autocomplete} from './mobile/Autocomplete'
|
||||||
import {Text} from 'view/com/util/text/Text'
|
import {Text} from 'view/com/util/text/Text'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
|
@ -36,7 +36,7 @@ interface TextInputProps {
|
||||||
richtext: RichText
|
richtext: RichText
|
||||||
placeholder: string
|
placeholder: string
|
||||||
suggestedLinks: Set<string>
|
suggestedLinks: Set<string>
|
||||||
autocompleteView: UserAutocompleteViewModel
|
autocompleteView: UserAutocompleteModel
|
||||||
setRichText: (v: RichText) => void
|
setRichText: (v: RichText) => void
|
||||||
onPhotoPasted: (uri: string) => void
|
onPhotoPasted: (uri: string) => void
|
||||||
onSuggestedLinksChanged: (uris: Set<string>) => void
|
onSuggestedLinksChanged: (uris: Set<string>) => void
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {Paragraph} from '@tiptap/extension-paragraph'
|
||||||
import {Placeholder} from '@tiptap/extension-placeholder'
|
import {Placeholder} from '@tiptap/extension-placeholder'
|
||||||
import {Text} from '@tiptap/extension-text'
|
import {Text} from '@tiptap/extension-text'
|
||||||
import isEqual from 'lodash.isequal'
|
import isEqual from 'lodash.isequal'
|
||||||
import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view'
|
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||||
import {createSuggestion} from './web/Autocomplete'
|
import {createSuggestion} from './web/Autocomplete'
|
||||||
|
|
||||||
export interface TextInputRef {
|
export interface TextInputRef {
|
||||||
|
@ -21,7 +21,7 @@ interface TextInputProps {
|
||||||
richtext: RichText
|
richtext: RichText
|
||||||
placeholder: string
|
placeholder: string
|
||||||
suggestedLinks: Set<string>
|
suggestedLinks: Set<string>
|
||||||
autocompleteView: UserAutocompleteViewModel
|
autocompleteView: UserAutocompleteModel
|
||||||
setRichText: (v: RichText) => void
|
setRichText: (v: RichText) => void
|
||||||
onPhotoPasted: (uri: string) => void
|
onPhotoPasted: (uri: string) => void
|
||||||
onSuggestedLinksChanged: (uris: Set<string>) => void
|
onSuggestedLinksChanged: (uris: Set<string>) => void
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React, {useEffect} from 'react'
|
import React, {useEffect} from 'react'
|
||||||
import {Animated, TouchableOpacity, StyleSheet, View} from 'react-native'
|
import {Animated, TouchableOpacity, StyleSheet, View} from 'react-native'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view'
|
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||||
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
|
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
import {Text} from 'view/com/util/text/Text'
|
import {Text} from 'view/com/util/text/Text'
|
||||||
|
@ -11,7 +11,7 @@ export const Autocomplete = observer(
|
||||||
view,
|
view,
|
||||||
onSelect,
|
onSelect,
|
||||||
}: {
|
}: {
|
||||||
view: UserAutocompleteViewModel
|
view: UserAutocompleteModel
|
||||||
onSelect: (item: string) => void
|
onSelect: (item: string) => void
|
||||||
}) => {
|
}) => {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
SuggestionProps,
|
SuggestionProps,
|
||||||
SuggestionKeyDownProps,
|
SuggestionKeyDownProps,
|
||||||
} from '@tiptap/suggestion'
|
} from '@tiptap/suggestion'
|
||||||
import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view'
|
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||||
|
|
||||||
interface MentionListRef {
|
interface MentionListRef {
|
||||||
onKeyDown: (props: SuggestionKeyDownProps) => boolean
|
onKeyDown: (props: SuggestionKeyDownProps) => boolean
|
||||||
|
@ -20,7 +20,7 @@ interface MentionListRef {
|
||||||
export function createSuggestion({
|
export function createSuggestion({
|
||||||
autocompleteView,
|
autocompleteView,
|
||||||
}: {
|
}: {
|
||||||
autocompleteView: UserAutocompleteViewModel
|
autocompleteView: UserAutocompleteModel
|
||||||
}): Omit<SuggestionOptions, 'editor'> {
|
}): Omit<SuggestionOptions, 'editor'> {
|
||||||
return {
|
return {
|
||||||
async items({query}) {
|
async items({query}) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||||
import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, StyleSheet, View} from 'react-native'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {SuggestedPostsView} from 'state/models/suggested-posts-view'
|
import {SuggestedPostsModel} from 'state/models/discovery/suggested-posts'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import {FeedItem as Post} from '../posts/FeedItem'
|
import {FeedItem as Post} from '../posts/FeedItem'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
|
@ -11,8 +11,8 @@ import {usePalette} from 'lib/hooks/usePalette'
|
||||||
export const SuggestedPosts = observer(() => {
|
export const SuggestedPosts = observer(() => {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const suggestedPostsView = React.useMemo<SuggestedPostsView>(
|
const suggestedPostsView = React.useMemo<SuggestedPostsModel>(
|
||||||
() => new SuggestedPostsView(store),
|
() => new SuggestedPostsModel(store),
|
||||||
[store],
|
[store],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {PickedMedia} from '../../../lib/media/picker'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {ProfileViewModel} from 'state/models/profile-view'
|
import {ProfileModel} from 'state/models/content/profile'
|
||||||
import {s, colors, gradients} from 'lib/styles'
|
import {s, colors, gradients} from 'lib/styles'
|
||||||
import {enforceLen} from 'lib/strings/helpers'
|
import {enforceLen} from 'lib/strings/helpers'
|
||||||
import {MAX_DISPLAY_NAME, MAX_DESCRIPTION} from 'lib/constants'
|
import {MAX_DISPLAY_NAME, MAX_DESCRIPTION} from 'lib/constants'
|
||||||
|
@ -30,7 +30,7 @@ export function Component({
|
||||||
profileView,
|
profileView,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
}: {
|
}: {
|
||||||
profileView: ProfileViewModel
|
profileView: ProfileModel
|
||||||
onUpdate?: () => void
|
onUpdate?: () => void
|
||||||
}) {
|
}) {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, {MutableRefObject} from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {CenteredView, FlatList} from '../util/Views'
|
import {CenteredView, FlatList} from '../util/Views'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
||||||
import {NotificationsViewModel} from 'state/models/notifications-view'
|
import {NotificationsFeedModel} from 'state/models/feeds/notifications'
|
||||||
import {FeedItem} from './FeedItem'
|
import {FeedItem} from './FeedItem'
|
||||||
import {NotificationFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
|
import {NotificationFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
|
@ -19,7 +19,7 @@ export const Feed = observer(function Feed({
|
||||||
onPressTryAgain,
|
onPressTryAgain,
|
||||||
onScroll,
|
onScroll,
|
||||||
}: {
|
}: {
|
||||||
view: NotificationsViewModel
|
view: NotificationsFeedModel
|
||||||
scrollElRef?: MutableRefObject<FlatList<any> | null>
|
scrollElRef?: MutableRefObject<FlatList<any> | null>
|
||||||
onPressTryAgain?: () => void
|
onPressTryAgain?: () => void
|
||||||
onScroll?: OnScrollCb
|
onScroll?: OnScrollCb
|
||||||
|
|
|
@ -14,8 +14,8 @@ import {
|
||||||
FontAwesomeIconStyle,
|
FontAwesomeIconStyle,
|
||||||
Props,
|
Props,
|
||||||
} from '@fortawesome/react-native-fontawesome'
|
} from '@fortawesome/react-native-fontawesome'
|
||||||
import {NotificationsViewItemModel} from 'state/models/notifications-view'
|
import {NotificationsFeedItemModel} from 'state/models/feeds/notifications'
|
||||||
import {PostThreadViewModel} from 'state/models/post-thread-view'
|
import {PostThreadModel} from 'state/models/content/post-thread'
|
||||||
import {s, colors} from 'lib/styles'
|
import {s, colors} from 'lib/styles'
|
||||||
import {ago} from 'lib/strings/time'
|
import {ago} from 'lib/strings/time'
|
||||||
import {pluralize} from 'lib/strings/helpers'
|
import {pluralize} from 'lib/strings/helpers'
|
||||||
|
@ -42,7 +42,7 @@ interface Author {
|
||||||
export const FeedItem = observer(function FeedItem({
|
export const FeedItem = observer(function FeedItem({
|
||||||
item,
|
item,
|
||||||
}: {
|
}: {
|
||||||
item: NotificationsViewItemModel
|
item: NotificationsFeedItemModel
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const [isAuthorsExpanded, setAuthorsExpanded] = React.useState<boolean>(false)
|
const [isAuthorsExpanded, setAuthorsExpanded] = React.useState<boolean>(false)
|
||||||
|
@ -338,7 +338,7 @@ function ExpandedAuthorsList({
|
||||||
function AdditionalPostText({
|
function AdditionalPostText({
|
||||||
additionalPost,
|
additionalPost,
|
||||||
}: {
|
}: {
|
||||||
additionalPost?: PostThreadViewModel
|
additionalPost?: PostThreadModel
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, {useEffect} from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
||||||
import {CenteredView, FlatList} from '../util/Views'
|
import {CenteredView, FlatList} from '../util/Views'
|
||||||
import {LikesViewModel, LikeItem} from 'state/models/likes-view'
|
import {LikesModel, LikeItem} from 'state/models/lists/likes'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
|
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
|
@ -11,10 +11,7 @@ import {usePalette} from 'lib/hooks/usePalette'
|
||||||
export const PostLikedBy = observer(function ({uri}: {uri: string}) {
|
export const PostLikedBy = observer(function ({uri}: {uri: string}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const view = React.useMemo(
|
const view = React.useMemo(() => new LikesModel(store, {uri}), [store, uri])
|
||||||
() => new LikesViewModel(store, {uri}),
|
|
||||||
[store, uri],
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
view.loadMore().catch(err => store.log.error('Failed to fetch likes', err))
|
view.loadMore().catch(err => store.log.error('Failed to fetch likes', err))
|
||||||
|
|
|
@ -2,10 +2,7 @@ import React, {useEffect} from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
||||||
import {CenteredView, FlatList} from '../util/Views'
|
import {CenteredView, FlatList} from '../util/Views'
|
||||||
import {
|
import {RepostedByModel, RepostedByItem} from 'state/models/lists/reposted-by'
|
||||||
RepostedByViewModel,
|
|
||||||
RepostedByItem,
|
|
||||||
} from 'state/models/reposted-by-view'
|
|
||||||
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
|
import {ProfileCardWithFollowBtn} from '../profile/ProfileCard'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
|
@ -19,7 +16,7 @@ export const PostRepostedBy = observer(function PostRepostedBy({
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const view = React.useMemo(
|
const view = React.useMemo(
|
||||||
() => new RepostedByViewModel(store, {uri}),
|
() => new RepostedByModel(store, {uri}),
|
||||||
[store, uri],
|
[store, uri],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ import {
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {CenteredView, FlatList} from '../util/Views'
|
import {CenteredView, FlatList} from '../util/Views'
|
||||||
import {
|
import {
|
||||||
PostThreadViewModel,
|
PostThreadModel,
|
||||||
PostThreadViewPostModel,
|
PostThreadItemModel,
|
||||||
} from 'state/models/post-thread-view'
|
} from 'state/models/content/post-thread'
|
||||||
import {
|
import {
|
||||||
FontAwesomeIcon,
|
FontAwesomeIcon,
|
||||||
FontAwesomeIconStyle,
|
FontAwesomeIconStyle,
|
||||||
|
@ -31,7 +31,7 @@ const BOTTOM_BORDER = {
|
||||||
_reactKey: '__bottom_border__',
|
_reactKey: '__bottom_border__',
|
||||||
_isHighlightedPost: false,
|
_isHighlightedPost: false,
|
||||||
}
|
}
|
||||||
type YieldedItem = PostThreadViewPostModel | typeof REPLY_PROMPT
|
type YieldedItem = PostThreadItemModel | typeof REPLY_PROMPT
|
||||||
|
|
||||||
export const PostThread = observer(function PostThread({
|
export const PostThread = observer(function PostThread({
|
||||||
uri,
|
uri,
|
||||||
|
@ -39,7 +39,7 @@ export const PostThread = observer(function PostThread({
|
||||||
onPressReply,
|
onPressReply,
|
||||||
}: {
|
}: {
|
||||||
uri: string
|
uri: string
|
||||||
view: PostThreadViewModel
|
view: PostThreadModel
|
||||||
onPressReply: () => void
|
onPressReply: () => void
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
@ -109,7 +109,7 @@ export const PostThread = observer(function PostThread({
|
||||||
// I could find to get a border positioned directly under the last item
|
// I could find to get a border positioned directly under the last item
|
||||||
// -prf
|
// -prf
|
||||||
return <View style={[styles.bottomBorder, pal.border]} />
|
return <View style={[styles.bottomBorder, pal.border]} />
|
||||||
} else if (item instanceof PostThreadViewPostModel) {
|
} else if (item instanceof PostThreadItemModel) {
|
||||||
return <PostThreadItem item={item} onPostReply={onRefresh} />
|
return <PostThreadItem item={item} onPostReply={onRefresh} />
|
||||||
}
|
}
|
||||||
return <></>
|
return <></>
|
||||||
|
@ -187,14 +187,14 @@ export const PostThread = observer(function PostThread({
|
||||||
})
|
})
|
||||||
|
|
||||||
function* flattenThread(
|
function* flattenThread(
|
||||||
post: PostThreadViewPostModel,
|
post: PostThreadItemModel,
|
||||||
isAscending = false,
|
isAscending = false,
|
||||||
): Generator<YieldedItem, void> {
|
): Generator<YieldedItem, void> {
|
||||||
if (post.parent) {
|
if (post.parent) {
|
||||||
if ('notFound' in post.parent && post.parent.notFound) {
|
if ('notFound' in post.parent && post.parent.notFound) {
|
||||||
// TODO render not found
|
// TODO render not found
|
||||||
} else {
|
} else {
|
||||||
yield* flattenThread(post.parent as PostThreadViewPostModel, true)
|
yield* flattenThread(post.parent as PostThreadItemModel, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield post
|
yield post
|
||||||
|
@ -206,7 +206,7 @@ function* flattenThread(
|
||||||
if ('notFound' in reply && reply.notFound) {
|
if ('notFound' in reply && reply.notFound) {
|
||||||
// TODO render not found
|
// TODO render not found
|
||||||
} else {
|
} else {
|
||||||
yield* flattenThread(reply as PostThreadViewPostModel)
|
yield* flattenThread(reply as PostThreadItemModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!isAscending && !post.parent && post.post.replyCount) {
|
} else if (!isAscending && !post.parent && post.post.replyCount) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
FontAwesomeIcon,
|
FontAwesomeIcon,
|
||||||
FontAwesomeIconStyle,
|
FontAwesomeIconStyle,
|
||||||
} from '@fortawesome/react-native-fontawesome'
|
} from '@fortawesome/react-native-fontawesome'
|
||||||
import {PostThreadViewPostModel} from 'state/models/post-thread-view'
|
import {PostThreadItemModel} from 'state/models/content/post-thread'
|
||||||
import {Link} from '../util/Link'
|
import {Link} from '../util/Link'
|
||||||
import {RichText} from '../util/text/RichText'
|
import {RichText} from '../util/text/RichText'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
|
@ -31,7 +31,7 @@ export const PostThreadItem = observer(function PostThreadItem({
|
||||||
item,
|
item,
|
||||||
onPostReply,
|
onPostReply,
|
||||||
}: {
|
}: {
|
||||||
item: PostThreadViewPostModel
|
item: PostThreadItemModel
|
||||||
onPostReply: () => void
|
onPostReply: () => void
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {observer} from 'mobx-react-lite'
|
||||||
import Clipboard from '@react-native-clipboard/clipboard'
|
import Clipboard from '@react-native-clipboard/clipboard'
|
||||||
import {AtUri} from '../../../third-party/uri'
|
import {AtUri} from '../../../third-party/uri'
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
import {PostThreadViewModel} from 'state/models/post-thread-view'
|
import {PostThreadModel} from 'state/models/content/post-thread'
|
||||||
import {Link} from '../util/Link'
|
import {Link} from '../util/Link'
|
||||||
import {UserInfoText} from '../util/UserInfoText'
|
import {UserInfoText} from '../util/UserInfoText'
|
||||||
import {PostMeta} from '../util/PostMeta'
|
import {PostMeta} from '../util/PostMeta'
|
||||||
|
@ -34,21 +34,21 @@ export const Post = observer(function Post({
|
||||||
style,
|
style,
|
||||||
}: {
|
}: {
|
||||||
uri: string
|
uri: string
|
||||||
initView?: PostThreadViewModel
|
initView?: PostThreadModel
|
||||||
showReplyLine?: boolean
|
showReplyLine?: boolean
|
||||||
hideError?: boolean
|
hideError?: boolean
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const [view, setView] = useState<PostThreadViewModel | undefined>(initView)
|
const [view, setView] = useState<PostThreadModel | undefined>(initView)
|
||||||
const [deleted, setDeleted] = useState(false)
|
const [deleted, setDeleted] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initView || view?.params.uri === uri) {
|
if (initView || view?.params.uri === uri) {
|
||||||
return // no change needed? or trigger refresh?
|
return // no change needed? or trigger refresh?
|
||||||
}
|
}
|
||||||
const newView = new PostThreadViewModel(store, {uri, depth: 0})
|
const newView = new PostThreadModel(store, {uri, depth: 0})
|
||||||
setView(newView)
|
setView(newView)
|
||||||
newView.setup().catch(err => store.log.error('Failed to fetch post', err))
|
newView.setup().catch(err => store.log.error('Failed to fetch post', err))
|
||||||
}, [initView, uri, view?.params.uri, store])
|
}, [initView, uri, view?.params.uri, store])
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {StyleProp, StyleSheet, TextStyle, View} from 'react-native'
|
||||||
import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
|
import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
import {PostModel} from 'state/models/post'
|
import {PostModel} from 'state/models/content/post'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
|
|
||||||
export const PostText = observer(function PostText({
|
export const PostText = observer(function PostText({
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
import {FlatList} from '../util/Views'
|
import {FlatList} from '../util/Views'
|
||||||
import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
|
import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {FeedModel} from 'state/models/feed-view'
|
import {PostsFeedModel} from 'state/models/feeds/posts'
|
||||||
import {FeedSlice} from './FeedSlice'
|
import {FeedSlice} from './FeedSlice'
|
||||||
import {OnScrollCb} from 'lib/hooks/useOnMainScroll'
|
import {OnScrollCb} from 'lib/hooks/useOnMainScroll'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
|
@ -33,7 +33,7 @@ export const Feed = observer(function Feed({
|
||||||
testID,
|
testID,
|
||||||
headerOffset = 0,
|
headerOffset = 0,
|
||||||
}: {
|
}: {
|
||||||
feed: FeedModel
|
feed: PostsFeedModel
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
showPostFollowBtn?: boolean
|
showPostFollowBtn?: boolean
|
||||||
scrollElRef?: MutableRefObject<FlatList<any> | null>
|
scrollElRef?: MutableRefObject<FlatList<any> | null>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
FontAwesomeIcon,
|
FontAwesomeIcon,
|
||||||
FontAwesomeIconStyle,
|
FontAwesomeIconStyle,
|
||||||
} from '@fortawesome/react-native-fontawesome'
|
} from '@fortawesome/react-native-fontawesome'
|
||||||
import {FeedItemModel} from 'state/models/feed-view'
|
import {PostsFeedItemModel} from 'state/models/feeds/posts'
|
||||||
import {Link, DesktopWebTextLink} from '../util/Link'
|
import {Link, DesktopWebTextLink} from '../util/Link'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
import {UserInfoText} from '../util/UserInfoText'
|
import {UserInfoText} from '../util/UserInfoText'
|
||||||
|
@ -30,7 +30,7 @@ export const FeedItem = observer(function ({
|
||||||
showFollowBtn,
|
showFollowBtn,
|
||||||
ignoreMuteFor,
|
ignoreMuteFor,
|
||||||
}: {
|
}: {
|
||||||
item: FeedItemModel
|
item: PostsFeedItemModel
|
||||||
isThreadChild?: boolean
|
isThreadChild?: boolean
|
||||||
isThreadParent?: boolean
|
isThreadParent?: boolean
|
||||||
showReplyLine?: boolean
|
showReplyLine?: boolean
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleSheet, View} from 'react-native'
|
import {StyleSheet, View} from 'react-native'
|
||||||
import {FeedSliceModel} from 'state/models/feed-view'
|
import {PostsFeedSliceModel} from 'state/models/feeds/posts'
|
||||||
import {AtUri} from '../../../third-party/uri'
|
import {AtUri} from '../../../third-party/uri'
|
||||||
import {Link} from '../util/Link'
|
import {Link} from '../util/Link'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
|
@ -13,7 +13,7 @@ export function FeedSlice({
|
||||||
showFollowBtn,
|
showFollowBtn,
|
||||||
ignoreMuteFor,
|
ignoreMuteFor,
|
||||||
}: {
|
}: {
|
||||||
slice: FeedSliceModel
|
slice: PostsFeedSliceModel
|
||||||
showFollowBtn?: boolean
|
showFollowBtn?: boolean
|
||||||
ignoreMuteFor?: string
|
ignoreMuteFor?: string
|
||||||
}) {
|
}) {
|
||||||
|
@ -66,7 +66,7 @@ export function FeedSlice({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function ViewFullThread({slice}: {slice: FeedSliceModel}) {
|
function ViewFullThread({slice}: {slice: PostsFeedSliceModel}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const itemHref = React.useMemo(() => {
|
const itemHref = React.useMemo(() => {
|
||||||
const urip = new AtUri(slice.rootItem.post.uri)
|
const urip = new AtUri(slice.rootItem.post.uri)
|
||||||
|
|
|
@ -2,9 +2,9 @@ import React, {useEffect} from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
||||||
import {
|
import {
|
||||||
UserFollowersViewModel,
|
UserFollowersModel,
|
||||||
FollowerItem,
|
FollowerItem,
|
||||||
} from 'state/models/user-followers-view'
|
} from 'state/models/lists/user-followers'
|
||||||
import {CenteredView, FlatList} from '../util/Views'
|
import {CenteredView, FlatList} from '../util/Views'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {ProfileCardWithFollowBtn} from './ProfileCard'
|
import {ProfileCardWithFollowBtn} from './ProfileCard'
|
||||||
|
@ -19,7 +19,7 @@ export const ProfileFollowers = observer(function ProfileFollowers({
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const view = React.useMemo(
|
const view = React.useMemo(
|
||||||
() => new UserFollowersViewModel(store, {actor: name}),
|
() => new UserFollowersModel(store, {actor: name}),
|
||||||
[store, name],
|
[store, name],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, {useEffect} from 'react'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
import {ActivityIndicator, RefreshControl, StyleSheet, View} from 'react-native'
|
||||||
import {CenteredView, FlatList} from '../util/Views'
|
import {CenteredView, FlatList} from '../util/Views'
|
||||||
import {UserFollowsViewModel, FollowItem} from 'state/models/user-follows-view'
|
import {UserFollowsModel, FollowItem} from 'state/models/lists/user-follows'
|
||||||
import {ErrorMessage} from '../util/error/ErrorMessage'
|
import {ErrorMessage} from '../util/error/ErrorMessage'
|
||||||
import {ProfileCardWithFollowBtn} from './ProfileCard'
|
import {ProfileCardWithFollowBtn} from './ProfileCard'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
|
@ -16,7 +16,7 @@ export const ProfileFollows = observer(function ProfileFollows({
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const view = React.useMemo(
|
const view = React.useMemo(
|
||||||
() => new UserFollowsViewModel(store, {actor: name}),
|
() => new UserFollowsModel(store, {actor: name}),
|
||||||
[store, name],
|
[store, name],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
} from '@fortawesome/react-native-fontawesome'
|
} from '@fortawesome/react-native-fontawesome'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
import {BlurView} from '../util/BlurView'
|
import {BlurView} from '../util/BlurView'
|
||||||
import {ProfileViewModel} from 'state/models/profile-view'
|
import {ProfileModel} from 'state/models/content/profile'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {ProfileImageLightbox} from 'state/models/ui/shell'
|
import {ProfileImageLightbox} from 'state/models/ui/shell'
|
||||||
import {pluralize} from 'lib/strings/helpers'
|
import {pluralize} from 'lib/strings/helpers'
|
||||||
|
@ -34,13 +34,7 @@ import {isDesktopWeb} from 'platform/detection'
|
||||||
const BACK_HITSLOP = {left: 30, top: 30, right: 30, bottom: 30}
|
const BACK_HITSLOP = {left: 30, top: 30, right: 30, bottom: 30}
|
||||||
|
|
||||||
export const ProfileHeader = observer(
|
export const ProfileHeader = observer(
|
||||||
({
|
({view, onRefreshAll}: {view: ProfileModel; onRefreshAll: () => void}) => {
|
||||||
view,
|
|
||||||
onRefreshAll,
|
|
||||||
}: {
|
|
||||||
view: ProfileViewModel
|
|
||||||
onRefreshAll: () => void
|
|
||||||
}) => {
|
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
|
||||||
// loading
|
// loading
|
||||||
|
@ -91,7 +85,7 @@ const ProfileHeaderLoaded = observer(function ProfileHeaderLoaded({
|
||||||
view,
|
view,
|
||||||
onRefreshAll,
|
onRefreshAll,
|
||||||
}: {
|
}: {
|
||||||
view: ProfileViewModel
|
view: ProfileModel
|
||||||
onRefreshAll: () => void
|
onRefreshAll: () => void
|
||||||
}) {
|
}) {
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {useFocusEffect, useIsFocused} from '@react-navigation/native'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import useAppState from 'react-native-appstate-hook'
|
import useAppState from 'react-native-appstate-hook'
|
||||||
import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
|
import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
|
||||||
import {FeedModel} from 'state/models/feed-view'
|
import {PostsFeedModel} from 'state/models/feeds/posts'
|
||||||
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {Feed} from '../com/posts/Feed'
|
import {Feed} from '../com/posts/Feed'
|
||||||
import {FollowingEmptyState} from 'view/com/posts/FollowingEmptyState'
|
import {FollowingEmptyState} from 'view/com/posts/FollowingEmptyState'
|
||||||
|
@ -26,7 +26,7 @@ export const HomeScreen = withAuthRequired((_opts: Props) => {
|
||||||
const [selectedPage, setSelectedPage] = React.useState(0)
|
const [selectedPage, setSelectedPage] = React.useState(0)
|
||||||
|
|
||||||
const algoFeed = React.useMemo(() => {
|
const algoFeed = React.useMemo(() => {
|
||||||
const feed = new FeedModel(store, 'goodstuff', {})
|
const feed = new PostsFeedModel(store, 'goodstuff', {})
|
||||||
feed.setup()
|
feed.setup()
|
||||||
return feed
|
return feed
|
||||||
}, [store])
|
}, [store])
|
||||||
|
@ -104,7 +104,7 @@ const FeedPage = observer(
|
||||||
renderEmptyState,
|
renderEmptyState,
|
||||||
}: {
|
}: {
|
||||||
testID?: string
|
testID?: string
|
||||||
feed: FeedModel
|
feed: PostsFeedModel
|
||||||
isPageFocused: boolean
|
isPageFocused: boolean
|
||||||
renderEmptyState?: () => JSX.Element
|
renderEmptyState?: () => JSX.Element
|
||||||
}) => {
|
}) => {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {withAuthRequired} from 'view/com/auth/withAuthRequired'
|
||||||
import {ViewHeader} from '../com/util/ViewHeader'
|
import {ViewHeader} from '../com/util/ViewHeader'
|
||||||
import {PostThread as PostThreadComponent} from '../com/post-thread/PostThread'
|
import {PostThread as PostThreadComponent} from '../com/post-thread/PostThread'
|
||||||
import {ComposePrompt} from 'view/com/composer/Prompt'
|
import {ComposePrompt} from 'view/com/composer/Prompt'
|
||||||
import {PostThreadViewModel} from 'state/models/post-thread-view'
|
import {PostThreadModel} from 'state/models/content/post-thread'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||||
|
@ -22,8 +22,8 @@ export const PostThreadScreen = withAuthRequired(({route}: Props) => {
|
||||||
const safeAreaInsets = useSafeAreaInsets()
|
const safeAreaInsets = useSafeAreaInsets()
|
||||||
const {name, rkey} = route.params
|
const {name, rkey} = route.params
|
||||||
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
|
const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey)
|
||||||
const view = useMemo<PostThreadViewModel>(
|
const view = useMemo<PostThreadModel>(
|
||||||
() => new PostThreadViewModel(store, {uri}),
|
() => new PostThreadModel(store, {uri}),
|
||||||
[store, uri],
|
[store, uri],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {ViewSelector} from '../com/util/ViewSelector'
|
||||||
import {CenteredView} from '../com/util/Views'
|
import {CenteredView} from '../com/util/Views'
|
||||||
import {ProfileUiModel} from 'state/models/ui/profile'
|
import {ProfileUiModel} from 'state/models/ui/profile'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {FeedSliceModel} from 'state/models/feed-view'
|
import {PostsFeedSliceModel} from 'state/models/feeds/posts'
|
||||||
import {ProfileHeader} from '../com/profile/ProfileHeader'
|
import {ProfileHeader} from '../com/profile/ProfileHeader'
|
||||||
import {FeedSlice} from '../com/posts/FeedSlice'
|
import {FeedSlice} from '../com/posts/FeedSlice'
|
||||||
import {PostFeedLoadingPlaceholder} from '../com/util/LoadingPlaceholder'
|
import {PostFeedLoadingPlaceholder} from '../com/util/LoadingPlaceholder'
|
||||||
|
@ -124,7 +124,7 @@ export const ProfileScreen = withAuthRequired(
|
||||||
style={styles.emptyState}
|
style={styles.emptyState}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
} else if (item instanceof FeedSliceModel) {
|
} else if (item instanceof PostsFeedSliceModel) {
|
||||||
return <FeedSlice slice={item} ignoreMuteFor={uiState.profile.did} />
|
return <FeedSlice slice={item} ignoreMuteFor={uiState.profile.did} />
|
||||||
}
|
}
|
||||||
return <View />
|
return <View />
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {Text} from 'view/com/util/text/Text'
|
import {Text} from 'view/com/util/text/Text'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view'
|
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||||
import {SearchUIModel} from 'state/models/ui/search'
|
import {SearchUIModel} from 'state/models/ui/search'
|
||||||
import {FoafsModel} from 'state/models/discovery/foafs'
|
import {FoafsModel} from 'state/models/discovery/foafs'
|
||||||
import {SuggestedActorsModel} from 'state/models/discovery/suggested-actors'
|
import {SuggestedActorsModel} from 'state/models/discovery/suggested-actors'
|
||||||
|
@ -37,8 +37,8 @@ export const SearchScreen = withAuthRequired(
|
||||||
const onMainScroll = useOnMainScroll(store)
|
const onMainScroll = useOnMainScroll(store)
|
||||||
const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false)
|
const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false)
|
||||||
const [query, setQuery] = React.useState<string>('')
|
const [query, setQuery] = React.useState<string>('')
|
||||||
const autocompleteView = React.useMemo<UserAutocompleteViewModel>(
|
const autocompleteView = React.useMemo<UserAutocompleteModel>(
|
||||||
() => new UserAutocompleteViewModel(store),
|
() => new UserAutocompleteModel(store),
|
||||||
[store],
|
[store],
|
||||||
)
|
)
|
||||||
const foafs = React.useMemo<FoafsModel>(
|
const foafs = React.useMemo<FoafsModel>(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {TextInput, View, StyleSheet, TouchableOpacity} from 'react-native'
|
import {TextInput, View, StyleSheet, TouchableOpacity} from 'react-native'
|
||||||
import {useNavigation, StackActions} from '@react-navigation/native'
|
import {useNavigation, StackActions} from '@react-navigation/native'
|
||||||
import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view'
|
import {UserAutocompleteModel} from 'state/models/discovery/user-autocomplete'
|
||||||
import {observer} from 'mobx-react-lite'
|
import {observer} from 'mobx-react-lite'
|
||||||
import {useStores} from 'state/index'
|
import {useStores} from 'state/index'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {usePalette} from 'lib/hooks/usePalette'
|
||||||
|
@ -16,8 +16,8 @@ export const DesktopSearch = observer(function DesktopSearch() {
|
||||||
const textInput = React.useRef<TextInput>(null)
|
const textInput = React.useRef<TextInput>(null)
|
||||||
const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false)
|
const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false)
|
||||||
const [query, setQuery] = React.useState<string>('')
|
const [query, setQuery] = React.useState<string>('')
|
||||||
const autocompleteView = React.useMemo<UserAutocompleteViewModel>(
|
const autocompleteView = React.useMemo<UserAutocompleteModel>(
|
||||||
() => new UserAutocompleteViewModel(store),
|
() => new UserAutocompleteModel(store),
|
||||||
[store],
|
[store],
|
||||||
)
|
)
|
||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
|
Loading…
Reference in New Issue