react-native#ListRenderItem TypeScript Examples
The following examples show how to use
react-native#ListRenderItem.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: App.tsx From react-native-ios-context-menu with MIT License | 6 votes |
export function HomeScreen(props) {
const renderItem: ListRenderItem<ExampleListItem> = ({ item }) => (
React.createElement(item.component, {
index: item.id,
style: styles.exampleListItem
})
);
return (
<SafeAreaView>
{false && (
<TouchableOpacity
onPress={() => {
props.navigation.navigate('Test');
}}
>
<Text>
Push
</Text>
</TouchableOpacity>
)}
<FlatList
contentContainerStyle={styles.scrollContentContainer}
data={EXAMPLE_ITEMS}
renderItem={renderItem}
keyExtractor={(item) => `item-${item.id}`}
/>
</SafeAreaView>
);
}
Example #2
Source File: CardRowColorPicker.tsx From react-native-ios-context-menu with MIT License | 6 votes |
_listRenderItem: ListRenderItem<string> = ({item}) => {
const props = this.props;
const state = this.state;
const isSelected = (item === state.selectedItem);
return(
<TouchableOpacity
style={[
styles.listItem,
isSelected && styles.listItemSelected,
{ backgroundColor: item }
]}
onPress={() => {
// clear if already selected
const selectedItem = isSelected? undefined : item;
this.setState({selectedItem});
props.onSelectItem?.(selectedItem);
}}
/>
);
};
Example #3
Source File: WeekCarousel.tsx From nyxo-app with GNU General Public License v3.0 | 6 votes |
WeekCarousel: FC<Props> = ({
ListHeaderComponent,
refreshControl,
coaching
}) => {
const { data, error } = useWeeks()
const renderWeekCard: ListRenderItem<WeekCollectionItem> = ({ item }) => {
return (
<WeekCard
key={item.slug}
week={item}
cardMargin={cardMargin}
cardWidth={cardWidth}
coaching={coaching}
/>
)
}
return (
<FlatList
ListHeaderComponent={ListHeaderComponent}
refreshControl={refreshControl}
keyExtractor={(item) => item.slug}
showsHorizontalScrollIndicator={false}
snapToAlignment="center"
data={data?.coachingWeekCollection?.items}
renderItem={renderWeekCard}
/>
)
}
Example #4
Source File: ExampleHabitSection.tsx From nyxo-app with GNU General Public License v3.0 | 6 votes |
ExampleHabitSection: FC<Props> = ({ habits }) => {
if (!habits) return null
const contentOffsets = habits.map(
(_, index) => (EXAMPLE_HABIT_WIDTH + EXAMPLE_HABIT_MARGIN_LEFT) * index
)
const renderHabit: ListRenderItem<HabitCollectionItem> = ({
item: habit
}) => (
<ExampleHabit
key={`${habit?.title}`}
title={habit?.title}
period={habit?.period}
description={habit?.description?.json}
/>
)
return (
<>
<H3>EXAMPLE_HABITS</H3>
<TextSmall>TRY_THIS_HABIT</TextSmall>
<List
keyExtractor={keyExtractor}
centerContent
horizontal
data={habits}
renderItem={renderHabit}
snapToOffsets={contentOffsets}
decelerationRate="fast"
/>
</>
)
}
Example #5
Source File: PickerView.tsx From BitcoinWalletMobile with MIT License | 5 votes |
PickerView: React.FC<Props> = (props) => {
const languages = ["English", "Español", "Catalan", "Français", "Italiano", "Português Brasil", "日本語", "简体ä¸æ–‡"]
const currencies = [
"USD",
"AUD",
"BRL",
"CAD",
"CHF",
"CLP",
"CNY",
"DKK",
"EUR",
"GBP",
"HKD",
"INR",
"ISK",
"JPY",
"KRW",
"NZD",
"PLN",
"RUB",
"SEK",
"SGD",
"THB",
"TRY",
"TWD",
]
const getCurrentLanguage = (state: WalletState) => state.language
const getCurrentCurrency = (state: WalletState) => state.currency
const selectedLanguage = useSelector(getCurrentLanguage)
const selectedCurrency = useSelector(getCurrentCurrency)
const dispatch = useDispatch()
const selectItem = (item: string) => {
if (props.route.params.type == "Choose Currency") {
dispatch(setCurrency(item))
}
else {
dispatch(setLanguage(getLanguageShortCode(item)))
}
props.navigation.goBack()
}
const renderItem: ListRenderItem<string> = ({ item }) => (
<TouchableOpacity onPress={() => { selectItem(item) }}>
<View style={(props.route.params.type == "Choose Currency" ? (selectedCurrency == item ? styles.trSelected : styles.tr) : (selectedLanguage == getLanguageShortCode(item) ? styles.trSelected : styles.tr))}>
<Text style={(props.route.params.type == "Choose Currency" ? (selectedCurrency == item ? styles.selectedRowText : styles.rowText) : (selectedLanguage == getLanguageShortCode(item) ? styles.selectedRowText : styles.rowText))}>{item}</Text>
{props.route.params.type == "Choose Currency" && selectedCurrency == item &&
<Image style={styles.icon} source={require("../../assets/images/tick.png")} />
}
{props.route.params.type == "Choose Language" && selectedLanguage == getLanguageShortCode(item) &&
<Image style={styles.icon} source={require("../../assets/images/tick.png")} />
}
</View>
</TouchableOpacity>
)
return (
<View style={styles.container}>
<Header screen={props.route.params.type == "Choose Language" ? getTranslated(selectedLanguage).choose_language : getTranslated(selectedLanguage).currency} action={() => { props.navigation.goBack() }} />
<Screen>
<View style={styles.container}>
<FlatList
data={props.route.params.type == "Choose Language" ? languages : currencies}
renderItem={renderItem}
showsVerticalScrollIndicator={false}
keyExtractor={(item) => item}
/>
</View>
</Screen>
</View>
)
}
Example #6
Source File: Lessons.tsx From nyxo-app with GNU General Public License v3.0 | 5 votes |
LessonList: FC<Props> = ({
locked,
header,
footer,
onScroll,
slug,
refreshControl,
...rest
}) => {
const { data } = useGetActiveCoaching()
const { data: weekData } = useWeek(slug ?? 'introduction')
const week = getWeek(weekData)
const withData = week?.lessonsCollection.items.map((lesson) => ({
...lesson,
completed: !!data?.lessons?.find((lssn) => lesson.slug === lssn)
}))
const groupedLessons = groupBy(withData, (lesson) => lesson.section?.title)
const sectionData = withData?.map((item) => ({
title: item.section?.title,
description: item.section?.description,
order: item.section?.order
}))
const sections = Object.entries(groupedLessons).map((group) => ({
header: { ...sectionData?.find((item) => item.title === group[0]) },
data: group[1]
}))
const renderCard: ListRenderItem<LessonCollectionItem> = ({ item }) => (
<LessonListItem key={item?.slug} locked={locked} lesson={item} />
)
const renderSectionHeader: RenderSectionHeader = ({ section }) => (
<SectionHeader
key={`${section.header.title}`}
description={section.header.description?.json}
title={`${section.header.title}`}
/>
)
return (
<StyledSectionList
scrollEventThrottle={16}
onScroll={onScroll}
refreshControl={refreshControl}
ListHeaderComponent={header}
stickySectionHeadersEnabled={false}
ListFooterComponent={
<>
{footer}
<Spacer />
</>
}
keyExtractor={keyExtractor}
sections={sections}
renderSectionHeader={renderSectionHeader}
renderItem={renderCard}
{...rest}
/>
)
}
Example #7
Source File: CoachingSettings.tsx From nyxo-app with GNU General Public License v3.0 | 5 votes |
CoachingSettings: FC = () => {
const {
data: months,
isLoading,
refetch: refetchCoaching
} = useListCoaching()
const {
data: activeMonth,
refetch: refetchActiveMonth
} = useGetActiveCoaching()
const renderItem: ListRenderItem<CoachingPeriod> = ({ item }) => (
<CoachingMonthCard key={`${item?.id}`} month={item} />
)
const data = months?.filter((m) => m?.id !== activeMonth?.id)
const refresh = () => {
refetchCoaching()
refetchActiveMonth()
}
return (
<SafeAreaView>
<FlatList
refreshControl={
<ThemedRefreshControl refreshing={isLoading} onRefresh={refresh} />
}
ListHeaderComponent={() => (
<>
<GoBackContainer>
<GoBack route={'Settings'} />
</GoBackContainer>
<Container>
<H2>COACHING.SETTINGS.TITLE</H2>
<H4>COACHING.SETTINGS.ACTIVE</H4>
</Container>
{activeMonth ? (
<CoachingMonthCard actionsEnabled={false} month={activeMonth} />
) : null}
<Container>
<H4>COACHING.SETTINGS.ALL</H4>
</Container>
</>
)}
data={data}
renderItem={renderItem}
/>
</SafeAreaView>
)
}
Example #8
Source File: Playlists.tsx From jellyfin-audio-player with MIT License | 5 votes |
Playlists: React.FC = () => {
// Retrieve data from store
const { entities, ids } = useTypedSelector((state) => state.music.playlists);
const isLoading = useTypedSelector((state) => state.music.playlists.isLoading);
const lastRefreshed = useTypedSelector((state) => state.music.playlists.lastRefreshed);
// Initialise helpers
const dispatch = useAppDispatch();
const navigation = useNavigation<MusicNavigationProp>();
const getImage = useGetImage();
const listRef = useRef<FlatList<EntityId>>(null);
const getItemLayout = useCallback((data: EntityId[] | null | undefined, index: number): { offset: number, length: number, index: number } => {
const length = 220;
const offset = length * index;
return { index, length, offset };
}, []);
// Set callbacks
const retrieveData = useCallback(() => dispatch(fetchAllPlaylists()), [dispatch]);
const selectAlbum = useCallback((id: string) => {
navigation.navigate('Playlist', { id });
}, [navigation]);
const generateItem: ListRenderItem<EntityId> = useCallback(({ item, index }) => {
if (index % 2 === 1) {
return <View key={item} />;
}
const nextItemId = ids[index + 1];
const nextItem = entities[nextItemId];
return (
<View style={{ flexDirection: 'row', marginLeft: 10, marginRight: 10 }} key={item}>
<GeneratedPlaylistItem
id={item}
imageUrl={getImage(item as string)}
name={entities[item]?.Name || ''}
onPress={selectAlbum}
/>
{nextItem &&
<GeneratedPlaylistItem
id={nextItemId}
imageUrl={getImage(nextItemId as string)}
name={nextItem.Name || ''}
onPress={selectAlbum}
/>
}
</View>
);
}, [entities, getImage, selectAlbum, ids]);
// Retrieve data on mount
useEffect(() => {
// GUARD: Only refresh this API call every set amounts of days
if (!lastRefreshed || differenceInDays(lastRefreshed, new Date()) > PLAYLIST_CACHE_AMOUNT_OF_DAYS) {
retrieveData();
}
});
return (
<FlatList
data={ids}
refreshing={isLoading}
onRefresh={retrieveData}
getItemLayout={getItemLayout}
ref={listRef}
keyExtractor={(item, index) => `${item}_${index}`}
renderItem={generateItem}
/>
);
}
Example #9
Source File: Overview.tsx From BitcoinWalletMobile with MIT License | 4 votes |
Overview: React.FC<Props> = (props) => {
const dispatch = useDispatch()
var opacityRef = useRef(new Animated.Value(0)).current
const mounted = useRef(true)
const opacity = opacityRef.interpolate({ inputRange: [80, 150], outputRange: [0, 1] })
const [isRefreshing, setIsRefreshing] = useState(false)
const isSyncingSelector = (state: WalletState) => state.isSyncing
const isSyncing = useSelector(isSyncingSelector)
const transactionsSelector = (state: WalletState) => state.transactions
const transactions = useSelector(transactionsSelector)
const multiDeviceSupportSelector = (state: WalletState) => state.multiDeviceSupport
const multiDeviceSupport = useSelector(multiDeviceSupportSelector)
const isRestoringSelector = (state: WalletState) => state.isRestoring
const isWalletRestoring = useSelector(isRestoringSelector)
const isNewWalletSelector = (state: WalletState) => state.newlyCreated
const isNewWallet = useSelector(isNewWalletSelector)
const balanceSelector = (state: WalletState) => state.balance
const balance = useSelector(balanceSelector)
const currencySelector = (state: WalletState) => state.currency
const currency = useSelector(currencySelector)
let canGetRates = true
const rateSelector = (state: WalletState) => {
if (state.fiatRates[currency] != undefined) {
return state.fiatRates[currency].last
}
else {
canGetRates = false
return 0
}
}
const rate = useSelector(rateSelector)
const langSelector = (state: WalletState) => state.language
const language = useSelector(langSelector)
const pushSend = () => {
props.navigation.dangerouslyGetParent()?.navigate('Send')
}
const pushReceive = () => {
props.navigation.navigate('Receive')
}
const btcToFiat = () => {
let fiat = new BigNumber(balance).multipliedBy(rate).toFixed(2)
if (isNaN(parseFloat(fiat))) {
fiat = "0";
}
if (!canGetRates) {
return "N/A"
}
return new Intl.NumberFormat(language, { style: 'currency', currency: currency }).format(parseFloat(fiat));
}
const syncWallet = async (smallSync = true) => {
await wallet.synchronize(smallSync)
}
useEffect(() => {
// Refresh every 10 minutes with a mini-sync
const interval = setInterval(() => {
syncWallet(!multiDeviceSupport)
}, 600000);
}, [])
const renderItem: ListRenderItem<Transaction> = ({ item }) => (
<TransactionView transaction={item} />
);
const insets = useSafeAreaInsets()
return (
<View style={styles.container}>
<View style={styles.headerContainer}>
<View style={{ marginTop: insets.top, height: 56 }}>
<View style={styles.textContain}>
<Text style={styles.headerText}>{getTranslated(language).overview}</Text>
<Animated.View style={{ opacity: opacity }}>
<View style={styles.btcBalanceRow}>
<Text style={styles.totalBalance}>{getTranslated(language).total_balance}:</Text>
<Text style={styles.btcBalance}>{balance.toString()}</Text>
<Text style={styles.currencyText}>BTC</Text>
</View>
<View style={styles.fiatBalanceRow}>
<Text style={styles.fiatBalance}>{btcToFiat()}</Text>
<Text style={styles.currencyText}>{currency}</Text>
</View>
</Animated.View>
</View>
</View>
</View>
<Screen>
<View style={styles.listContainer}>
<Animated.FlatList
data={transactions}
ListHeaderComponent={<BalanceCard numOfTransaction={transactions.length} isRefreshing={isSyncing} receiveAction={pushReceive} sendAction={pushSend} refreshAction={() => syncWallet(!multiDeviceSupport)} />}
renderItem={renderItem}
showsVerticalScrollIndicator={false}
keyExtractor={item => item.hash}
onScroll={Animated.event([{ nativeEvent: { contentOffset: { y: opacityRef } } }], { useNativeDriver: true })} />
{transactions.length == 0 &&
<View style={styles.noTransactions}>
<Text style={styles.noTransactionsText}>{getTranslated(language).no_transactions}</Text>
</View>
}
</View>
</Screen>
</View>
);
}
Example #10
Source File: Settings.tsx From BitcoinWalletMobile with MIT License | 4 votes |
Settings: React.FC<Props> = (props) => {
const [recoveryWordsModalVisible, setrecoveryWordsModalVisible] = useState(false)
const [exitModalVisible, setExitModalVisible] = useState(false)
const languageSelector = (state: WalletState) => state.language
const language = useSelector(languageSelector)
const currencySelector = (state: WalletState) => state.currency
const currency = useSelector(currencySelector)
const data = [getTranslated(language).currency, getTranslated(language).language, getTranslated(language).seed_phrase, "Support multiple devices", getTranslated(language).exit_wallet]
const clearAndDelete = async () => {
setExitModalVisible(false)
store.dispatch(clearWallet())
}
const showRecoveryWordsModal = () => {
setrecoveryWordsModalVisible(true)
}
const hideRecoveryWordsModal = () => {
setrecoveryWordsModalVisible(false)
}
const showExitModal = () => {
setExitModalVisible(true)
}
const hideExitModal = () => {
setExitModalVisible(false)
}
const pushCurrency = () => {
// @ts-ignore
props.navigation.navigate('PickerView', { type: "Choose Currency" })
}
const pushLanguage = () => {
// @ts-ignore
props.navigation.navigate('PickerView', { type: "Choose Language" })
}
interface ChildProps {
item: string
}
const conditonalView: React.FC<ChildProps> = ({ item }) => {
if (item == getTranslated(language).currency) {
return <View style={{ marginTop: 20 }}><SettingsItem label={getTranslated(language).currency} subLabel={currency} onClick={pushCurrency} /></View>
}
if (item == getTranslated(language).seed_phrase) {
return <View style={{ marginTop: 50 }}><SettingsItem label={getTranslated(language).seed_phrase} subLabel="" onClick={showRecoveryWordsModal} /></View>
}
if (item == getTranslated(language).exit_wallet) {
return <View style={{ marginTop: 50 }}><SettingsItem label={getTranslated(language).exit_wallet} subLabel="" onClick={showExitModal} /></View>
}
if (item == "Support multiple devices") {
return <SettingsItem label="Support multiple devices" subLabel="" onClick={() => { }} />
}
else {
return <SettingsItem label={getTranslated(language).language} subLabel={getLanguageBigName(language)} onClick={pushLanguage} />
}
}
const renderItem: ListRenderItem<string> = ({ item }) => (
conditonalView({ item: item })
)
return (
<View style={styles.container}>
<Header screen={getTranslated(language).settings} />
<Screen>
<View style={styles.content}>
<FlatList data={data}
renderItem={renderItem}
keyExtractor={item => item} />
<RecoveryWordsModal isVisible={recoveryWordsModalVisible} hideModal={hideRecoveryWordsModal} />
<ExitWalletModal isVisible={exitModalVisible} hideModal={hideExitModal} deleteCallback={clearAndDelete} />
</View>
</Screen>
</View>
);
}
Example #11
Source File: Onboarding.tsx From mobile with Apache License 2.0 | 4 votes |
OnboardingScreen = () => {
const navigation = useNavigation();
const {width: viewportWidth} = useWindowDimensions();
const carouselRef = useRef<Carousel<OnboardingKey>>(null);
const [currentStep, setCurrentStep] = useState(0);
const i18n = useI18n();
const {setOnboarded, setOnboardedDatetime} = useStorage();
const startExposureNotificationService = useStartExposureNotificationService();
const isStart = currentStep === 0;
const isEnd = currentStep === onboardingData.length - 1;
const {isScreenReaderEnabled} = useAccessibilityService();
const currentStepForRenderItem = isScreenReaderEnabled ? currentStep : -1;
const renderItem: ListRenderItem<OnboardingKey> = useCallback(
({item, index}) => {
return (
<View style={styles.flex} accessibilityElementsHidden={index !== currentStepForRenderItem}>
<OnboardingContent key={item} item={item} isActive={index === currentStepForRenderItem} />
</View>
);
},
[currentStepForRenderItem],
);
const onSnapToNewPage = useCallback(
async (index: number) => {
// we want the EN permission dialogue to appear on the last step.
if (index === onboardingData.length - 1) {
try {
await startExposureNotificationService();
} catch (error) {
if (error.message === 'API_NOT_CONNECTED') {
navigation.reset({
index: 0,
routes: [{name: 'ErrorScreen'}],
});
}
}
}
},
[navigation, startExposureNotificationService],
);
const nextItem = useCallback(async () => {
if (isEnd) {
await setOnboarded(true);
await setOnboardedDatetime(getCurrentDate());
navigation.reset({
index: 0,
routes: [{name: 'Home'}],
});
return;
}
carouselRef.current?.snapToNext();
}, [isEnd, navigation, setOnboarded, setOnboardedDatetime]);
const prevItem = useCallback(() => {
carouselRef.current?.snapToPrev();
}, []);
const onSnapToItem = useCallback(
(newIndex: number) => {
setCurrentStep(newIndex);
onSnapToNewPage(newIndex);
},
[onSnapToNewPage],
);
return (
<Box backgroundColor="overlayBackground" flex={1}>
<SafeAreaView style={styles.flex}>
<View style={styles.flex}>
<Carousel
ref={carouselRef}
data={onboardingData}
renderItem={renderItem}
sliderWidth={viewportWidth}
itemWidth={viewportWidth}
onSnapToItem={onSnapToItem}
importantForAccessibility="no"
accessible={false}
initialNumToRender={1}
/>
</View>
<Box flexDirection="row" borderTopWidth={2} borderTopColor="gray5">
<Box flex={0} style={{...styles.offset1}}>
{!isStart && (
<Button text={i18n.translate(`Onboarding.ActionBack`)} variant="navigation" onPress={prevItem} />
)}
</Box>
<Box flex={2} justifyContent="center" style={{...styles.offset2}}>
<ProgressCircles numberOfSteps={onboardingData.length} activeStep={currentStep + 1} marginBottom="none" />
</Box>
<Box flex={0} style={{...styles.offset3}}>
<Button
color="bodyTextWhite"
testID="onboardingNextButton"
text={i18n.translate(`Onboarding.Action${isEnd ? 'End' : 'Next'}`)}
variant="navigation"
onPress={nextItem}
/>
</Box>
</Box>
</SafeAreaView>
</Box>
);
}
Example #12
Source File: Tutorial.tsx From mobile with Apache License 2.0 | 4 votes |
TutorialScreen = () => {
const navigation = useNavigation();
const {width: viewportWidth} = useWindowDimensions();
const carouselRef = useRef<Carousel<TutorialKey>>(null);
const [currentStep, setCurrentStep] = useState(0);
const i18n = useI18n();
const close = useCallback(() => navigation.goBack(), [navigation]);
const isStart = currentStep === 0;
const isEnd = currentStep === tutorialData.length - 1;
const {isScreenReaderEnabled} = useAccessibilityService();
const currentStepForRenderItem = isScreenReaderEnabled ? currentStep : -1;
const renderItem: ListRenderItem<TutorialKey> = useCallback(
({item, index}) => {
return (
<View style={styles.flex} accessibilityElementsHidden={index !== currentStepForRenderItem}>
<TutorialContent key={item} item={item} isActive={index === currentStepForRenderItem} />
</View>
);
},
[currentStepForRenderItem],
);
const nextItem = useCallback(() => {
if (isEnd) {
close();
return;
}
carouselRef.current?.snapToNext();
}, [close, isEnd]);
const prevItem = useCallback(() => {
carouselRef.current?.snapToPrev();
}, []);
const onSnapToItem = useCallback((newIndex: number) => {
setCurrentStep(newIndex);
}, []);
return (
<Box backgroundColor="overlayBackground" flex={1}>
<SafeAreaView style={styles.flex}>
<Toolbar
title=""
navIcon="icon-back-arrow"
navText={i18n.translate('Tutorial.Close')}
navLabel={i18n.translate('Tutorial.Close')}
onIconClicked={close}
/>
<View style={styles.flex}>
<Carousel
ref={carouselRef}
data={tutorialData}
renderItem={renderItem}
sliderWidth={viewportWidth}
itemWidth={viewportWidth}
onSnapToItem={onSnapToItem}
importantForAccessibility="no"
accessible={false}
removeClippedSubviews={false}
/>
</View>
<Box flexDirection="row" borderTopWidth={2} borderTopColor="gray5">
<Box flex={0} style={{...styles.offset1}}>
{!isStart && (
<Button text={i18n.translate(`Tutorial.ActionBack`)} variant="navigation" onPress={prevItem} />
)}
</Box>
<Box flex={2} justifyContent="center" style={{...styles.offset2}}>
<ProgressCircles numberOfSteps={tutorialData.length} activeStep={currentStep + 1} marginBottom="none" />
</Box>
<Box flex={0} style={{...styles.offset3}}>
<Button
testID="howItWorksNextButton"
text={i18n.translate(`Tutorial.Action${isEnd ? 'End' : 'Next'}`)}
variant="navigation"
onPress={nextItem}
/>
</Box>
</Box>
</SafeAreaView>
</Box>
);
}
Example #13
Source File: DayStrip.tsx From nyxo-app with GNU General Public License v3.0 | 4 votes |
CalendarStrip: FC = () => {
const { selectDate, selectedDate } = useCalendar()
const flatListRef = useRef<FlatList>(null)
const [init, setInit] = useState(true)
const dispatch = useAppDispatch()
const startDate = new Date()
const days = Array.from(Array(365 * 3)).map((_, index) =>
startOfDay(sub(startDate, { days: index }))
)
const toggleCalendar = () => {
dispatch(toggleCalendarModal(true))
}
const renderItem: ListRenderItem<Date> = ({ item, index }) => (
<PressableContainer key={item.toISOString()} onPress={toggleCalendar}>
<Day isFirst={index === 0}>
<DateContainer isFirst={index === 0}>
{localizedFormat(item, 'EEE d. LLL')}
</DateContainer>
</Day>
</PressableContainer>
)
const handleViewableItemsChanged = ({
viewableItems
}: {
viewableItems: Array<ViewToken>
}) => {
if (viewableItems.length === 1) {
const date = viewableItems[0].item
selectDate(date)
}
}
const handleViewableItemsChangedRef = useRef(handleViewableItemsChanged)
const viewabilityConfig = {
itemVisiblePercentThreshold: 85,
minimumViewTime: 750
}
const keyExtractor = (item: Date) => item.toISOString()
const scrollToItem = (index: number) => {
return flatListRef?.current?.scrollToIndex({
index,
animated: true,
viewPosition: 0.5
})
}
useEffect(() => {
if (!init) {
const index = days.findIndex((date) =>
isSameDay(date, new Date(selectedDate))
)
if (index >= 0) {
scrollToItem(index)
}
} else {
setInit(false)
}
}, [days, init, selectedDate])
const getItemLayout = (_: unknown, index: number) => {
if (index === 0) {
return {
index,
length: FIRST_DAY_WIDTH,
offset: 0
}
}
return {
index,
length: DAY_WIDTH,
offset: FIRST_DAY_WIDTH + DAY_WIDTH * index - DAY_WIDTH
}
}
const snapOffsets = days.map((_, index) => {
if (index === 0) {
return DAY_WIDTH
}
return DAY_WIDTH * (index + 1)
})
return (
<Container>
<FlatList
ref={flatListRef}
showsHorizontalScrollIndicator={false}
inverted
snapToStart
horizontal
getItemLayout={getItemLayout}
keyExtractor={keyExtractor}
viewabilityConfig={viewabilityConfig}
onViewableItemsChanged={handleViewableItemsChangedRef.current}
decelerationRate="fast"
snapToOffsets={snapOffsets}
data={days}
renderItem={renderItem}
/>
<Gradient pointerEvents="box-none" />
</Container>
)
}
Example #14
Source File: settings.tsx From nyxo-app with GNU General Public License v3.0 | 4 votes |
SettingsScreen: FC<Props> = ({ navigation }) => {
const theme = useAppSelector((state) => state.theme.theme)
const rateApp = () => {
// FIXME
Rate.rate(options, () => undefined)
}
const displayTheme = (t: string) => (t === 'dark' ? 'Light' : 'Dark')
const settings = [
{
text: 'Select Tracking Source',
icon: 'smartWatchCircleGraph',
action: () => navigation.navigate('Sources')
},
{
text: 'Coaching settings',
icon: 'schoolPhysicalBold',
action: () => navigation.navigate('Coaching')
},
{
text: 'Manage Nyxo Subscription',
icon: 'receipt',
action: () => navigation.navigate('Subscription')
},
{
text: 'Sync to backend',
icon: 'syncCloud',
action: () => navigation.navigate('Cloud', { code: '' })
},
{
text: 'Switch mode',
icon: 'astronomyMoon',
theme: displayTheme(theme),
action: () => navigation.push('Theme')
},
{
text: 'RATE_APP',
icon: 'star',
action: rateApp
},
{
text: 'ONBOARDING.TITLE',
icon: 'compass',
action: () => navigation.push('Onboarding')
}
]
const socialActions = [
{
text: 'Send feedback',
icon: 'envelope',
action: () => Linking.openURL('mailto:[email protected]')
},
{
text: 'Visit site',
icon: 'browserDotCom',
action: () => Linking.openURL('https://nyxo.app/')
},
{
text: 'Follow us on Facebook',
icon: 'facebook',
action: () =>
Linking.openURL('https://www.facebook.com/Nyxo-467927177117033/')
},
{
text: 'Follow us on Twitter',
icon: 'twitter',
action: () => Linking.openURL('https://twitter.com/hellonyxo')
},
{
text: 'Follow us on Instagram',
icon: 'instagram',
action: () => Linking.openURL('https://www.instagram.com/hellonyxo/')
},
{
text: 'Terms of Service',
icon: 'handshake',
action: () => Linking.openURL(CONFIG.TERMS_LINK)
},
{
text: 'Privacy Policy',
icon: 'lockCircle',
action: () => Linking.openURL(CONFIG.PRIVACY_LINK)
}
]
const renderItem: ListRenderItem<SettingItem> = ({ item }) => {
if (!item) return null
return (
<SettingRow onPress={item.action} badge={item.badge} icon={item.icon}>
<Title>{`${item.text}`}</Title>
</SettingRow>
)
}
const renderSectionHeader = ({
section
}: {
section: SectionListData<SettingItem, { title: string }>
}) => {
if (section.title === 'Settings') return null
return <SectionHeader>{section.title}</SectionHeader>
}
const sections = [
{
title: 'Settings',
data: settings
},
{
title: 'Support',
data: socialActions
}
]
return (
<SafeAreaView>
<SectionList
ListHeaderComponent={<PageTitle>Settings</PageTitle>}
sections={sections}
renderSectionHeader={renderSectionHeader}
keyExtractor={keyExtractor}
renderItem={renderItem}
ListFooterComponent={<VersionInformation />}
/>
</SafeAreaView>
)
}