Merge branch 'hailey/list-web-empty-component' into starter-packs
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "bsky.app",
|
"name": "bsky.app",
|
||||||
"version": "1.85.0",
|
"version": "1.85.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
KeyboardAvoidingView,
|
KeyboardAvoidingView,
|
||||||
KeyboardStickyView,
|
KeyboardStickyView,
|
||||||
|
useKeyboardContext,
|
||||||
} from 'react-native-keyboard-controller'
|
} from 'react-native-keyboard-controller'
|
||||||
import Animated, {
|
import Animated, {
|
||||||
interpolateColor,
|
interpolateColor,
|
||||||
@@ -129,6 +130,17 @@ export const ComposePost = observer(function ComposePost({
|
|||||||
const {closeAllDialogs} = useDialogStateControlContext()
|
const {closeAllDialogs} = useDialogStateControlContext()
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|
||||||
|
// Disable this in the composer to prevent any extra keyboard height being applied.
|
||||||
|
// See https://github.com/bluesky-social/social-app/pull/4399
|
||||||
|
const {setEnabled} = useKeyboardContext()
|
||||||
|
React.useEffect(() => {
|
||||||
|
setEnabled(false)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
setEnabled(true)
|
||||||
|
}
|
||||||
|
}, [setEnabled])
|
||||||
|
|
||||||
const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
|
const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
|
||||||
const [isProcessing, setIsProcessing] = useState(false)
|
const [isProcessing, setIsProcessing] = useState(false)
|
||||||
const [processingState, setProcessingState] = useState('')
|
const [processingState, setProcessingState] = useState('')
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {LoadMoreRetryBtn} from '#/view/com/util/LoadMoreRetryBtn'
|
|||||||
import {CenteredView} from '#/view/com/util/Views'
|
import {CenteredView} from '#/view/com/util/Views'
|
||||||
import {FeedItem} from './FeedItem'
|
import {FeedItem} from './FeedItem'
|
||||||
import hairlineWidth = StyleSheet.hairlineWidth
|
import hairlineWidth = StyleSheet.hairlineWidth
|
||||||
|
import {isWeb} from '#/platform/detection'
|
||||||
|
|
||||||
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
|
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
|
||||||
const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'}
|
const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'}
|
||||||
@@ -214,7 +215,15 @@ export function Feed({
|
|||||||
refreshing={isPTRing}
|
refreshing={isPTRing}
|
||||||
onRefresh={onRefresh}
|
onRefresh={onRefresh}
|
||||||
onEndReached={onEndReached}
|
onEndReached={onEndReached}
|
||||||
onEndReachedThreshold={2}
|
onEndReachedThreshold={
|
||||||
|
/*
|
||||||
|
NOTE:
|
||||||
|
web's intersection observer struggles with the 2x threshold
|
||||||
|
and leads to missed pagination, so we keep it <1
|
||||||
|
-prf
|
||||||
|
*/
|
||||||
|
isWeb ? 0.6 : 2
|
||||||
|
}
|
||||||
onScrolledDownChange={onScrolledDownChange}
|
onScrolledDownChange={onScrolledDownChange}
|
||||||
contentContainerStyle={s.contentContainer}
|
contentContainerStyle={s.contentContainer}
|
||||||
// @ts-ignore our .web version only -prf
|
// @ts-ignore our .web version only -prf
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ function ListImpl<ItemT>(
|
|||||||
{
|
{
|
||||||
ListHeaderComponent,
|
ListHeaderComponent,
|
||||||
ListFooterComponent,
|
ListFooterComponent,
|
||||||
|
ListEmptyComponent,
|
||||||
containWeb,
|
containWeb,
|
||||||
contentContainerStyle,
|
contentContainerStyle,
|
||||||
data,
|
data,
|
||||||
@@ -72,23 +73,35 @@ function ListImpl<ItemT>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let header: JSX.Element | null = null
|
const isEmpty = !data || data.length === 0
|
||||||
|
|
||||||
|
let headerComponent: JSX.Element | null = null
|
||||||
if (ListHeaderComponent != null) {
|
if (ListHeaderComponent != null) {
|
||||||
if (isValidElement(ListHeaderComponent)) {
|
if (isValidElement(ListHeaderComponent)) {
|
||||||
header = ListHeaderComponent
|
headerComponent = ListHeaderComponent
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore Nah it's fine.
|
// @ts-ignore Nah it's fine.
|
||||||
header = <ListHeaderComponent />
|
headerComponent = <ListHeaderComponent />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let footer: JSX.Element | null = null
|
let footerComponent: JSX.Element | null = null
|
||||||
if (ListFooterComponent != null) {
|
if (ListFooterComponent != null) {
|
||||||
if (isValidElement(ListFooterComponent)) {
|
if (isValidElement(ListFooterComponent)) {
|
||||||
footer = ListFooterComponent
|
footerComponent = ListFooterComponent
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore Nah it's fine.
|
// @ts-ignore Nah it's fine.
|
||||||
footer = <ListFooterComponent />
|
footerComponent = <ListFooterComponent />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let emptyComponent: JSX.Element | null = null
|
||||||
|
if (ListEmptyComponent != null) {
|
||||||
|
if (isValidElement(ListEmptyComponent)) {
|
||||||
|
emptyComponent = ListEmptyComponent
|
||||||
|
} else {
|
||||||
|
// @ts-ignore Nah it's fine.
|
||||||
|
emptyComponent = <ListEmptyComponent />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,15 +336,17 @@ function ListImpl<ItemT>(
|
|||||||
onVisibleChange={handleAboveTheFoldVisibleChange}
|
onVisibleChange={handleAboveTheFoldVisibleChange}
|
||||||
style={[styles.aboveTheFoldDetector, {height: headerOffset}]}
|
style={[styles.aboveTheFoldDetector, {height: headerOffset}]}
|
||||||
/>
|
/>
|
||||||
{onStartReached && (
|
{onStartReached && !isEmpty && (
|
||||||
<Visibility
|
<Visibility
|
||||||
root={containWeb ? nativeRef : null}
|
root={containWeb ? nativeRef : null}
|
||||||
onVisibleChange={onHeadVisibilityChange}
|
onVisibleChange={onHeadVisibilityChange}
|
||||||
topMargin={(onStartReachedThreshold ?? 0) * 100 + '%'}
|
topMargin={(onStartReachedThreshold ?? 0) * 100 + '%'}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{header}
|
{headerComponent}
|
||||||
{(data as Array<ItemT>).map((item, index) => {
|
{isEmpty
|
||||||
|
? emptyComponent
|
||||||
|
: (data as Array<ItemT>)?.map((item, index) => {
|
||||||
const key = keyExtractor!(item, index)
|
const key = keyExtractor!(item, index)
|
||||||
return (
|
return (
|
||||||
<Row<ItemT>
|
<Row<ItemT>
|
||||||
@@ -345,14 +360,14 @@ function ListImpl<ItemT>(
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
{onEndReached && (
|
{onEndReached && !isEmpty && (
|
||||||
<Visibility
|
<Visibility
|
||||||
root={containWeb ? nativeRef : null}
|
root={containWeb ? nativeRef : null}
|
||||||
onVisibleChange={onTailVisibilityChange}
|
onVisibleChange={onTailVisibilityChange}
|
||||||
bottomMargin={(onEndReachedThreshold ?? 0) * 100 + '%'}
|
bottomMargin={(onEndReachedThreshold ?? 0) * 100 + '%'}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{footer}
|
{footerComponent}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user