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:
Paul Frazee 2023-11-01 16:15:40 -07:00 committed by GitHub
parent f9944b55e2
commit f57a8cf8ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
87 changed files with 4090 additions and 1988 deletions

View file

@ -1,6 +1,10 @@
import React, {forwardRef} from 'react'
import {Animated, View} from 'react-native'
import PagerView, {PagerViewOnPageSelectedEvent} from 'react-native-pager-view'
import PagerView, {
PagerViewOnPageSelectedEvent,
PagerViewOnPageScrollEvent,
PageScrollStateChangedNativeEvent,
} from 'react-native-pager-view'
import {s} from 'lib/styles'
export type PageSelectedEvent = PagerViewOnPageSelectedEvent
@ -21,6 +25,7 @@ interface Props {
initialPage?: number
renderTabBar: RenderTabBarFn
onPageSelected?: (index: number) => void
onPageSelecting?: (index: number) => void
testID?: string
}
export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
@ -31,11 +36,15 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
initialPage = 0,
renderTabBar,
onPageSelected,
onPageSelecting,
testID,
}: React.PropsWithChildren<Props>,
ref,
) {
const [selectedPage, setSelectedPage] = React.useState(0)
const lastOffset = React.useRef(0)
const lastDirection = React.useRef(0)
const scrollState = React.useRef('')
const pagerView = React.useRef<PagerView>(null)
React.useImperativeHandle(ref, () => ({
@ -50,15 +59,61 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
[setSelectedPage, onPageSelected],
)
const onPageScroll = React.useCallback(
(e: PagerViewOnPageScrollEvent) => {
const {position, offset} = e.nativeEvent
if (offset === 0) {
// offset hits 0 in some awkward spots so we ignore it
return
}
// NOTE
// we want to call `onPageSelecting` as soon as the scroll-gesture
// enters the "settling" phase, which means the user has released it
// we can't infer directionality from the scroll information, so we
// track the offset changes. if the offset delta is consistent with
// the existing direction during the settling phase, we can say for
// certain where it's going and can fire
// -prf
if (scrollState.current === 'settling') {
if (lastDirection.current === -1 && offset < lastOffset.current) {
onPageSelecting?.(position)
lastDirection.current = 0
} else if (
lastDirection.current === 1 &&
offset > lastOffset.current
) {
onPageSelecting?.(position + 1)
lastDirection.current = 0
}
} else {
if (offset < lastOffset.current) {
lastDirection.current = -1
} else if (offset > lastOffset.current) {
lastDirection.current = 1
}
}
lastOffset.current = offset
},
[lastOffset, lastDirection, onPageSelecting],
)
const onPageScrollStateChanged = React.useCallback(
(e: PageScrollStateChangedNativeEvent) => {
scrollState.current = e.nativeEvent.pageScrollState
},
[scrollState],
)
const onTabBarSelect = React.useCallback(
(index: number) => {
pagerView.current?.setPage(index)
onPageSelecting?.(index)
},
[pagerView],
[pagerView, onPageSelecting],
)
return (
<View testID={testID}>
<View testID={testID} style={s.flex1}>
{tabBarPosition === 'top' &&
renderTabBar({
selectedPage,
@ -66,9 +121,11 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
})}
<AnimatedPagerView
ref={pagerView}
style={s.h100pct}
style={s.flex1}
initialPage={initialPage}
onPageSelected={onPageSelectedInner}>
onPageScrollStateChanged={onPageScrollStateChanged}
onPageSelected={onPageSelectedInner}
onPageScroll={onPageScroll}>
{children}
</AnimatedPagerView>
{tabBarPosition === 'bottom' &&