react-native#RefreshControl TypeScript Examples
The following examples show how to use
react-native#RefreshControl.
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: scrollable.tsx From protect-scotland with Apache License 2.0 | 6 votes |
Scrollable: FC<LayoutProps> = ({
toast,
backgroundColor,
refresh,
scrollViewRef,
safeArea = true,
children,
contentContainerStyle,
scrollableStyle = {},
importantForAccessibility = 'auto'
}) => {
const insets = useSafeAreaInsets();
const refreshControl = refresh && <RefreshControl {...refresh} />;
return (
<Container style={[!!backgroundColor && {backgroundColor}]}>
<ScrollView
ref={scrollViewRef}
keyboardShouldPersistTaps="always"
style={scrollableStyle}
importantForAccessibility={importantForAccessibility}
contentContainerStyle={[
styles.scrollView,
{paddingBottom: (safeArea ? insets.bottom : 0) + SPACING_BOTTOM},
contentContainerStyle
]}
refreshControl={refreshControl}>
{toast && (
<>
{toast}
<Spacing s={8} />
</>
)}
{children}
</ScrollView>
</Container>
);
}
Example #2
Source File: News.tsx From wuhan2020-frontend-react-native-app with MIT License | 6 votes |
function NewsScreen() {
const { data, loading, fetchMore, refresh } = useContext(NewsDataContext);
const [refreshing, setRefreshing] = useState(false);
const onRefresh = useCallback(() => {
setRefreshing(true);
refresh();
wait(2000).then(() => setRefreshing(false));
}, [refreshing, refresh]);
const news = uniqBy(data || [], 'sourceId');
return (
<StatusBarSafeLayout>
<View style={styles.constainer}>
<H1 title="新闻汇总" />
</View>
<ScrollView
refreshControl={
<RefreshControl
tintColor="pink"
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
onMomentumScrollEnd={fetchMore}>
{news.map((entry: EntryPropsType) => (
<Entry key={entry.sourceId} {...entry} />
))}
{loading ? <ActivityIndicator size="large" color="red" /> : null}
</ScrollView>
</StatusBarSafeLayout>
);
}
Example #3
Source File: Logistic.tsx From wuhan2020-frontend-react-native-app with MIT License | 6 votes |
function LogisticLayout() {
const [data, , loading, refresh] = useWuhan2020<LogisticalType>('logistical');
const [refreshing, setRefreshing] = useState(false);
const logistics: LogisticalType[] = data || [];
function onRefresh() {
setRefreshing(true);
refresh();
wait(2000).then(() => {
setRefreshing(false);
});
}
function renderItem({ item }: { item: LogisticalType }) {
return <Logistic item={item} />;
}
return (
<StatusBarSafeLayout>
<FlatList
refreshControl={
<RefreshControl
tintColor="red"
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
keyExtractor={(item: LogisticalType) => String(item.id)}
data={logistics}
renderItem={renderItem}
ListFooterComponent={loading ? <Loader /> : null}
/>
</StatusBarSafeLayout>
);
}
Example #4
Source File: PostList.tsx From lexicon with MIT License | 6 votes |
PostList = forwardRef<Ref, Props>((props, ref) => {
const { navigate } = useNavigation();
const styles = useStyles();
const { colors } = useTheme();
const { onStartScroll, onStopScroll } = useUserEvent();
const {
data,
showLabel,
currentUser,
hasFooter = true,
numberOfLines = 0,
showImageRow = false,
style,
prevScreen,
onPressReply,
refreshing,
onRefresh,
likedTopic,
progressViewOffset = 0,
...otherProps
} = props;
const onPressAuthor = (username: string) => {
navigate('UserInformation', { username });
};
const getItem = (data: Array<Post>, index: number) => data[index];
const getItemCount = (data: Array<Post>) => data.length;
const keyExtractor = ({ id, topicId }: Post) =>
`post-${id === 0 ? topicId : id}`;
const renderItem = ({ item }: { item: Post }) => (
<PostItem
data={item}
postList={true}
showLabel={showLabel}
currentUser={currentUser}
hasFooter={hasFooter}
showImageRow={showImageRow}
style={styles.item}
numberOfLines={numberOfLines}
prevScreen={prevScreen}
onPressReply={onPressReply}
onPressAuthor={onPressAuthor}
likedTopic={likedTopic}
/>
);
return (
<VirtualizedList
ref={ref}
data={data}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
tintColor={colors.primary}
progressViewOffset={progressViewOffset}
/>
}
onScrollBeginDrag={onStartScroll}
onScrollEndDrag={onStopScroll}
keyExtractor={keyExtractor}
getItem={getItem}
getItemCount={getItemCount}
renderItem={renderItem}
initialNumToRender={5}
maxToRenderPerBatch={7}
windowSize={10}
style={[styles.container, style]}
{...otherProps}
/>
);
})
Example #5
Source File: devices.tsx From iotc-cpm-sample with MIT License | 6 votes |
function DeviceList(props: {
devices: IHealthDevice[];
connect: (deviceId: string) => Promise<void>;
refresh: () => void;
}) {
const [refreshing, setRefreshing] = useState(false);
const {devices, refresh, connect} = props;
if (devices.length == 0) {
return <NotFound retry={refresh} />;
}
return (
<View style={{flex: 4}}>
<Counter value={devices.length} />
<ScrollView
style={{flex: 1}}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={() => {
setRefreshing(true);
refresh();
// Hack! No need to restore refreshing state to false since
// component will be unmounted by the end of the scan process
}}
/>
}>
{devices.map(device => {
return <Device key={device.id} device={device} connect={connect} />;
})}
</ScrollView>
</View>
);
}
Example #6
Source File: CloudSettings.tsx From nyxo-app with GNU General Public License v3.0 | 5 votes |
CloudSettings: FC<Props> = ({ route }) => {
const dispatch = useAppDispatch()
const { authenticated, loading } = useAppSelector(({ auth }) => auth)
const linkingLoading = useAppSelector(({ linking }) => linking.loading)
const linkCode = route?.params?.code
const handleSignOut = () => {
dispatch(logout())
}
const refresh = async () => {
//FIXME
}
return (
<SafeAreaView>
<ScrollView
refreshControl={
<RefreshControl
tintColor={colors.darkBlue}
onRefresh={refresh}
refreshing={linkingLoading === 'pending'}
/>
}
scrollEventThrottle={16}>
<GoBackContainer>
<GoBack route="Settings" />
<Spacer />
</GoBackContainer>
<Container>
<H2>NYXO_CLOUD.TITLE</H2>
{!!authenticated && (
<>
<P>SCCloudInfo</P>
<LinkModule linkCode={linkCode} />
<PrimaryButton
white
title="Signout"
onPress={handleSignOut}
loading={loading === 'pending'}
/>
</>
)}
{!authenticated && <SignupBottomButton />}
</Container>
</ScrollView>
<CodeDisclaimer linkCode={linkCode} />
</SafeAreaView>
)
}
Example #7
Source File: MyLeave.tsx From orangehrm-os-mobile with GNU General Public License v3.0 | 5 votes |
render() {
const {theme, leaveRequests} = this.props;
return (
<SafeAreaLayout>
<FlatList
data={leaveRequests}
renderItem={({item}) => (
<MyLeaveListItem
leaveRequest={item}
onPress={this.onPressLeave(item)}
/>
)}
keyExtractor={(item) => item.id}
ItemSeparatorComponent={() => {
return (
<View style={{paddingHorizontal: theme.spacing}}>
<Divider />
</View>
);
}}
ListFooterComponent={
leaveRequests === undefined ||
leaveRequests?.length === 0 ? null : (
<View
style={{
paddingHorizontal: theme.spacing,
paddingBottom: theme.spacing * 4,
}}>
<Divider />
</View>
)
}
refreshControl={
<RefreshControl refreshing={false} onRefresh={this.onRefresh} />
}
contentContainerStyle={styles.contentContainer}
ListEmptyComponent={
leaveRequests !== undefined ? (
<View style={styles.emptyContentView}>
<Icon
name={'info-outline'}
type={'MaterialIcons'}
style={{
fontSize: theme.typography.largeIconSize,
paddingBottom: theme.spacing * 2,
marginTop: -theme.spacing * 2,
}}
/>
<Text>{'No Leave Requests Found.'}</Text>
</View>
) : null
}
/>
</SafeAreaLayout>
);
}
Example #8
Source File: LeaveList.tsx From orangehrm-os-mobile with GNU General Public License v3.0 | 5 votes |
render() {
const {theme, leaveList} = this.props;
return (
<SafeAreaLayout>
<FlatList
data={leaveList}
renderItem={({item}) => (
<>
<LeaveListItem
leaveRequest={item}
onPress={this.onPressLeave(item)}
/>
</>
)}
keyExtractor={(item) => item.leaveRequestId}
ItemSeparatorComponent={() => {
return (
<View style={{paddingHorizontal: theme.spacing}}>
<Divider />
</View>
);
}}
ListFooterComponent={
leaveList === undefined || leaveList?.length === 0 ? null : (
<View
style={{
paddingHorizontal: theme.spacing,
paddingBottom: theme.spacing * 4,
}}>
<Divider />
</View>
)
}
refreshControl={
<RefreshControl refreshing={false} onRefresh={this.onRefresh} />
}
contentContainerStyle={styles.contentContainer}
ListEmptyComponent={
leaveList !== undefined ? (
<View style={styles.emptyContentView}>
<Icon
name={'info-outline'}
type={'MaterialIcons'}
style={{
fontSize: theme.typography.largeIconSize,
paddingBottom: theme.spacing * 2,
marginTop: -theme.spacing * 2,
}}
/>
<Text>{'No Leave Requests Found.'}</Text>
</View>
) : null
}
/>
</SafeAreaLayout>
);
}
Example #9
Source File: MainLayout.tsx From orangehrm-os-mobile with GNU General Public License v3.0 | 5 votes |
MainLayout = (props: React.PropsWithChildren<MainLayoutProps>) => {
const {
theme,
children,
refreshing,
onRefresh,
footer,
header,
scrollViewProps,
statusBarBackgroundColor,
} = props;
return (
<>
<StatusBar
barStyle="dark-content"
backgroundColor={
statusBarBackgroundColor
? statusBarBackgroundColor
: theme.palette.statusBarSecondary
}
/>
<SafeAreaView
style={[styles.safeArea, {backgroundColor: theme.palette.background}]}>
{header === undefined ? null : header}
<ScrollView
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={styles.scrollView}
keyboardShouldPersistTaps="handled"
refreshControl={
onRefresh === undefined ? undefined : (
<RefreshControl
refreshing={refreshing === undefined ? false : refreshing}
onRefresh={onRefresh}
/>
)
}
{...scrollViewProps}>
{children}
</ScrollView>
{footer === undefined ? null : footer}
</SafeAreaView>
</>
);
}
Example #10
Source File: AttendanceList.tsx From orangehrm-os-mobile with GNU General Public License v3.0 | 5 votes |
render() {
const {theme, employeeList, weekStartDay} = this.props;
return (
<SafeAreaLayout>
<View
style={{
backgroundColor: theme.palette.backgroundSecondary,
paddingBottom: theme.spacing * 2,
}}>
<DatePeriodComponent
startDate={this.getWeekStartDate()}
endDate={this.getWeekEndDate()}
leftActive={true}
rightActive={this.state.startDayIndex !== weekStartDay}
onPressLeft={this.goLeft}
onPressRight={this.goRight}
/>
</View>
<FlatList
data={employeeList}
renderItem={({item}) => (
<>
<AttendanceListItem
employeeAttendance={item}
onPress={this.onPressLeave(item)}
/>
</>
)}
keyExtractor={(item) => item.employeeId}
ItemSeparatorComponent={() => {
return (
<View style={{paddingHorizontal: theme.spacing}}>
<Divider />
</View>
);
}}
ListFooterComponent={
employeeList === undefined || employeeList?.length === 0 ? null : (
<View
style={{
paddingHorizontal: theme.spacing,
paddingBottom: theme.spacing * 4,
}}>
<Divider />
</View>
)
}
refreshControl={
<RefreshControl refreshing={false} onRefresh={this.onRefresh} />
}
contentContainerStyle={styles.contentContainer}
ListEmptyComponent={
employeeList !== undefined ? (
<View style={styles.emptyContentView}>
<Icon
name={'info-outline'}
type={'MaterialIcons'}
style={{
fontSize: theme.typography.largeIconSize,
paddingBottom: theme.spacing * 2,
marginTop: -theme.spacing * 2,
}}
/>
<Text>{'No Records Found.'}</Text>
</View>
) : null
}
/>
</SafeAreaLayout>
);
}
Example #11
Source File: simpleRefreshListScreen.tsx From THUInfo with MIT License | 5 votes |
export function simpleRefreshListScreen<T>(
dataSource: (props: PropsWithChildren<any>) => Promise<T[]>,
renderItem: (
item: T,
refresh: () => void,
props: PropsWithChildren<any>,
theme: Theme,
index: number,
total: number,
) => ReactElement,
keyExtractor: (item: T) => string,
footer?: (theme: Theme) => ReactElement,
header?: (theme: Theme) => ReactElement,
empty?: (theme: Theme) => ReactElement,
initialNumToRender?: number,
): FC {
return (props) => {
const [data, setData] = useState<T[]>([]);
const [refreshing, setRefreshing] = useState(false);
const themeName = useColorScheme();
const theme = themes(themeName);
const refresh = () => {
setRefreshing(true);
dataSource(props)
.then(setData)
.catch(() =>
Snackbar.show({
text: getStr("networkRetry"),
duration: Snackbar.LENGTH_SHORT,
}),
)
.then(() => setRefreshing(false));
};
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(refresh, []);
return (
<FlatList
style={{flex: 1}}
data={data}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={refresh}
colors={[theme.colors.accent]}
/>
}
renderItem={({item, index}) =>
renderItem(item, refresh, props, theme, index, data.length)
}
keyExtractor={keyExtractor}
ListHeaderComponent={
data.length === 0 ? null : header ? header(theme) : undefined
}
ListFooterComponent={footer ? footer(theme) : undefined}
ListEmptyComponent={empty ? empty(theme) : undefined}
initialNumToRender={initialNumToRender}
/>
);
};
}
Example #12
Source File: ThreadList.tsx From make-a-fortune with MIT License | 5 votes |
ThreadList: React.FC<{
safeArea?: boolean;
}> = ({ safeArea }) => {
const [refreshing, setRefreshing] = useState(false);
const reloadLines = React.useCallback(() => {
setRefreshing(true);
wait(2000).then(() => {
setRefreshing(false);
});
}, []);
return (
<>
<Box safeAreaTop={safeArea} />
<FlatList
removeClippedSubviews
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={reloadLines} />
}
initialNumToRender={5}
data={data}
my={safeArea ? 12 : undefined}
renderItem={({ item }) => (
<VStack
borderColor="gray.100"
borderTopWidth={1}
py={4}
px={3}
alignSelf="center"
width={700}
maxWidth="100%"
key={item.id}
space={1}
bgColor="white"
>
<HStack space={2} alignItems="center">
<Badge>#23333</Badge>
<Badge>校园</Badge>
<Box mx="auto" />
<HStack space={1}>
<Icon
as={<MaterialCommunityIcons name="comment-outline" />}
color="black"
size="xs"
/>
<Text alignSelf="flex-end" fontSize="sm">
1
</Text>
</HStack>
</HStack>
<HStack space={1} alignItems="center">
<Text>{item.title}</Text>
</HStack>
<Text>{item.content}</Text>
</VStack>
)}
keyExtractor={item => item.id.toString()}
// ListHeaderComponent={
// <Box alignSelf="center">
// <Button
// startIcon={
// <Icon as={MaterialCommunityIcons} name="refresh" size={5} />
// }
// >
// 有新帖子
// </Button>
// </Box>
// }
/>
<Box safeAreaBottom={safeArea} />
</>
);
}
Example #13
Source File: ListView.tsx From rn-clean-architecture-template with MIT License | 5 votes |
ListView: ListViewFC = (props) => {
const {
refreshing,
ListFooterComponent,
data,
isLoadingMore,
LoadingComponent,
} = props;
const refreshIndicatorVisible =
refreshing === true && (data?.length ?? 0) > 0;
const skeletonDisplayable =
(refreshing && data?.length === 0) || isLoadingMore;
const emptyItem = () => {
if (refreshing) {
return null;
}
return <EmptyListView {...props.emptyListViewProps} />;
};
const footer = () => {
if (skeletonDisplayable) {
if (LoadingComponent) {
return LoadingComponent;
}
return (
<>
<SkeletonLoadingItem />
<SkeletonLoadingItem />
<SkeletonLoadingItem />
</>
);
}
return ListFooterComponent;
};
return (
<View style={[styles.container]}>
<FlatList
{...props}
ListEmptyComponent={emptyItem()}
ListFooterComponent={footer()}
refreshControl={
<RefreshControl
refreshing={refreshIndicatorVisible}
onRefresh={props.onRefresh}
/>
}
style={styles.list}
/>
</View>
);
}
Example #14
Source File: ManageSubscription.tsx From nyxo-app with GNU General Public License v3.0 | 5 votes |
ManageSubscription: FC = () => {
const loadingPurchase = useAppSelector((state) => state.subscription.loading)
const dispatch = useAppDispatch()
const [info, setEntitlements] = useState<
PurchasesEntitlementInfos | undefined
>()
const handleRestorePurchase = async () => {
await dispatch(restorePurchase())
}
const refetch = async () => {
const { entitlements } = await Purchases.getPurchaserInfo()
setEntitlements(entitlements)
}
useEffect(() => {
const fetchData = async () => {
const { entitlements } = await Purchases.getPurchaserInfo()
setEntitlements(entitlements)
}
fetchData()
}, [])
const hasActiveSubscription = info?.active['Nyxo Coaching']?.isActive
return (
<SafeAreaView>
<ScrollView
refreshControl={
<RefreshControl refreshing={loadingPurchase} onRefresh={refetch} />
}>
<GoBackContainer>
<GoBack />
</GoBackContainer>
<Container>
<H1>Manage Nyxo Subscription</H1>
<ActiveSubscriptions />
{!hasActiveSubscription && (
<>
<H2>RESTORE_PURCHASE</H2>
<P>RESTORE_PURCHASE_BODY</P>
<TextButton center onPress={handleRestorePurchase}>
RESTORE_PURCHASE
</TextButton>
</>
)}
</Container>
</ScrollView>
</SafeAreaView>
)
}
Example #15
Source File: Consultation.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function ConsultationLayout() {
const [data, , loading, refresh] = useWuhan2020<Clinic>('clinic');
const [refreshing, setRefreshing] = useState(false);
const clinics: Clinic[] = data || [];
function onRefresh() {
setRefreshing(true);
refresh();
wait(2000).then(() => {
setRefreshing(false);
});
}
function renderItem({ item }: { item: Clinic }) {
return <Consultation item={item} />;
}
return (
<StatusBarSafeLayout>
<FlatList
refreshControl={
<RefreshControl
tintColor="pink"
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
keyExtractor={(item: Clinic) => String(item.id)}
data={clinics}
renderItem={renderItem}
ListFooterComponent={
loading ? (
<View style={{ paddingTop: 20 }}>
<Loader />
</View>
) : null
}
/>
</StatusBarSafeLayout>
);
}
Example #16
Source File: Donation.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function DonationLayout() {
const [data, , loading, refresh] = useWuhan2020<DonationType>('donation');
const [refreshing, setRefreshing] = useState(false);
const donations: DonationType[] = data || [];
function onRefresh() {
setRefreshing(true);
refresh();
wait(2000).then(() => {
setRefreshing(false);
});
}
function renderItem({ item }: { item: DonationType }) {
return <Donation item={item} />;
}
return (
<StatusBarSafeLayout>
<FlatList
refreshControl={
<RefreshControl
tintColor="pink"
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
keyExtractor={(item: DonationType) => String(item.id)}
data={donations}
renderItem={renderItem}
ListFooterComponent={
loading ? (
<View style={{ paddingTop: 20 }}>
<Loader />
</View>
) : null
}
/>
</StatusBarSafeLayout>
);
}
Example #17
Source File: crHome.tsx From THUInfo with MIT License | 5 votes |
CrHomeScreen = ({navigation}: {navigation: RootNav}) => {
const [semesters, setSemesters] = useState<CrSemester[]>([]);
const [refreshing, setRefreshing] = useState(false);
const themeName = useColorScheme();
const {colors} = themes(themeName);
const refresh = () => {
setRefreshing(true);
helper
.getCrAvailableSemesters()
.then(setSemesters)
.catch((e) => {
if (e instanceof CrTimeoutError) {
navigation.navigate("CrCaptcha");
} else {
Snackbar.show({
text: getStr("networkRetry") + e?.message,
duration: Snackbar.LENGTH_SHORT,
});
}
})
.then(() => setRefreshing(false));
};
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(refresh, []);
return (
<FlatList
style={{flex: 1}}
data={semesters}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={refresh}
colors={[colors.accent]}
/>
}
renderItem={({item: {id, name}}) => (
<TouchableOpacity
onPress={() => navigation.navigate("CrCoursePlan", {semesterId: id})}
style={{
padding: 15,
flexDirection: "row",
justifyContent: "space-between",
}}>
<View style={{flex: 2, alignItems: "flex-start"}}>
<Text style={{fontSize: 16, marginVertical: 2, color: colors.text}}>
{name}
</Text>
<Text style={{color: "grey", marginVertical: 2}}>{id}</Text>
</View>
</TouchableOpacity>
)}
keyExtractor={({id}) => id}
/>
);
}
Example #18
Source File: Mobility.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function MobilityScreen() {
const { data, loading, refresh } = useContext(MobilityDataContext);
const [refreshing, setRefreshing] = useState(false);
function keyExtractor(item: EntryType) {
return String(item.id);
}
function renderItem({ item }: { item: EntryType }) {
return <Mobility item={item} />;
}
const onRefresh = useCallback(() => {
setRefreshing(true);
refresh();
wait(2000).then(() => setRefreshing(false));
}, [refreshing, refresh]);
return (
<StatusBarSafeLayout>
<View>
<SectionList
keyExtractor={keyExtractor}
refreshing={loading}
refreshControl={
<RefreshControl
tintColor="pink"
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
renderItem={renderItem}
sections={toSection(data)}
renderSectionHeader={({ section: { title } }) => (
<View style={{ backgroundColor: '#eee' }}>
<Text style={styles.subheader}>{title}</Text>
</View>
)}
ListEmptyComponent={<ActivityIndicator size="large" color="red" />}
ListHeaderComponent={
<View style={styles.header}>
<H1 title="确诊患者相同行程查询" />
</View>
}
/>
</View>
</StatusBarSafeLayout>
);
}
Example #19
Source File: Hospital.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function HospitalLayout() {
const [data, , loading, refresh] = useWuhan2020<HospitalType>('hospital');
const [refreshing, setRefreshing] = useState(false);
const hospitals: HospitalType[] = data || [];
function onRefresh() {
setRefreshing(true);
refresh();
wait(2000).then(() => {
setRefreshing(false);
});
}
function renderItem({ item }: { item: HospitalType }) {
return <Hospital item={item} />;
}
return (
<StatusBarSafeLayout>
<FlatList
refreshControl={
<RefreshControl
tintColor="pink"
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
keyExtractor={(item: HospitalType) => String(item.id)}
data={hospitals}
renderItem={renderItem}
ListFooterComponent={
loading ? (
<View style={{ paddingTop: 20 }}>
<Loader />
</View>
) : null
}
/>
</StatusBarSafeLayout>
);
}
Example #20
Source File: Hotel.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function HotelLayout() {
const [data, , loading, refresh] = useWuhan2020<TravelHotel>('travel_hotel');
const [refreshing, setRefreshing] = useState(false);
const hotels: HotelType[] = data || [];
function onRefresh() {
setRefreshing(true);
refresh();
wait(2000).then(() => {
setRefreshing(false);
});
}
function renderItem({ item }: { item: HotelType }) {
return <Hotel item={item} />;
}
return (
<StatusBarSafeLayout>
<FlatList
refreshControl={
<RefreshControl
tintColor="pink"
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
keyExtractor={(item: HotelType) => String(item.id)}
data={hotels}
renderItem={renderItem}
ListFooterComponent={
loading ? (
<View style={{ paddingTop: 20 }}>
<Loader />
</View>
) : null
}
/>
</StatusBarSafeLayout>
);
}
Example #21
Source File: expenditure.tsx From THUInfo with MIT License | 5 votes |
ExpenditureScreen = () => {
const [[expenditures, income, outgo, remainder], setExpenditures] = useState<
[Record[], number, number, number]
>([[], 0, 0, 0]);
const [beg, setBeg] = useState(dayjs().add(-1, "month").toDate());
const [end, setEnd] = useState(dayjs().toDate());
const [refreshing, setRefreshing] = useState(false);
const themeName = useColorScheme();
const theme = themes(themeName);
const refresh = () => {
setRefreshing(true);
helper
.getExpenditures(beg, end)
.then(setExpenditures)
.catch((e) => {
Snackbar.show({
text: getStr("networkRetry") + e?.message,
duration: Snackbar.LENGTH_SHORT,
});
})
.then(() => setRefreshing(false));
};
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(refresh, []);
return (
<View style={{padding: 10, flex: 1}}>
<View style={{flexDirection: "row"}}>
<Money title={getStr("income")} money={income} />
<Money title={getStr("outgo")} money={outgo} />
<Money title={getStr("remainder")} money={refreshing ? 0 : remainder} />
</View>
{!helper.mocked() && (
<View style={styles.header}>
<DatePickerTrigger
date={beg}
onChange={setBeg}
disabled={refreshing}
text={Platform.OS === "ios" ? getStr("begDate") : ""}
/>
<DatePickerTrigger
date={end}
onChange={setEnd}
disabled={refreshing}
text={Platform.OS === "ios" ? getStr("endDate") : ""}
/>
<Button
title={getStr("query")}
onPress={refresh}
disabled={refreshing}
/>
</View>
)}
<View style={styles.container}>
<FlatList
data={expenditures}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={refresh}
colors={[theme.colors.accent]}
/>
}
renderItem={({item}) => <ExpenditureCard record={item} />}
keyExtractor={(item, index) => `${item.date}-${item.value}-${index}`}
/>
</View>
</View>
);
}
Example #22
Source File: dashboard.tsx From protect-scotland with Apache License 2.0 | 4 votes |
Dashboard: FC = () => {
const {t} = useTranslation();
const {
initialised,
enabled,
status,
contacts,
getCloseContacts,
permissions,
readPermissions
} = useExposure();
const [appState] = useAppState();
const {checked, paused} = useReminder();
const navigation = useNavigation();
const {onboarded, setContext, loadAppData} = useApplication();
const {
isolationDuration,
isolationCompleteDuration,
latestVersion: appLatestVersion
} = useSettings();
const [refreshing, setRefreshing] = useState(false);
const {
focusRef: tourFocus,
focusA11yElement: focusTourElem
} = useA11yElement();
const {
focusRef: dashboardFocus,
focusA11yElement: focusDashboardElem
} = useA11yElement();
const isFocused = useIsFocused();
const messageOpacity = useRef(new Animated.Value(0)).current;
const contentOpacity = useRef(new Animated.Value(0)).current;
const gridOpacity = useRef(new Animated.Value(0)).current;
const exposureEnabled = useRef(enabled);
const bluetoothDisabled = useRef(
status.state === 'disabled' && status.type?.includes(StatusType.bluetooth)
);
const pushNotificationsDisabled = useRef(
permissions.notifications.status === 'not_allowed'
);
const [state, setState] = useState<{
stage: number;
exposurePrompt: boolean;
bluetoothPrompt: boolean;
pushNotificationsPrompt: boolean;
disabled: boolean;
current: string;
isolationMessage: string | null;
isolationComplete: boolean;
default: string;
messages: string[];
}>({
stage: onboarded ? -1 : 0,
exposurePrompt: false,
bluetoothPrompt: false,
pushNotificationsPrompt: false,
disabled: false,
current: t(
getMessage({
onboarded,
enabled,
status,
messages: t('dashboard:tour', {returnObjects: true}),
stage: onboarded ? -1 : 0,
paused
})
),
isolationMessage: null,
isolationComplete: false,
messages: t('dashboard:tour', {returnObjects: true}),
default: t('dashboard:message:standard')
});
const version = useVersion();
const resetToNormal = () =>
setState((s) => ({
...s,
isolationComplete: false,
isolationMessage: null
}));
const setExposed = () =>
setState((s) => ({
...s,
isolationComplete: false,
isolationMessage: t('dashboard:exposed')
}));
const setIsolationComplete = () =>
setState((s) => ({
...s,
isolationComplete: true,
isolationMessage: t('dashboard:isolationComplete')
}));
const processContactsForMessaging = async () => {
let currentStatus = null;
try {
currentStatus = await SecureStore.getItemAsync('niexposuredate');
} catch (err) {
await SecureStore.deleteItemAsync('niexposuredate');
console.log('processContactsForMessaging', err);
}
if (currentStatus) {
const daysDiff = differenceInCalendarDays(
new Date(),
new Date(Number(currentStatus))
);
const withIsolation = isolationDuration + isolationCompleteDuration;
if (daysDiff >= withIsolation) {
await SecureStore.deleteItemAsync('niexposuredate');
return resetToNormal();
}
if (daysDiff >= isolationDuration && daysDiff < withIsolation) {
return setIsolationComplete();
}
if (contacts && contacts.length > 0) {
return setExposed();
}
}
return resetToNormal();
};
const checkLatestExposure = async () => {
const latestExposure = getExposureDate(contacts);
if (latestExposure) {
await SecureStore.setItemAsync(
'niexposuredate',
String(latestExposure.getTime())
);
}
processContactsForMessaging();
};
const onRefresh = () => {
setRefreshing(true);
loadAppData().then(() => setRefreshing(false));
};
useEffect(() => {
onRefresh();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
getCloseContacts();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [status]);
useEffect(() => {
checkLatestExposure();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [contacts, status]);
useFocusEffect(
React.useCallback(() => {
if (!isFocused || appState !== 'active') {
return;
}
readPermissions();
}, [isFocused, appState, readPermissions])
);
useEffect(() => {
setState((s) => ({
...s,
current: t(
getMessage({
onboarded,
enabled,
status,
messages: state.messages,
stage: state.stage,
paused
})
)
}));
exposureEnabled.current = enabled;
bluetoothDisabled.current =
status.state === 'disabled' &&
status.type?.includes(StatusType.bluetooth);
pushNotificationsDisabled.current =
permissions.notifications.status === 'not_allowed';
if (!exposureEnabled.current && onboarded) {
setTimeout(() => {
if (!exposureEnabled.current) {
setState((s) => ({
...s,
exposurePrompt: true
}));
}
}, PROMPT_OFFSET);
} else if (bluetoothDisabled.current && onboarded) {
setTimeout(() => {
if (bluetoothDisabled.current) {
setState((s) => ({
...s,
bluetoothPrompt: true
}));
}
}, PROMPT_OFFSET);
} else if (pushNotificationsDisabled.current && onboarded) {
setTimeout(() => {
if (
pushNotificationsDisabled.current &&
exposureEnabled.current &&
!bluetoothDisabled.current
) {
setState((s) => ({
...s,
pushNotificationsPrompt: true
}));
}
}, PROMPT_OFFSET);
} else if (onboarded && exposureEnabled.current) {
setState((s) => ({
...s,
exposurePrompt: false
}));
}
setTimeout(() => checkLatestExposure(), 100);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [enabled, onboarded, status, permissions]);
const animateTourIn = () => {
setState((s) => ({...s, disabled: true}));
Animated.parallel([
Animated.timing(messageOpacity, {
toValue: 1,
duration: ANIMATION_DURATION,
useNativeDriver: true
}),
Animated.timing(gridOpacity, {
toValue: 1,
duration: ANIMATION_DURATION,
useNativeDriver: true
})
]).start(() => {
setState((s) => ({...s, disabled: false}));
});
};
const animateTourOut = () => {
setState((s) => ({...s, disabled: true}));
Animated.parallel([
Animated.timing(messageOpacity, {
toValue: 0,
duration: ANIMATION_DURATION,
useNativeDriver: true
}),
Animated.timing(gridOpacity, {
toValue: 0,
duration: ANIMATION_DURATION,
useNativeDriver: true
})
]).start(() => {
if (state.stage < state.messages.length - 1) {
setState((s) => ({
...s,
stage: state.stage + 1,
current: getMessage({
onboarded,
enabled,
status,
messages: state.messages,
stage: state.stage + 1
})
}));
animateTourIn();
} else {
setState((s) => ({
...s,
stage: -1,
current: s.default
}));
setContext({onboarded: true});
animateDashboard();
}
});
};
const animateDashboard = () => {
setState((s) => ({...s, disabled: true}));
Animated.parallel([
Animated.timing(messageOpacity, {
toValue: 1,
duration: ANIMATION_DURATION,
useNativeDriver: true
}),
Animated.timing(contentOpacity, {
toValue: 1,
duration: ANIMATION_DURATION,
useNativeDriver: true
}),
Animated.timing(gridOpacity, {
toValue: 1,
duration: ANIMATION_DURATION,
useNativeDriver: true
})
]).start(() => {
AsyncStorage.setItem('scot.onboarded', 'true');
setState((s) => ({...s, disabled: false}));
});
};
useEffect(() => {
if (onboarded) {
setTimeout(() => animateDashboard(), 200);
} else {
setTimeout(() => animateTourIn(), 200);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
if (!state.disabled) {
focusTourElem();
}
}, [focusTourElem, state.disabled]);
useEffect(() => {
if (onboarded && !state.disabled) {
focusDashboardElem();
}
}, [focusDashboardElem, onboarded, state.disabled]);
const handleTour = () => {
animateTourOut();
};
if (!initialised || !checked) {
return (
<>
<Container center="both">
<ActivityIndicator color={colors.darkGrey} size="large" />
</Container>
</>
);
}
return (
<>
<Header />
<ScrollView
refreshControl={
<RefreshControl
refreshing={onboarded && refreshing}
onRefresh={onRefresh}
/>
}>
{onboarded &&
appLatestVersion &&
version &&
appLatestVersion !== version?.display && (
<View style={blockStyles.block}>
<NewVersionCard />
<Spacing s={16} />
</View>
)}
<Spacing s={onboarded ? 15 : 65} />
{!onboarded && state.stage > -1 && (
<>
<View style={styles.dots}>
{[-1, 0, 1, 2].map((x) => (
<Animated.View
key={`step-${x}`}
style={[
styles.dot,
{
backgroundColor:
state.stage > x
? colors.primaryPurple
: colors.lighterPurple
}
]}
/>
))}
</View>
<A11yView
ref={tourFocus}
accessible
accessibilityHint={
t('dashboard:tourA11y', {returnObjects: true})[state.stage]
}
/>
<Animated.View style={{opacity: messageOpacity}}>
<TouchableWithoutFeedback onPress={() => handleTour()}>
<Markdown markdownStyles={markDownStyles}>
{state.current}
</Markdown>
</TouchableWithoutFeedback>
<Spacing s={30} />
<ArrowLink
onPress={() => {
if (!state.disabled) {
handleTour();
}
}}
accessibilityHint={t('dashboard:tourActionHint')}
invert>
<Text variant="h3" color="pink" style={styles.nextLink}>
{t('dashboard:tourAction')}
</Text>
</ArrowLink>
</Animated.View>
</>
)}
{onboarded && state.isolationMessage && (
<>
<Animated.View
style={{
opacity: messageOpacity
}}>
<View accessible ref={dashboardFocus}>
<Markdown
markdownStyles={
state.isolationComplete
? markDownStyles
: markDownStylesExposed
}>
{state.isolationMessage}
</Markdown>
</View>
{!state.isolationComplete && (
<>
<Spacing s={30} />
<ArrowLink
onPress={() =>
navigation.navigate(ScreenNames.closeContact)
}
accessibilityHint={t('dashboard:exposedAction')}
invert>
<Text variant="h3" color="pink" style={styles.nextLink}>
{t('dashboard:tourAction')}
</Text>
</ArrowLink>
</>
)}
{state.isolationComplete && (
<>
<Spacing s={20} />
<Text style={blockStyles.block} inline color="darkGrey">
{t('dashboard:isolationCompleteSupplemental')}
</Text>
</>
)}
</Animated.View>
<Spacing s={30} />
<Animated.View
style={[{opacity: contentOpacity}, blockStyles.block]}>
<Message />
</Animated.View>
</>
)}
{onboarded && !state.isolationMessage && (
<Animated.View style={{opacity: messageOpacity}}>
<View accessible ref={dashboardFocus}>
<Markdown markdownStyles={markDownStyles}>
{state.current}
</Markdown>
</View>
{state.stage === -1 && !paused && (
<>
<Spacing s={20} />
<Text style={blockStyles.block} inline color="darkGrey">
{t(`dashboard:message:bluetooth:${Platform.OS}`)}
</Text>
</>
)}
{state.stage === -1 && paused && (
<>
<Spacing s={20} />
<Text style={blockStyles.block} inline color="darkGrey">
{t('dashboard:message:pausedSupplemental')}
</Text>
</>
)}
</Animated.View>
)}
<Spacing s={30} />
<Grid
onboarded={onboarded}
stage={state.stage}
opacity={gridOpacity}
onboardingCallback={() => handleTour()}
/>
{state.isolationMessage && <Spacing s={34} />}
{onboarded && !state.isolationMessage && (
<>
<Animated.View
style={[{opacity: contentOpacity}, blockStyles.block]}>
<Spacing s={30} />
<Message />
<Spacing s={16} />
<Message
image={RestrictionsImage}
markdown={t('restrictions:message')}
accessibilityLabel={t('restrictions:a11y:label')}
accessibilityHint={t('restrictions:a11y:hint')}
link={t('links:r')}
/>
<Spacing s={45} />
</Animated.View>
</>
)}
{onboarded && (
<Text variant="h4" color="primaryPurple" align="center">
{t('dashboard:thanks')}
</Text>
)}
<Spacing s={60} />
</ScrollView>
{checked && !paused && state.exposurePrompt && (
<ExposureNotificationsModal
isVisible={state.exposurePrompt}
onBackdropPress={() =>
setState((s) => ({...s, exposurePrompt: false}))
}
onClose={() => setState((s) => ({...s, exposurePrompt: false}))}
/>
)}
{checked && !paused && state.bluetoothPrompt && (
<BluetoothNotificationsModal
isVisible={state.bluetoothPrompt}
onBackdropPress={() =>
setState((s) => ({...s, bluetoothPrompt: false}))
}
onClose={() => setState((s) => ({...s, bluetoothPrompt: false}))}
/>
)}
{checked && !paused && state.pushNotificationsPrompt && (
<PushNotificationsModal
isVisible={state.pushNotificationsPrompt}
onBackdropPress={() =>
setState((s) => ({...s, pushNotificationsPrompt: false}))
}
onClose={() =>
setState((s) => ({...s, pushNotificationsPrompt: false}))
}
/>
)}
</>
);
}
Example #23
Source File: PickEmployee.tsx From orangehrm-os-mobile with GNU General Public License v3.0 | 4 votes |
render() {
const {theme, route, navigation, employees} = this.props;
const {textValue, setTextValue, onRefresh} = route.params;
let filteredData;
if (textValue !== '') {
const filterFn = this.filterFunction(textValue);
filteredData = employees?.filter(filterFn);
} else {
filteredData = employees;
}
const paddingRight = theme.spacing * 6;
return (
<SafeAreaLayout>
<View
style={[
styles.flex,
{backgroundColor: theme.palette.backgroundSecondary},
]}>
<View style={[styles.row, styles.inflex]}>
<FlatButton
text={'Employee'}
icon={'account'}
rightIcon={false}
elevation
onPress={this.onPressEmployeePicker}
/>
</View>
<View style={styles.inflex}>
<PickEmployeeTextInput
ref={(input) => {
this.inputRef = input;
}}
autoFocus
value={textValue}
onChangeText={(text) => {
navigation.setParams({textValue: text});
setTextValue(text);
}}
style={[
{
paddingRight,
paddingLeft: theme.spacing * 12,
backgroundColor: theme.palette.background,
...Platform.select({
ios: {
paddingVertical: theme.spacing * 4,
},
}),
},
styles.textInputView,
]}
/>
</View>
<View style={[styles.row, styles.flex]}>
{filteredData === undefined || filteredData.length === 0 ? (
<View style={[styles.row, styles.flex, styles.center]}>
<Text
style={{
padding: theme.spacing * 4,
}}>
{'No matching records found'}
</Text>
</View>
) : (
<FlatList
ItemSeparatorComponent={() => {
return <Divider />;
}}
ListHeaderComponent={<Divider />}
ListFooterComponent={
<View
style={{
paddingBottom: theme.spacing * 2,
}}
/>
}
data={filteredData}
renderItem={({item}) => {
const fullName = getFirstAndLastNames(item);
return (
<TouchableOpacity onPress={this.pickEmployee(item)}>
<View
style={[
styles.row,
styles.flex,
{
paddingVertical: theme.spacing * 3,
paddingRight,
paddingLeft: theme.spacing * 4,
backgroundColor: theme.palette.background,
},
]}>
<Avatar name={fullName} small />
<View
style={[
styles.row,
styles.flex,
styles.listItemView,
{
paddingTop: theme.spacing * 2,
paddingLeft: theme.spacing * 4,
},
]}>
<Text style={styles.fullName}>{fullName}</Text>
<Text style={styles.employeeId}>
{item.employeeId}
</Text>
</View>
</View>
</TouchableOpacity>
);
}}
keyExtractor={(item) => item.empNumber}
keyboardShouldPersistTaps="handled"
refreshControl={
<RefreshControl refreshing={false} onRefresh={onRefresh} />
}
/>
)}
</View>
</View>
</SafeAreaLayout>
);
}
Example #24
Source File: paginatedRefreshListScreen.tsx From THUInfo with MIT License | 4 votes |
export function paginatedRefreshListScreen<T, R>(
dataSource: (props: PropsWithChildren<R>, page: number) => Promise<T[]>,
renderItem: (
item: T,
refresh: () => void,
props: PropsWithChildren<R>,
theme: Theme,
index: number,
total: number,
) => ReactElement,
keyExtractor: (item: T) => string,
footer?: (theme: Theme) => ReactElement,
header?: (theme: Theme, refresh: () => void) => ReactElement,
empty?: (theme: Theme) => ReactElement,
initialNumToRender?: number,
): FC<R> {
return (props: PropsWithChildren<R>) => {
const [data, setData] = useState<T[]>([]);
const [page, setPage] = useState<number>(1);
const [refreshing, setRefreshing] = useState(false);
const [locked, setLocked] = useState(false);
const themeName = useColorScheme();
const theme = themes(themeName);
const refresh = (force: boolean) => {
if ((locked || refreshing) && !force) {
return;
}
setRefreshing(true);
setLocked(false);
dataSource(props, force ? 1 : page + 1)
.then((r) => {
setData((prevData) => (force ? r : prevData.concat(r)));
if (r.length === 0) {
setLocked(true);
}
})
.catch((e) => {
console.error(e);
Snackbar.show({
text: `${getStr("networkRetry")}: ${e.message}`,
duration: Snackbar.LENGTH_SHORT,
});
})
.then(() => {
setRefreshing(false);
setPage((prevPage) => (force ? 1 : prevPage + 1));
});
};
useEffect(() => {
refresh(true);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<FlatList
style={{flex: 1}}
data={data}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={() => refresh(true)}
colors={[theme.colors.accent]}
/>
}
renderItem={({item, index}) =>
renderItem(
item,
() => {
refresh(true);
},
props,
theme,
index,
data.length,
)
}
keyExtractor={keyExtractor}
ListHeaderComponent={
header
? header(theme, () => {
refresh(true); // eslint-disable-next-line no-mixed-spaces-and-tabs
})
: undefined
}
ListFooterComponent={footer ? footer(theme) : undefined}
ListEmptyComponent={empty ? empty(theme) : undefined}
initialNumToRender={initialNumToRender}
onEndReached={() => refresh(false)}
/>
);
};
}
Example #25
Source File: AttendancePickEmployee.tsx From orangehrm-os-mobile with GNU General Public License v3.0 | 4 votes |
render() {
const {theme, subordinates} = this.props;
const {text} = this.state;
let filteredData = subordinates;
if (text !== '') {
const filterFn = this.filterFunction(text);
filteredData = subordinates?.filter(filterFn);
} else {
filteredData = subordinates;
}
const paddingRight = theme.spacing * 6;
return (
<SafeAreaLayout>
<View
style={[
styles.flex,
{backgroundColor: theme.palette.backgroundSecondary},
]}>
<View style={styles.inflex}>
<PickEmployeeTextInput
autoFocus
value={text}
onChangeText={this.onChangeText}
style={[
{
paddingRight,
paddingLeft: theme.spacing * 12,
backgroundColor: theme.palette.background,
paddingVertical: theme.spacing * 4,
},
styles.textInputView,
]}
/>
</View>
<View style={[styles.row, styles.flex]}>
{filteredData === undefined || filteredData.length === 0 ? (
<View style={[styles.row, styles.flex, styles.center]}>
<Text
style={{
padding: theme.spacing * 4,
}}>
{'No matching records found'}
</Text>
</View>
) : (
<FlatList
ItemSeparatorComponent={() => {
return <Divider />;
}}
ListHeaderComponent={<Divider />}
ListFooterComponent={
<View
style={{
paddingBottom: theme.spacing * 2,
}}
/>
}
data={filteredData}
renderItem={({item}) => {
const fullName = getFirstAndLastNames(item);
return (
<TouchableOpacity onPress={this.pickEmployee(item)}>
<View
style={[
styles.row,
styles.flex,
{
paddingVertical: theme.spacing * 3,
paddingRight,
paddingLeft: theme.spacing * 4,
backgroundColor: theme.palette.background,
},
]}>
<Avatar name={fullName} small />
<View
style={[
styles.row,
styles.flex,
styles.listItemView,
{
paddingTop: theme.spacing * 2,
paddingLeft: theme.spacing * 4,
},
]}>
<Text style={styles.fullName}>{fullName}</Text>
<Text style={styles.employeeId}>
{item.employeeId}
</Text>
</View>
</View>
</TouchableOpacity>
);
}}
keyExtractor={(item) => item.empNumber}
keyboardShouldPersistTaps="handled"
refreshControl={
<RefreshControl
refreshing={false}
onRefresh={this.onRefresh}
/>
}
/>
)}
</View>
</View>
</SafeAreaLayout>
);
}
Example #26
Source File: ProductListScreen.tsx From magento_react_native_graphql with MIT License | 4 votes |
ProductListScreen = ({
navigation,
route: {
params: { categoryId },
},
}: Props): React.ReactElement => {
const { data, networkStatus, error, refresh, loadMore } = useCategoryProducts(
{
categoryId,
},
);
const { isVisible, selectedIndex, setVisible, sortOptions } = useSort({
onPress: refresh,
});
const { theme } = useContext(ThemeContext);
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<CustomHeaderButtons>
<CustomHeaderItem
title={translate('common.sort')}
iconName="sort"
onPress={() => setVisible(true)}
/>
</CustomHeaderButtons>
),
});
}, [navigation]);
const onProductItemClicked = (index: number) => {
if (data?.products?.items) {
navigation.navigate(Routes.NAVIGATION_TO_PRODUCT_DETAILS_SCREEN, {
name: data.products.items[index].name,
sku: data.products.items[index].sku,
});
}
};
const renderItem = ({
item,
index,
}: {
item: ProductInListType;
index: number;
}) => {
return (
<ProductListItem
item={item}
index={index}
onPress={onProductItemClicked}
/>
);
};
const renderFooterComponent = () =>
(networkStatus === NetworkStatus.fetchMore && (
<View style={styles.footerContainer}>
<Spinner />
</View>
)) || <></>;
return (
<GenericTemplate errorMessage={error?.message}>
<FlatList
numColumns={2}
data={data?.products?.items ?? []}
renderItem={renderItem}
keyExtractor={item => `productListItem${item.sku}`}
refreshControl={
<RefreshControl
refreshing={
networkStatus === NetworkStatus.refetch ||
networkStatus === NetworkStatus.loading
}
onRefresh={refresh}
/>
}
onEndReached={loadMore}
ListFooterComponent={renderFooterComponent}
/>
<BottomSheet isVisible={isVisible} containerStyle={styles.sortContainer}>
{sortOptions.map((option, index) => (
<ListItem
key={option.title}
containerStyle={[
option.containerStyle,
selectedIndex === index && {
backgroundColor: theme.colors?.grey5,
},
]}
onPress={option.onPress}
>
<ListItem.Content>
<ListItem.Title style={option.titleStyle}>
{option.title}
</ListItem.Title>
</ListItem.Content>
</ListItem>
))}
</BottomSheet>
</GenericTemplate>
);
}
Example #27
Source File: HomeScreen.tsx From Covid19 with MIT License | 4 votes |
HomeScreen = (props: any) => {
const defaultState = useAppSelector((state) => state.root.default);
const dispatch = useAppDispatch();
const [refreshing, setRefresh] = useState<boolean>(false);
const onRefresh = useCallback(async () => {
setRefresh(true);
const data = await getCovidData(props.country);
dispatch(updateData(data));
setRefresh(false);
}, []);
const results = defaultState.data;
const country = defaultState.country;
return (
<SafeAreaView>
<MotiView
style={styles.topIconsContainer}
from={{
opacity: 0,
}}
animate={{
opacity: 1,
}}
transition={{
type: "timing",
duration: 200,
delay: 400,
}}
>
<TouchableOpacity
style={{
backgroundColor: "white",
borderRadius: 8,
elevation: 8,
marginRight: 6,
}}
onPress={() =>
Linking.openURL("https://github.com/sarthakpranesh/Covid19")
}
>
<Github
style={{
margin: 8,
}}
color="black"
/>
</TouchableOpacity>
{Object.keys(vaccineData).includes(country.toLowerCase()) ? (
<TouchableOpacity
style={{
backgroundColor: "white",
borderRadius: 8,
elevation: 8,
marginRight: 6,
}}
onPress={() => Linking.openURL(vaccineData[country.toLowerCase()])}
>
<Vaccine
style={{
margin: 8,
}}
color="black"
/>
</TouchableOpacity>
) : null}
</MotiView>
<ScrollView
style={Styles.scrollView}
contentContainerStyle={Styles.scrollViewContentContainer}
alwaysBounceVertical
showsVerticalScrollIndicator={false}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
}
>
<View style={Styles.mainHeader}>
<Image
style={styles.mainHeaderImage}
source={require("../../assets/ic1.png")}
/>
</View>
<MotiView
from={{
translateX: 50,
opacity: 0,
}}
animate={{
translateX: 0,
opacity: 1,
}}
transition={{
type: "timing",
duration: 200,
}}
>
<Country
data={results?.global}
countryName="World"
containerStyle="#B1ECFF"
/>
</MotiView>
<MotiView
from={{
translateX: 50,
opacity: 0,
}}
animate={{
translateX: 0,
opacity: 1,
}}
transition={{
type: "timing",
duration: 200,
delay: 200,
}}
>
<Country data={results?.country} countryName={country} />
</MotiView>
<MotiView
from={{
translateX: 50,
opacity: 0,
}}
animate={{
translateX: 0,
opacity: 1,
}}
transition={{
type: "timing",
duration: 200,
delay: 400,
}}
>
<CandleCharts country={country} data={results?.timeline} />
</MotiView>
</ScrollView>
</SafeAreaView>
);
}
Example #28
Source File: quick-add-accounts-selector.tsx From beancount-mobile with MIT License | 4 votes |
QuickAddAccountsSelector = connect(
(state: { base: { userId: string } }) => ({
userId: state.base.userId,
})
)(function AssetsExpensesSelectorInner(props: Props): JSX.Element {
const theme = useTheme().colorTheme;
const styles = getStyles(theme);
const { userId, onChange, navigation } = props;
const [refreshing, setRefreshing] = useState(false);
const {
assetsOptionTabs,
expensesOptionTabs,
currencies,
error,
loading,
refetch,
} = useLedgerMeta(userId);
const [selectedAssets, setSelectedAssets] = useState(
assetsOptionTabs.length > 0 ? assetsOptionTabs[0].options[0] : ""
);
const [selectedExpenses, setSelectedExpenses] = useState(
expensesOptionTabs.length > 0 ? expensesOptionTabs[0].options[0] : ""
);
useEffect(() => {
const currency = currencies.length > 0 ? currencies[0] : "";
if (onChange) {
onChange({ asset: selectedAssets, expense: selectedExpenses, currency });
}
});
const isLoading = loading || refreshing;
if (loading) {
return (
<ScrollView
style={styles.container}
refreshControl={
<RefreshControl
refreshing={isLoading}
onRefresh={async () => {
try {
setRefreshing(true);
await refetch();
} finally {
setRefreshing(false);
}
}}
/>
}
>
<LoadingList />
</ScrollView>
);
}
if (error) {
return (
<View style={[styles.container, styles.center]}>
<Text
onPress={async () => {
await refetch();
}}
>
{error.message}
</Text>
</View>
);
}
return (
<ScrollView
style={styles.container}
refreshControl={
<RefreshControl
refreshing={isLoading}
onRefresh={async () => {
try {
setRefreshing(true);
await refetch();
} finally {
setRefreshing(false);
}
}}
/>
}
>
{isLoading ? (
<LoadingList />
) : (
<List>
<ListItemStyled
onPress={async () => {
await analytics.track("tap_assets_picker", {
originalOption: selectedAssets,
});
navigation.navigate("AccountPicker", {
optionTabs: assetsOptionTabs,
selectedItem: selectedAssets,
onSelected: (item: string) => {
setSelectedAssets(item);
},
});
}}
>
<Brief>{i18n.t("from").toUpperCase()}</Brief>
<TextStyled>{selectedAssets}</TextStyled>
</ListItemStyled>
<ListItemStyled
onPress={async () => {
await analytics.track("tap_expenses_picker", {
originalOption: selectedAssets,
});
navigation.navigate("AccountPicker", {
optionTabs: expensesOptionTabs,
selectedItem: selectedExpenses,
onSelected: (item: string) => {
setSelectedExpenses(item);
},
});
}}
>
<Brief>{i18n.t("to").toUpperCase()}</Brief>
<TextStyled>{selectedExpenses}</TextStyled>
</ListItemStyled>
</List>
)}
</ScrollView>
);
})
Example #29
Source File: Home.tsx From wuhan2020-frontend-react-native-app with MIT License | 4 votes |
function Map() {
const { data, refresh, timeout } = useContext(DataContext);
const [selectedIndex, setIndex] = useState(0);
const filter = filterList[selectedIndex];
const [refreshing, setRefreshing] = useState(false);
let mapData = data || [];
const total = {
confirmedCount: 0,
curedCount: 0,
deadCount: 0,
};
const webviewRef = useRef(null);
useEffect(function() {
if (webviewRef.current) {
webviewRef.current.setOption({
title: {
text: `疫情地图${titleMap[filter]}`,
},
tooltip: {
trigger: 'item',
formatter: '{b}',
},
visualMap: {
pieces: piecesMap[filter],
showLabel: true,
realtime: true,
inRange: {
color: ['yellow', 'red'],
},
},
series: [
{
name: '中国',
type: 'map',
map: 'china',
selectedMode: 'single', //multiple多选
itemStyle: {
normal: {
label: {
show: false,
textStyle: {
color: '#231816',
},
},
areaStyle: { color: '#B1D0EC' },
color: '#B1D0EC',
borderColor: '#bbb',
},
emphasis: {
label: {
show: false,
textStyle: {
color: '#fa4f04',
},
},
},
},
data: mapData,
},
],
});
}
});
const onRefresh = useCallback(() => {
setRefreshing(true);
refresh();
wait(2000).then(() => setRefreshing(false));
}, [refreshing, refresh]);
if (data) {
let formatted = [];
data.getAreaStat.forEach(entry => {
total.confirmedCount = total.confirmedCount + entry.confirmedCount;
total.curedCount = total.curedCount + entry.curedCount;
total.deadCount = total.deadCount + entry.deadCount;
formatted = formatted.concat([
{
name: entry.provinceShortName,
value: entry[filter],
},
]);
});
mapData = formatted;
}
const option = {
title: {
text: `疫情地图${titleMap[filter]}`,
},
tooltip: {
trigger: 'item',
formatter: '{b}',
},
visualMap: {
pieces: piecesMap[filter],
showLabel: true,
realtime: true,
inRange: {
color: ['yellow', 'red'],
},
},
series: [
{
name: '中国',
type: 'map',
map: 'china',
selectedMode: 'single', //multiple多选
itemStyle: {
normal: {
label: {
show: false,
textStyle: {
color: '#231816',
},
},
areaStyle: { color: '#B1D0EC' },
color: '#B1D0EC',
borderColor: '#bbb',
},
emphasis: {
label: {
show: false,
textStyle: {
color: '#fa4f04',
},
},
},
},
data: mapData,
},
],
};
if (timeout) {
return (
<SafeAreaView style={{ flex: 1 }}>
<View
style={{ justifyContent: 'center', alignItems: 'center', flex: 1 }}>
<Text
style={{
color: colors.primary,
fontSize: 18,
paddingVertical: 20,
}}>
数据载入失败?
</Text>
<Button type="outline" onPress={refresh} title="点击重试" />
</View>
</SafeAreaView>
);
}
return (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView
style={{
flex: 1,
}}
refreshControl={
<RefreshControl
tintColor="pink"
refreshing={refreshing}
onRefresh={onRefresh}
/>
}>
<View style={{ backgroundColor: 'white' }}>
{mapData.length ? (
<View style={{ flex: 1 }}>
<View style={{ height: 300 }}>
<ECharts
ref={webviewRef}
option={option}
backgroundColor="#fcfcfc"
/>
</View>
<ButtonGroup
selectedButtonStyle={styles.buttonGroup}
onPress={setIndex}
selectedIndex={selectedIndex}
buttons={[
`确诊 (${total.confirmedCount})`,
`治愈 (${total.curedCount})`,
`致死 (${total.deadCount})`,
]}
containerStyle={{ height: 50 }}
/>
{data && data.getTimelineService && (
<Timeline data={data.getTimelineService} />
)}
{data && data.getIndexRecommendList && (
<RecommendationList data={data.getIndexRecommendList} />
)}
</View>
) : (
<View style={{ flex: 1, width, height }}>
<Loader
size="large"
color="red"
style={{ marginTop: height / 3 }}
/>
</View>
)}
</View>
</ScrollView>
</SafeAreaView>
);
}