get monologue tab working against all odds

This commit is contained in:
Samuel Newman
2024-10-22 23:03:53 +03:00
parent 090ac041c3
commit 0569e02442
2 changed files with 283 additions and 189 deletions
+38 -6
View File
@@ -15,6 +15,7 @@ import Animated, {
useAnimatedRef, useAnimatedRef,
useAnimatedStyle, useAnimatedStyle,
useSharedValue, useSharedValue,
withTiming,
} from 'react-native-reanimated' } from 'react-native-reanimated'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
@@ -44,8 +45,15 @@ export interface PagerWithHeaderProps {
onCurrentPageSelected?: (index: number) => void onCurrentPageSelected?: (index: number) => void
allowHeaderOverScroll?: boolean allowHeaderOverScroll?: boolean
} }
export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>( export const PagerWithHeader = React.forwardRef<
function PageWithHeaderImpl( PagerRef,
PagerWithHeaderProps & {
headerRef: React.Ref<{
scrollHeaderAway: () => void
scrollHeaderBack: () => void
}>
}
>(function PageWithHeaderImpl(
{ {
children, children,
testID, testID,
@@ -56,15 +64,40 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
onPageSelected, onPageSelected,
onCurrentPageSelected, onCurrentPageSelected,
allowHeaderOverScroll, allowHeaderOverScroll,
}: PagerWithHeaderProps, headerRef,
},
ref, ref,
) { ) {
const [currentPage, setCurrentPage] = React.useState(0) const [currentPage, setCurrentPage] = React.useState(0)
const [tabBarHeight, setTabBarHeight] = React.useState(0) const [tabBarHeight, setTabBarHeight] = React.useState(0)
const [headerOnlyHeight, setHeaderOnlyHeight] = React.useState(0) const [headerOnlyHeight, setHeaderOnlyHeight] = React.useState(0)
const scrollY = useSharedValue(0) const scrollY = useSharedValue(0)
const headerHeight = headerOnlyHeight + tabBarHeight const headerHeight = headerOnlyHeight + tabBarHeight
const maybePrevScrollY = useSharedValue<number | null>(null)
function scrollHeaderAway() {
'worklet'
maybePrevScrollY.value = scrollY.value
scrollY.value = withTiming(headerHeight)
}
function scrollHeaderBack() {
'worklet'
if (maybePrevScrollY.value !== null) {
scrollY.value = withTiming(maybePrevScrollY.value)
maybePrevScrollY.value = null
}
}
React.useImperativeHandle(headerRef, () => ({
scrollHeaderAway: () => {
runOnUI(scrollHeaderAway)()
},
scrollHeaderBack: () => {
runOnUI(scrollHeaderBack)()
},
}))
// capture the header bar sizing // capture the header bar sizing
const onTabBarLayout = useNonReactiveCallback((evt: LayoutChangeEvent) => { const onTabBarLayout = useNonReactiveCallback((evt: LayoutChangeEvent) => {
const height = evt.nativeEvent.layout.height const height = evt.nativeEvent.layout.height
@@ -215,8 +248,7 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
})} })}
</Pager> </Pager>
) )
}, })
)
let PagerTabBar = ({ let PagerTabBar = ({
currentPage, currentPage,
+84 -22
View File
@@ -25,6 +25,7 @@ import {isInvalidHandle} from '#/lib/strings/handles'
import {colors, s} from '#/lib/styles' import {colors, s} from '#/lib/styles'
import {useProfileShadow} from '#/state/cache/profile-shadow' import {useProfileShadow} from '#/state/cache/profile-shadow'
import {listenSoftReset} from '#/state/events' import {listenSoftReset} from '#/state/events'
import {ConvoProvider, isConvoActive, useConvo} from '#/state/messages/convo'
import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useActorStarterPacksQuery} from '#/state/queries/actor-starter-packs' import {useActorStarterPacksQuery} from '#/state/queries/actor-starter-packs'
import {useLabelerInfoQuery} from '#/state/queries/labeler' import {useLabelerInfoQuery} from '#/state/queries/labeler'
@@ -41,6 +42,7 @@ import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
import {FAB} from '#/view/com/util/fab/FAB' import {FAB} from '#/view/com/util/fab/FAB'
import {ListRef} from '#/view/com/util/List' import {ListRef} from '#/view/com/util/List'
import {CenteredView} from '#/view/com/util/Views' import {CenteredView} from '#/view/com/util/Views'
import {MessagesList} from '#/screens/Messages/components/MessagesList'
import {ProfileHeader, ProfileHeaderLoading} from '#/screens/Profile/Header' import {ProfileHeader, ProfileHeaderLoading} from '#/screens/Profile/Header'
import {ProfileFeedSection} from '#/screens/Profile/Sections/Feed' import {ProfileFeedSection} from '#/screens/Profile/Sections/Feed'
import {ProfileLabelsSection} from '#/screens/Profile/Sections/Labels' import {ProfileLabelsSection} from '#/screens/Profile/Sections/Labels'
@@ -190,8 +192,9 @@ function ProfileScreenLoaded({
const [scrollViewTag, setScrollViewTag] = React.useState<number | null>(null) const [scrollViewTag, setScrollViewTag] = React.useState<number | null>(null)
const postsSectionRef = React.useRef<SectionRef>(null) const postsSectionRef = React.useRef<SectionRef>(null)
const repliesSectionRef = React.useRef<SectionRef>(null) // const repliesSectionRef = React.useRef<SectionRef>(null)
const mediaSectionRef = React.useRef<SectionRef>(null) // const mediaSectionRef = React.useRef<SectionRef>(null)
const monologueSectionRef = React.useRef<SectionRef>(null)
const likesSectionRef = React.useRef<SectionRef>(null) const likesSectionRef = React.useRef<SectionRef>(null)
const feedsSectionRef = React.useRef<SectionRef>(null) const feedsSectionRef = React.useRef<SectionRef>(null)
const listsSectionRef = React.useRef<SectionRef>(null) const listsSectionRef = React.useRef<SectionRef>(null)
@@ -213,8 +216,9 @@ function ProfileScreenLoaded({
const hasLabeler = !!profile.associated?.labeler const hasLabeler = !!profile.associated?.labeler
const showFiltersTab = hasLabeler const showFiltersTab = hasLabeler
const showPostsTab = true const showPostsTab = true
const showRepliesTab = hasSession // const showRepliesTab = hasSession
const showMediaTab = !hasLabeler // const showMediaTab = !hasLabeler
const showMonologueTab = !!currentAccount
const showLikesTab = isMe const showLikesTab = isMe
const showFeedsTab = isMe || (profile.associated?.feedgens || 0) > 0 const showFeedsTab = isMe || (profile.associated?.feedgens || 0) > 0
const showStarterPacksTab = const showStarterPacksTab =
@@ -226,8 +230,9 @@ function ProfileScreenLoaded({
showFiltersTab ? _(msg`Labels`) : undefined, showFiltersTab ? _(msg`Labels`) : undefined,
showListsTab && hasLabeler ? _(msg`Lists`) : undefined, showListsTab && hasLabeler ? _(msg`Lists`) : undefined,
showPostsTab ? _(msg`Posts`) : undefined, showPostsTab ? _(msg`Posts`) : undefined,
showRepliesTab ? _(msg`Replies`) : undefined, // showRepliesTab ? _(msg`Replies`) : undefined,
showMediaTab ? _(msg`Media`) : undefined, // showMediaTab ? _(msg`Media`) : undefined,
showMonologueTab ? _(msg`Monologue`) : undefined,
showLikesTab ? _(msg`Likes`) : undefined, showLikesTab ? _(msg`Likes`) : undefined,
showFeedsTab ? _(msg`Feeds`) : undefined, showFeedsTab ? _(msg`Feeds`) : undefined,
showStarterPacksTab ? _(msg`Starter Packs`) : undefined, showStarterPacksTab ? _(msg`Starter Packs`) : undefined,
@@ -237,8 +242,9 @@ function ProfileScreenLoaded({
let nextIndex = 0 let nextIndex = 0
let filtersIndex: number | null = null let filtersIndex: number | null = null
let postsIndex: number | null = null let postsIndex: number | null = null
let repliesIndex: number | null = null // let repliesIndex: number | null = null
let mediaIndex: number | null = null // let mediaIndex: number | null = null
let monologueIndex: number | null = null
let likesIndex: number | null = null let likesIndex: number | null = null
let feedsIndex: number | null = null let feedsIndex: number | null = null
let starterPacksIndex: number | null = null let starterPacksIndex: number | null = null
@@ -249,11 +255,14 @@ function ProfileScreenLoaded({
if (showPostsTab) { if (showPostsTab) {
postsIndex = nextIndex++ postsIndex = nextIndex++
} }
if (showRepliesTab) { // if (showRepliesTab) {
repliesIndex = nextIndex++ // repliesIndex = nextIndex++
} // }
if (showMediaTab) { // if (showMediaTab) {
mediaIndex = nextIndex++ // mediaIndex = nextIndex++
// }
if (showMonologueTab) {
monologueIndex = nextIndex++
} }
if (showLikesTab) { if (showLikesTab) {
likesIndex = nextIndex++ likesIndex = nextIndex++
@@ -274,10 +283,12 @@ function ProfileScreenLoaded({
labelsSectionRef.current?.scrollToTop() labelsSectionRef.current?.scrollToTop()
} else if (index === postsIndex) { } else if (index === postsIndex) {
postsSectionRef.current?.scrollToTop() postsSectionRef.current?.scrollToTop()
} else if (index === repliesIndex) { // } else if (index === repliesIndex) {
repliesSectionRef.current?.scrollToTop() // repliesSectionRef.current?.scrollToTop()
} else if (index === mediaIndex) { // } else if (index === mediaIndex) {
mediaSectionRef.current?.scrollToTop() // mediaSectionRef.current?.scrollToTop()
} else if (index === monologueIndex) {
monologueSectionRef.current?.scrollToTop()
} else if (index === likesIndex) { } else if (index === likesIndex) {
likesSectionRef.current?.scrollToTop() likesSectionRef.current?.scrollToTop()
} else if (index === feedsIndex) { } else if (index === feedsIndex) {
@@ -291,8 +302,9 @@ function ProfileScreenLoaded({
[ [
filtersIndex, filtersIndex,
postsIndex, postsIndex,
repliesIndex, // repliesIndex,
mediaIndex, // mediaIndex,
monologueIndex,
likesIndex, likesIndex,
feedsIndex, feedsIndex,
listsIndex, listsIndex,
@@ -330,7 +342,17 @@ function ProfileScreenLoaded({
openComposer({mention}) openComposer({mention})
} }
const headerRef = React.useRef<{
scrollHeaderAway: () => void
scrollHeaderBack: () => void
}>(null!)
const onPageSelected = (i: number) => { const onPageSelected = (i: number) => {
if (showMonologueTab && i === monologueIndex) {
headerRef.current?.scrollHeaderAway()
} else {
headerRef.current?.scrollHeaderBack()
}
setCurrentPage(i) setCurrentPage(i)
} }
@@ -363,6 +385,7 @@ function ProfileScreenLoaded({
screenDescription={_(msg`profile`)} screenDescription={_(msg`profile`)}
modui={moderation.ui('profileView')}> modui={moderation.ui('profileView')}>
<PagerWithHeader <PagerWithHeader
headerRef={headerRef}
testID="profilePager" testID="profilePager"
isHeaderReady={!showPlaceholder} isHeaderReady={!showPlaceholder}
items={sectionTitles} items={sectionTitles}
@@ -410,7 +433,20 @@ function ProfileScreenLoaded({
/> />
) )
: null} : null}
{showRepliesTab {showMonologueTab
? ({headerHeight, isFocused, scrollElRef}) => (
<ConvoProvider convoId="3ksogfbowfs27">
<ProfileMonologueSection
// ref={monologueSectionRef}
headerHeight={headerHeight}
isFocused={isFocused}
scrollElRef={scrollElRef as ListRef}
setScrollViewTag={setScrollViewTag}
/>
</ConvoProvider>
)
: null}
{/* {showRepliesTab
? ({headerHeight, isFocused, scrollElRef}) => ( ? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileFeedSection <ProfileFeedSection
ref={repliesSectionRef} ref={repliesSectionRef}
@@ -435,7 +471,7 @@ function ProfileScreenLoaded({
setScrollViewTag={setScrollViewTag} setScrollViewTag={setScrollViewTag}
/> />
) )
: null} : null} */}
{showLikesTab {showLikesTab
? ({headerHeight, isFocused, scrollElRef}) => ( ? ({headerHeight, isFocused, scrollElRef}) => (
<ProfileFeedSection <ProfileFeedSection
@@ -487,7 +523,8 @@ function ProfileScreenLoaded({
) )
: null} : null}
</PagerWithHeader> </PagerWithHeader>
{hasSession && ( {hasSession &&
(showMonologueTab ? monologueIndex !== currentPage : true) && (
<FAB <FAB
testID="composeFAB" testID="composeFAB"
onPress={onPressCompose} onPress={onPressCompose}
@@ -501,6 +538,31 @@ function ProfileScreenLoaded({
) )
} }
function ProfileMonologueSection({}: // isFocused,
// scrollElRef,
// headerHeight,
// setScrollViewTag,
{
headerHeight: number
isFocused: boolean
scrollElRef: ListRef
setScrollViewTag: (tag: number | null) => void
}) {
const [hasScrolled, setHasScrolled] = React.useState(false)
const convo = useConvo()
if (isConvoActive(convo)) {
return (
<MessagesList
hasScrolled={hasScrolled}
setHasScrolled={setHasScrolled}
blocked={false}
footer={<></>}
/>
)
}
}
function useRichText(text: string): [RichTextAPI, boolean] { function useRichText(text: string): [RichTextAPI, boolean] {
const agent = useAgent() const agent = useAgent()
const [prevText, setPrevText] = React.useState(text) const [prevText, setPrevText] = React.useState(text)