143e2c802d
* Add common gutter styles as hook * Add computed scrollbar gutter CSS vars * Add new layout components * Replace layout components in settings screens * Remove old back button * Invert web border logic for easier migration * Clean up Slot API * Port over FF handling of scrollbar offset * Trade boilerplate for ease of use * Limit to one line * Allow two lines, fix wrapping * Fix alignment * sticky headers * set max with on header and center * [Layout] Notifications Header (#6910) * Replace notifications screen header * fix cropped indicator --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com> * Replace Hashtag header (#6928) * [Layout] ChatList header (#6929) * Replace ChatList header * update chat settings as well --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com> * Add web borders to Chat settings * Remove unused var * Move ChatList header outside center * Replace empty chat layout * fix breakpoints * [Layout] Scrollbar gutters (#6908) * Fix sidebar alignment * Make sure scrollbars don't hide * Gift left nav more space * Use stable one-edge, update logic in RightNav * Ope * Increase width * Reset * Add transform to sidebars * Remove bg in sidebars * Handle shifts in layout components * Replace scroll-removal handling * Make react-remove-scroll an explicit dep * Remove unused script * use correct scroll insets (#6950) * [Layout] Feeds headers (#6913) * Replace ViewHeader internals, duplicate old ViewHeader * Replace Feeds header * Replace SavedFeeds header * Visual alignment * Uglier but clear * Use old ViewHeader for SavedFeeds * use Layout.Center instead of Layout.Content * use left-aligned header for feed edit * delete unused old view header --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com> * [Layout] Every other screen (#6953) * attempt to fix double borders on every other screen * delete ListHeaderDesktop * delete `SimpleViewHeader` and fix screens (#6956) * Make Layout.Center not full height * Refactor List to use Layout.Center, remove built-in borders * Fix Home screen * Refactor PagerWithHeader to use Layout components * Replace components in ProfileFeed and ProfileList * Borders on Profile * Search screen replacements * use new header for profile subpage header (#6958) * Search AutocompleteResults * use new header for starter pack wizard (#6957) * Fix post thread * Enable borders by default * Moderation muted and blocked accounts * Fix scrollbar offset on Labeler * Remove ScrollView from Moderation * Remove ScrollView from Deactivated * Remove ScrollView from onboarding * Remove ScrollView from SignupQueued * Mark deprecations * fix lint * Fix double borders on profile load * Remove unneeded CenteredView from noty Feed * Remove double Center layout on Notifications screen * Remove double Center layout on ChatList screen * Handle scrollbar offset in chat * Use new atom for other scrollbar offsets * Remove borders from old views * Better doc * Remove temp migration prop * Fix new atom usage on native * Clean up Hashtag screen * Layout docs * Clarify usage in Pager * Handle nested offset contexts * Clean up Layout * fix feeds page * asymmetric header on native (#6969) * Reusable header const * Fix up home header * Add back button to convo * Add hitslop to header buttons * Comment * Better handling on native for new atom * Format * Fix nested flatlist on mod screens * Use react-remove-scroll-bar directly * Fix notification count overflow on web * Clarify doc --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com>
174 lines
4.6 KiB
TypeScript
174 lines
4.6 KiB
TypeScript
/**
|
|
* In the Web build, we center all content so that it mirrors the
|
|
* mobile experience (a single narrow column). We then place a UI
|
|
* shell around the content if you're in desktop.
|
|
*
|
|
* Because scrolling is handled by components deep in the hierarchy,
|
|
* we can't just wrap the top-level element with a max width. The
|
|
* centering has to be done at the ScrollView.
|
|
*
|
|
* These components wrap the RN ScrollView-based components to provide
|
|
* consistent layout. It also provides <CenteredView> for views that
|
|
* need to match layout but which aren't scrolled.
|
|
*/
|
|
|
|
import React from 'react'
|
|
import {
|
|
FlatList,
|
|
FlatListProps,
|
|
ScrollViewProps,
|
|
StyleSheet,
|
|
View,
|
|
ViewProps,
|
|
} from 'react-native'
|
|
import Animated from 'react-native-reanimated'
|
|
|
|
import {usePalette} from '#/lib/hooks/usePalette'
|
|
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
|
import {addStyle} from '#/lib/styles'
|
|
|
|
interface AddedProps {
|
|
desktopFixedHeight?: boolean | number
|
|
}
|
|
|
|
/**
|
|
* @deprecated use `Layout` components
|
|
*/
|
|
export const CenteredView = React.forwardRef(function CenteredView(
|
|
{
|
|
style,
|
|
topBorder,
|
|
...props
|
|
}: React.PropsWithChildren<
|
|
ViewProps & {sideBorders?: boolean; topBorder?: boolean}
|
|
>,
|
|
ref: React.Ref<View>,
|
|
) {
|
|
const pal = usePalette('default')
|
|
const {isMobile} = useWebMediaQueries()
|
|
if (!isMobile) {
|
|
style = addStyle(style, styles.container)
|
|
}
|
|
if (topBorder) {
|
|
style = addStyle(style, {
|
|
borderTopWidth: 1,
|
|
})
|
|
style = addStyle(style, pal.border)
|
|
}
|
|
return <View ref={ref} style={style} {...props} />
|
|
})
|
|
|
|
export const FlatList_INTERNAL = React.forwardRef(function FlatListImpl<ItemT>(
|
|
{
|
|
contentContainerStyle,
|
|
style,
|
|
contentOffset,
|
|
desktopFixedHeight,
|
|
...props
|
|
}: React.PropsWithChildren<
|
|
Omit<FlatListProps<ItemT>, 'CellRendererComponent'> & AddedProps
|
|
>,
|
|
ref: React.Ref<FlatList<ItemT>>,
|
|
) {
|
|
const {isMobile} = useWebMediaQueries()
|
|
if (!isMobile) {
|
|
contentContainerStyle = addStyle(
|
|
contentContainerStyle,
|
|
styles.containerScroll,
|
|
)
|
|
}
|
|
if (contentOffset && contentOffset?.y !== 0) {
|
|
// NOTE
|
|
// we use paddingTop & contentOffset to space around the floating header
|
|
// but reactnative web puts the paddingTop on the wrong element (style instead of the contentContainer)
|
|
// so we manually correct it here
|
|
// -prf
|
|
style = addStyle(style, {
|
|
paddingTop: 0,
|
|
})
|
|
contentContainerStyle = addStyle(contentContainerStyle, {
|
|
paddingTop: Math.abs(contentOffset.y),
|
|
})
|
|
}
|
|
if (desktopFixedHeight) {
|
|
if (typeof desktopFixedHeight === 'number') {
|
|
// @ts-ignore Web only -prf
|
|
style = addStyle(style, {
|
|
height: `calc(100vh - ${desktopFixedHeight}px)`,
|
|
})
|
|
} else {
|
|
style = addStyle(style, styles.fixedHeight)
|
|
}
|
|
if (!isMobile) {
|
|
// NOTE
|
|
// react native web produces *three* wrapping divs
|
|
// the first two use the `style` prop and the innermost uses the
|
|
// `contentContainerStyle`. Unfortunately the stable-gutter style
|
|
// needs to be applied to only the "middle" of these. To hack
|
|
// around this, we set data-stable-gutters which can then be
|
|
// styled in our external CSS.
|
|
// -prf
|
|
// @ts-ignore web only -prf
|
|
props.dataSet = props.dataSet || {}
|
|
// @ts-ignore web only -prf
|
|
props.dataSet.stableGutters = '1'
|
|
}
|
|
}
|
|
return (
|
|
<Animated.FlatList
|
|
ref={ref}
|
|
contentContainerStyle={[styles.contentContainer, contentContainerStyle]}
|
|
style={style}
|
|
contentOffset={contentOffset}
|
|
{...props}
|
|
/>
|
|
)
|
|
})
|
|
|
|
/**
|
|
* @deprecated use `Layout` components
|
|
*/
|
|
export const ScrollView = React.forwardRef(function ScrollViewImpl(
|
|
{contentContainerStyle, ...props}: React.PropsWithChildren<ScrollViewProps>,
|
|
ref: React.Ref<Animated.ScrollView>,
|
|
) {
|
|
const {isMobile} = useWebMediaQueries()
|
|
if (!isMobile) {
|
|
contentContainerStyle = addStyle(
|
|
contentContainerStyle,
|
|
styles.containerScroll,
|
|
)
|
|
}
|
|
return (
|
|
<Animated.ScrollView
|
|
contentContainerStyle={[styles.contentContainer, contentContainerStyle]}
|
|
// @ts-ignore something is wrong with the reanimated types -prf
|
|
ref={ref}
|
|
{...props}
|
|
/>
|
|
)
|
|
})
|
|
|
|
const styles = StyleSheet.create({
|
|
contentContainer: {
|
|
// @ts-ignore web only
|
|
minHeight: '100vh',
|
|
},
|
|
container: {
|
|
width: '100%',
|
|
maxWidth: 600,
|
|
marginLeft: 'auto',
|
|
marginRight: 'auto',
|
|
},
|
|
containerScroll: {
|
|
width: '100%',
|
|
maxWidth: 600,
|
|
marginLeft: 'auto',
|
|
marginRight: 'auto',
|
|
},
|
|
fixedHeight: {
|
|
// @ts-ignore web only
|
|
height: '100vh',
|
|
},
|
|
})
|