Lists updates: curate lists and blocklists (#1689)
* Add lists screen * Update Lists screen and List create/edit modal to support curate lists * Rework the ProfileList screen and add curatelist support * More ProfileList progress * Update list modals * Rename mutelists to modlists * Layout updates/fixes * More layout fixes * Modal fixes * List list screen updates * Update feed page to give more info * Layout fixes to ListAddUser modal * Layout fixes to FlatList and Feed on desktop * Layout fix to LoadLatestBtn on Web * Handle did resolution before showing the ProfileList screen * Rename the CustomFeed routes to ProfileFeed for consistency * Fix layout issues with the pager and feeds * Factor out some common code * Fix UIs for mobile * Fix user list rendering * Fix: dont bubble custom feed errors in the merge feed * Refactor feed models to reduce usage of the SavedFeeds model * Replace CustomFeedModel with FeedSourceModel which abstracts feed-generators and lists * Add the ability to pin lists * Add pinned lists to mobile * Remove dead code * Rework the ProfileScreenHeader to create more real-estate for action buttons * Improve layout behavior on web mobile breakpoints * Refactor feed & list pages to use new Tabs layout component * Refactor to ProfileSubpageHeader * Implement modlist block and mute * Switch to new api and just modify state on modlist actions * Fix some UI overflows * Fix: dont show edit buttons on lists you dont own * Fix alignment issue on long titles * Improve loading and error states for feeds & lists * Update list dropdown icons for ios * Fetch feed display names in the mergefeed * Improve rendering off offline feeds in the feed-listing page * Update Feeds listing UI to react to changes in saved/pinned state * Refresh list and feed on posts tab press * Fix pinned feed ordering UI * Fixes to list pinning * Remove view=simple qp * Add list to feed tuners * Render richtext * Add list href * Add 'view avatar' * Remove unused import * Fix missing import * Correctly reflect block by list state * Replace the <Tabs> component with the more effective <PagerWithHeader> component * Improve the responsiveness of the PagerWithHeader * Fix visual jank in the feed loading state * Improve performance of the PagerWithHeader * Fix a case that would cause the header to animate too aggressively * Add the ability to scroll to top by tapping the selected tab * Fix unit test runner * Update modlists test * Add curatelist tests * Fix: remove link behavior in ListAddUser modal * Fix some layout jank in the PagerWithHeader on iOS * Simplify ListItems header rendering * Wait for the appview to recognize the list before proceeding with list creation * Fix glitch in the onPageSelecting index of the Pager * Fix until() * Copy fix Co-authored-by: Eric Bailey <git@esb.lol> --------- Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
parent
f9944b55e2
commit
f57a8cf8ba
87 changed files with 4090 additions and 1988 deletions
|
@ -1,24 +1,15 @@
|
|||
import {useEffect, useState} from 'react'
|
||||
import {useStores} from 'state/index'
|
||||
import {CustomFeedModel} from 'state/models/feeds/custom-feed'
|
||||
import {FeedSourceModel} from 'state/models/content/feed-source'
|
||||
|
||||
export function useCustomFeed(uri: string): CustomFeedModel | undefined {
|
||||
export function useCustomFeed(uri: string): FeedSourceModel | undefined {
|
||||
const store = useStores()
|
||||
const [item, setItem] = useState<CustomFeedModel | undefined>()
|
||||
const [item, setItem] = useState<FeedSourceModel | undefined>()
|
||||
useEffect(() => {
|
||||
async function fetchView() {
|
||||
const res = await store.agent.app.bsky.feed.getFeedGenerator({
|
||||
feed: uri,
|
||||
})
|
||||
const view = res.data.view
|
||||
return view
|
||||
}
|
||||
async function buildFeedItem() {
|
||||
const view = await fetchView()
|
||||
if (view) {
|
||||
const temp = new CustomFeedModel(store, view)
|
||||
setItem(temp)
|
||||
}
|
||||
const model = new FeedSourceModel(store, uri)
|
||||
await model.setup()
|
||||
setItem(model)
|
||||
}
|
||||
buildFeedItem()
|
||||
}, [store, uri])
|
||||
|
|
51
src/lib/hooks/useDesktopRightNavItems.ts
Normal file
51
src/lib/hooks/useDesktopRightNavItems.ts
Normal file
|
@ -0,0 +1,51 @@
|
|||
import {useEffect, useState} from 'react'
|
||||
import {useStores} from 'state/index'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import {AtUri} from '@atproto/api'
|
||||
import {FeedSourceModel} from 'state/models/content/feed-source'
|
||||
|
||||
interface RightNavItem {
|
||||
uri: string
|
||||
href: string
|
||||
hostname: string
|
||||
collection: string
|
||||
rkey: string
|
||||
displayName: string
|
||||
}
|
||||
|
||||
export function useDesktopRightNavItems(uris: string[]): RightNavItem[] {
|
||||
const store = useStores()
|
||||
const [items, setItems] = useState<RightNavItem[]>([])
|
||||
const [lastUris, setLastUris] = useState<string[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
if (isEqual(uris, lastUris)) {
|
||||
// no changes
|
||||
return
|
||||
}
|
||||
|
||||
async function fetchFeedInfo() {
|
||||
const models = uris
|
||||
.slice(0, 25)
|
||||
.map(uri => new FeedSourceModel(store, uri))
|
||||
await Promise.all(models.map(m => m.setup()))
|
||||
setItems(
|
||||
models.map(model => {
|
||||
const {hostname, collection, rkey} = new AtUri(model.uri)
|
||||
return {
|
||||
uri: model.uri,
|
||||
href: model.href,
|
||||
hostname,
|
||||
collection,
|
||||
rkey,
|
||||
displayName: model.displayName,
|
||||
}
|
||||
}),
|
||||
)
|
||||
setLastUris(uris)
|
||||
}
|
||||
fetchFeedInfo()
|
||||
}, [store, uris, lastUris, setLastUris, setItems])
|
||||
|
||||
return items
|
||||
}
|
29
src/lib/hooks/useHomeTabs.ts
Normal file
29
src/lib/hooks/useHomeTabs.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import {useEffect, useState} from 'react'
|
||||
import {useStores} from 'state/index'
|
||||
import isEqual from 'lodash.isequal'
|
||||
import {FeedSourceModel} from 'state/models/content/feed-source'
|
||||
|
||||
export function useHomeTabs(uris: string[]): string[] {
|
||||
const store = useStores()
|
||||
const [tabs, setTabs] = useState<string[]>(['Following'])
|
||||
const [lastUris, setLastUris] = useState<string[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
if (isEqual(uris, lastUris)) {
|
||||
// no changes
|
||||
return
|
||||
}
|
||||
|
||||
async function fetchFeedInfo() {
|
||||
const models = uris
|
||||
.slice(0, 25)
|
||||
.map(uri => new FeedSourceModel(store, uri))
|
||||
await Promise.all(models.map(m => m.setup()))
|
||||
setTabs(['Following'].concat(models.map(f => f.displayName)))
|
||||
setLastUris(uris)
|
||||
}
|
||||
fetchFeedInfo()
|
||||
}, [store, uris, lastUris, setLastUris, setTabs])
|
||||
|
||||
return tabs
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue