@react-navigation/native#useRoute TypeScript Examples
The following examples show how to use
@react-navigation/native#useRoute.
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: index.tsx From GoBarber with MIT License | 6 votes |
AppointmentCreated: React.FC = () => {
const { reset } = useNavigation();
const { params } = useRoute();
const { date } = params as RouteParams;
const formattedDate = useMemo(() => {
return format(date, "EEEE', dia' dd 'de' MMMM 'de' yyyy 'às' HH:mm'h'", {
locale: ptBR,
});
}, [date]);
const handleOkPressed = useCallback(() => {
reset({
routes: [
{
name: 'Dashboard',
},
],
index: 0,
});
}, [reset]);
return (
<Container>
<Icon name="check" size={80} color="#04d361" />
<Title>Agendamento Concluído</Title>
<Description>{formattedDate}</Description>
<OkButton onPress={handleOkPressed}>
<OkButtonText>Ok</OkButtonText>
</OkButton>
</Container>
);
}
Example #2
Source File: index.tsx From gobarber-mobile with MIT License | 6 votes |
AppointmentCreated: React.FC = () => {
const { reset } = useNavigation();
const { params } = useRoute();
const { date } = params as RouteParams;
const handleOkPressed = useCallback(() => {
reset({
routes: [{ name: 'Dashboard' }],
index: 0,
});
}, [reset]);
const formattedDate = useMemo(() => {
return format(date, "EEEE', dia' dd 'de' MMMM 'de' yyyy 'às' HH:mm'h'", {
locale: ptBR,
});
}, [date]);
return (
<Container>
<Icon name="check" size={80} color="#04d461" />
<Title>Agendamento concluído</Title>
<Description>{formattedDate}</Description>
<OkButton onPress={handleOkPressed}>
<OkButtonText>Ok</OkButtonText>
</OkButton>
</Container>
);
}
Example #3
Source File: index.tsx From gobarber-project with MIT License | 6 votes |
AppointmentCreated: React.FC = () => {
const { reset } = useNavigation();
const { params } = useRoute();
const { date } = params as IRouteParams;
const handleOkPressed = useCallback(() => {
reset({
routes: [
{
name: 'Dashboard',
},
],
index: 0,
});
}, [reset]);
const formattedDate = useMemo(() => {
return format(date, "EEEE', dia' dd 'de' MMMM 'de' yyyy 'às' HH:mm'h'", {
locale: ptBR,
});
}, [date]);
return (
<Container>
<Icon name="check" size={80} color="#04d361" />
<Title>Agendamento concluído</Title>
<Description>{formattedDate}</Description>
<OkButton onPress={handleOkPressed}>
<OkButtonText>OK</OkButtonText>
</OkButton>
</Container>
);
}
Example #4
Source File: Product.container.tsx From react-native-woocommerce with MIT License | 6 votes |
ProductContainer = (props: ProductsState): JSX.Element => {
const products = useSelector(selectors.products.getProducts);
const [imagesShown, showImages] = useState(false);
const route = useRoute();
const handlers = {
handleShowImages: (): void =>
showImages((prevState) => !prevState)
};
return (
<ProductComponent
{...props}
{...handlers}
// @ts-ignore
product={_getProductById(products, route.params.id)}
imagesShown={imagesShown}
/>
);
}
Example #5
Source File: Detail.container.tsx From RNWCShop with GNU General Public License v3.0 | 6 votes |
DetailContainer = ({ navigation }: Props): JSX.Element => {
const initialProduct = {
id: 1,
name: '',
price: 0,
description: '',
average_rating: '',
images: []
};
const [product, setProduct] = useState<Product>(initialProduct);
const [imagesShown, showImages] = useState(false);
const route = useRoute<RouteProp<NavigationParams, 'Detail'>>();
const dispatch = useDispatch();
const handlers = {
handleShowImages: (): void =>
showImages((prevState: boolean) => !prevState),
addToCart: (product: Product): Action => {
navigation.navigate('Orders', { screen: routes.Cart });
return dispatch(actions.addToCart(product));
}
};
useEffect(() => {
WooCommerce.get(`/products/${route.params.id}`).then(({ data }) => {
setProduct(data);
});
}, [route.params.id]);
return (
<DetailComponent
{...handlers}
imagesShown={imagesShown}
product={product}
/>
);
}
Example #6
Source File: AuthScene.tsx From sellflow with MIT License | 6 votes |
export default function AuthScene() {
let {
params: { initialRouteKey },
} = useRoute<StackRouteProp<'Auth'>>();
const routes: Array<TabRoute> = [
{ key: 'Login', title: 'Login', scene: LoginScene },
{ key: 'Register', title: 'Register', scene: RegisterScene },
];
return (
<TabView
isScrollEnabled={false}
routes={routes}
initialRouteKey={initialRouteKey}
/>
);
}
Example #7
Source File: debug.tsx From bext with MIT License | 6 votes |
DebugScreen: FC = () => {
const webView = useRef<WebView>(null);
const { params } = useRoute<any>();
const { script } = useDebug();
return (
<WebView
ref={webView}
originWhitelist={['*']}
source={{
uri: params.url,
}}
injectedJavaScriptBeforeContentLoaded={`${script.current};true;`}
/>
);
}
Example #8
Source File: AlbumScreen.tsx From SpotifyClone with MIT License | 6 votes |
AlbumScreen = () => {
const route = useRoute();
const albumId = route.params.id;
const [album, setAlbum] = useState(null)
useEffect(() => {
const fetchAlbumDetails = async () => {
try {
const data = await API.graphql(graphqlOperation(getAlbum, { id: albumId }))
setAlbum(data.data.getAlbum)
} catch (e) {
console.log(e);
}
}
fetchAlbumDetails();
}, [])
if (!album) {
return <Text>Loading...</Text>
}
return (
<View>
<FlatList
data={album.songs.items}
renderItem={({ item }) => <SongListItem song={item} />}
keyExtractor={(item) => item.id}
ListHeaderComponent={() => <AlbumHeader album={album} />}
/>
</View>
)
}
Example #9
Source File: Playlist.tsx From jellyfin-audio-player with MIT License | 6 votes |
Playlist: React.FC = () => {
const { params: { id } } = useRoute<Route>();
const dispatch = useAppDispatch();
// Retrieve the album data from the store
const playlist = useTypedSelector((state) => state.music.playlists.entities[id]);
const playlistTracks = useTypedSelector((state) => state.music.tracks.byPlaylist[id]);
// Define a function for refreshing this entity
const refresh = useCallback(() => dispatch(fetchTracksByPlaylist(id)), [dispatch, id]);
// Auto-fetch the track data periodically
useEffect(() => {
if (!playlist?.lastRefreshed || differenceInDays(playlist?.lastRefreshed, new Date()) > ALBUM_CACHE_AMOUNT_OF_DAYS) {
refresh();
}
}, [playlist?.lastRefreshed, refresh]);
return (
<TrackListView
trackIds={playlistTracks || []}
title={playlist?.Name}
entityId={id}
refresh={refresh}
listNumberingStyle='index'
playButtonText={t('play-playlist')}
shuffleButtonText={t('shuffle-playlist')}
downloadButtonText={t('download-playlist')}
deleteButtonText={t('delete-playlist')}
/>
);
}
Example #10
Source File: ReportUnMatchButton.tsx From vsinder with Apache License 2.0 | 5 votes |
ReportUnMatchButton: React.FC<ReportUnMatchButtonProps> = ({}) => {
const { buttonBackground } = useTheme();
const { showActionSheetWithOptions } = useActionSheet();
const cache = useQueryCache();
const navigation = useNavigation();
const [mutate] = useMutation(defaultMutationFn, {
onSuccess: () => {
navigation.goBack();
cache.setQueryData<MatchesResponse>("/matches/0", (m) => {
return {
matches: m?.matches.filter((x) => x.userId !== params.id) || [],
};
});
},
});
const { params } = useRoute<MatchesStackNav<"messages">["route"]>();
return (
<ReportDialog
onReportMessage={(message) => {
mutate([
"/report",
{ message, unmatchOrReject: "unmatch", userId: params.id },
"POST",
]);
}}
>
{(setOpen) => (
<TouchableOpacity
style={{
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
paddingRight: 15,
}}
onPress={() => {
const options = [
"Report user",
"Unmatch",
"Report a bug",
"Cancel",
];
const destructiveButtonIndex = 0;
const cancelButtonIndex = 3;
showActionSheetWithOptions(
{
options,
cancelButtonIndex,
destructiveButtonIndex,
},
(buttonIndex) => {
if (buttonIndex === 0) {
setOpen(true);
} else if (buttonIndex === 1) {
mutate([`/unmatch`, { userId: params.id }, "POST"]);
} else if (buttonIndex === 2) {
Linking.openURL("https://github.com/benawad/vsinder/issues");
}
}
);
}}
>
<MaterialIcons name="bug-report" size={27} color={buttonBackground} />
</TouchableOpacity>
)}
</ReportDialog>
);
}
Example #11
Source File: index.tsx From NLW-1.0 with MIT License | 5 votes |
Detail: React.FC = () => {
const [data, setData] = useState<Data>({} as Data);
const navigation = useNavigation();
const route = useRoute();
const routeParams = route.params as Params;
useEffect(() => {
async function loadPoint() {
const response = await api.get(`/points/${routeParams.point_id}`);
setData(response.data);
}
loadPoint();
}, []);
function handleNavigateBack() {
navigation.goBack();
}
function handleComposeMail() {
MailComposer.composeAsync({
subject: "Interesse na coleta de resíduos",
recipients: [data.point.email],
});
}
function handleWhatsApp() {
Linking.openURL(
`whatsapp://send?phone=${data.point.whatsapp}&text=Tenho interesse na coleta de resíduos`
);
}
if (!data.point) {
return null;
}
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<TouchableOpacity onPress={handleNavigateBack}>
<Icon name="arrow-left" size={20} color="#34cb79" />
</TouchableOpacity>
<Image
style={styles.pointImage}
source={{
uri: data.point.image_url,
}}
/>
<Text style={styles.pointName}>{data.point.name}</Text>
<Text style={styles.pointItems}>
{data.items.map((item) => item.title).join(",")}
</Text>
<View style={styles.address}>
<Text style={styles.addressTitle}>Endereço</Text>
<Text style={styles.addressContent}>
{data.point.city}, {data.point.uf}
</Text>
</View>
</View>
<View style={styles.footer}>
<RectButton style={styles.button} onPress={() => handleWhatsApp()}>
<FontAwesome name="whatsapp" size={20} color="#fff" />
<Text style={styles.buttonText}>Whatsapp</Text>
</RectButton>
<RectButton style={styles.button} onPress={() => handleComposeMail()}>
<Icon name="mail" size={20} color="#fff" />
<Text style={styles.buttonText}>E-mail</Text>
</RectButton>
</View>
</SafeAreaView>
);
}
Example #12
Source File: index.tsx From nlw-01-omnistack with MIT License | 5 votes |
Detail = () => {
const [data, setData] = useState<Data>({} as Data);
const navigation = useNavigation();
const route = useRoute();
const routeParams = route.params as Params;
useEffect(() => {
api.get(`points/${routeParams.point_id}`).then(response => {
setData(response.data);
});
}, []);
function handleNavigateBack() {
navigation.goBack();
}
function handleWhatsapp() {
Linking.openURL(`whatsapp://send?phone=${data.point.whatsapp}&text=Tenho interesse sobre coleta de resíduos`);
}
function handleComposeMail() {
MailComposer.composeAsync({
subject: 'Interesse na coleta de resíduos',
recipients: [data.point.email],
})
}
if (!data.point) {
return null;
}
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<TouchableOpacity onPress={handleNavigateBack}>
<Icon name="arrow-left" size={20} color="#34cb79" />
</TouchableOpacity>
<Image style={styles.pointImage} source={{ uri: data.point.image_url }} />
<Text style={styles.pointName}>{data.point.name}</Text>
<Text style={styles.pointItems}>
{data.items.map(item => item.title).join(', ')}
</Text>
<View style={styles.address}>
<Text style={styles.addressTitle}>Endereço</Text>
<Text style={styles.addressContent}>{data.point.city}, {data.point.uf}</Text>
</View>
</View>
<View style={styles.footer}>
<RectButton style={styles.button} onPress={handleWhatsapp}>
<FontAwesome name="whatsapp" size={20} color="#FFF" />
<Text style={styles.buttonText}>Whatsapp</Text>
</RectButton>
<RectButton style={styles.button} onPress={handleComposeMail}>
<Icon name="mail" size={20} color="#FFF" />
<Text style={styles.buttonText}>E-mail</Text>
</RectButton>
</View>
</SafeAreaView>
);
}
Example #13
Source File: index.tsx From nlw-ecoleta with MIT License | 5 votes |
Detail = () => {
const [data, setData] = useState<Data>({} as Data);
const navigation = useNavigation();
const route = useRoute();
const routeParams = route.params as Params;
useEffect(() => {
api.get(`points/${routeParams.point_id}`).then(response => {
setData(response.data);
});
}, []);
function handleNavigateBack() {
navigation.goBack();
}
function handleNavigateComposeMail() {
MailComposer.composeAsync({
subject: 'Interesse na coleta de resíduos',
recipients: [data.point.email],
})
}
function handleWhatsapp() {
Linking.openURL(`whatsapp://send?phone${data.point.whatsapp}$textTEnho interesse sobre coleta de resíduos`)
}
if(!data.point) {
return null;
}
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<TouchableOpacity onPress={handleNavigateBack}>
<Icon name="arrow-left" size={20} color="#34cb79" />
</TouchableOpacity>
<Image style={styles.pointImage} source={{ uri: data.point.image_url }} />
<Text style={styles.pointName}>{data.point.name}</Text>
<Text style={styles.pointItems}>{data.items.map(item =>item.title).join(', ')}</Text>
<View style={styles.address}>
<Text style={styles.addressTitle}>Endereço</Text>
<Text style={styles.addressContent}>{data.point.city}, {data.point.uf}</Text>
</View>
</View>
<View style={styles.footer}>
<RectButton style={styles.button} onPress={handleWhatsapp}>
<FontAwesome name="whatsapp" size={20} color="#FFF" />
<Text style={styles.buttonText}>Whatsapp</Text>
</RectButton>
<RectButton style={styles.button} onPress={handleNavigateComposeMail}>
<Icon name="mail" size={20} color="#FFF" />
<Text style={styles.buttonText}>E-mail</Text>
</RectButton>
</View>
</SafeAreaView>
);
}
Example #14
Source File: OrderHistoryScene.tsx From sellflow with MIT License | 5 votes |
export default function OrderHistoryScene() {
let { navigate } = useNavigation<StackNavProp<'OrderHistory'>>();
let {
params: { customerAccessToken },
} = useRoute<StackRouteProp<'OrderHistory'>>();
let first = 10;
let {
orderHistory,
error,
loading,
refetch,
isFetchingMore,
hasMore,
} = useOrderHistory(first, customerAccessToken);
let {
data: { countryCode },
} = useDefaultCountry();
if (error) {
return (
<ErrorPage
onRetry={() =>
refetch({
customerAccessToken,
first,
after: orderHistory[orderHistory.length - 1].cursor || null,
country: countryCode,
})
}
/>
);
}
if (loading && !isFetchingMore) {
return <ActivityIndicator style={styles.center} />;
}
let onEndReached = () => {
if (!isFetchingMore && hasMore) {
refetch({
customerAccessToken,
first,
after: orderHistory[orderHistory.length - 1].cursor || null,
country: countryCode,
});
}
};
return (
<FlatList
data={orderHistory}
renderItem={({ item }) => (
<OrderHistoryItem
order={item}
onPress={() => navigate('OrderDetails', { order: item })}
/>
)}
keyExtractor={(item) => item.orderID}
contentContainerStyle={styles.contentContainer}
ListEmptyComponent={() => {
return hasMore ? null : (
<View style={styles.center}>
<Text>{t('No orders yet')}</Text>
</View>
);
}}
onEndReached={onEndReached}
onEndReachedThreshold={0.25}
ListFooterComponent={() => {
return hasMore ? (
<ActivityIndicator style={styles.activityIndicator} />
) : null;
}}
/>
);
}
Example #15
Source File: ReportUnMatchButton.tsx From vsinder-app with Apache License 2.0 | 5 votes |
ReportUnMatchButton: React.FC<ReportUnMatchButtonProps> = ({}) => {
const { buttonBackground } = useTheme();
const { showActionSheetWithOptions } = useActionSheet();
const cache = useQueryCache();
const navigation = useNavigation();
const [mutate] = useMutation(defaultMutationFn, {
onSuccess: () => {
navigation.goBack();
cache.setQueryData<MatchesResponse>("/matches/0", (m) => {
return {
matches: m?.matches.filter((x) => x.userId !== params.id) || [],
};
});
},
});
const { params } = useRoute<MatchesStackNav<"messages">["route"]>();
return (
<ReportDialog
onReportMessage={(message) => {
mutate([
"/report",
{ message, unmatchOrReject: "unmatch", userId: params.id },
"POST",
]);
}}
>
{(setOpen) => (
<TouchableOpacity
style={{
flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
paddingRight: 15,
}}
onPress={() => {
const options = ["Report", "Unmatch", "Cancel"];
const destructiveButtonIndex = 0;
const cancelButtonIndex = 2;
showActionSheetWithOptions(
{
options,
cancelButtonIndex,
destructiveButtonIndex,
},
(buttonIndex) => {
if (buttonIndex === 0) {
setOpen(true);
} else if (buttonIndex === 1) {
mutate([`/unmatch`, { userId: params.id }, "POST"]);
}
}
);
}}
>
<MaterialIcons name="bug-report" size={27} color={buttonBackground} />
</TouchableOpacity>
)}
</ReportDialog>
);
}
Example #16
Source File: TrackPopupMenu.tsx From jellyfin-audio-player with MIT License | 5 votes |
function TrackPopupMenu() {
// Retrieve trackId from route
const { params: { trackId } } = useRoute<Route>();
// Retrieve helpers
const navigation = useNavigation();
const dispatch = useAppDispatch();
const playTracks = usePlayTracks();
const getImage = useGetImage();
// Retrieve data from store
const track = useTypedSelector((state) => state.music.tracks.entities[trackId]);
const isDownloaded = useTypedSelector(selectIsDownloaded(trackId));
// Set callback to close the modal
const closeModal = useCallback(() => {
navigation.dispatch(StackActions.popToTop());
}, [navigation]);
// Callback for adding the track to the queue as the next song
const handlePlayNext = useCallback(() => {
playTracks([trackId], { method: 'add-after-currently-playing', play: false });
closeModal();
}, [playTracks, closeModal, trackId]);
// Callback for adding the track to the end of the queue
const handleAddToQueue = useCallback(() => {
playTracks([trackId], { method: 'add-to-end', play: false });
closeModal();
}, [playTracks, closeModal, trackId]);
// Callback for downloading the track
const handleDownload = useCallback(() => {
dispatch(queueTrackForDownload(trackId));
closeModal();
}, [trackId, dispatch, closeModal]);
// Callback for removing the downloaded track
const handleDelete = useCallback(() => {
dispatch(removeDownloadedTrack(trackId));
closeModal();
}, [trackId, dispatch, closeModal]);
return (
<Container>
<Artwork src={getImage(track?.Id || '')} />
<Header>{track?.Name}</Header>
<SubHeader style={{ marginBottom: 18 }}>{track?.AlbumArtist} {track?.Album ? '— ' + track?.Album : ''}</SubHeader>
<WrappableButtonRow>
<WrappableButton title={t('play-next')} icon={PlayIcon} onPress={handlePlayNext} />
<WrappableButton title={t('add-to-queue')} icon={QueueAppendIcon} onPress={handleAddToQueue} />
{isDownloaded ? (
<WrappableButton title={t('delete-track')} icon={TrashIcon} onPress={handleDelete} />
) : (
<WrappableButton title={t('download-track')} icon={DownloadIcon} onPress={handleDownload} />
)}
</WrappableButtonRow>
</Container>
);
}
Example #17
Source File: Channels.tsx From lexicon with MIT License | 5 votes |
export default function Channels() {
const styles = useStyles();
const { navigate, goBack } = useNavigation<RootStackNavProp<'Channels'>>();
const {
params: { selectedChannelId, prevScreen },
} = useRoute<RootStackRouteProp<'Channels'>>();
const storage = useStorage();
const channels = storage.getItem('channels');
const ios = Platform.OS === 'ios';
const onPress = (id: number) => {
if (prevScreen === 'Home') {
navigate('Main', {
screen: 'TabNav',
params: {
screen: 'Home',
params: {
selectedChannelId: id,
},
},
});
} else {
navigate(prevScreen, { selectedChannelId: id });
}
};
return (
<SafeAreaView style={styles.container}>
{ios ? (
<ModalHeader
title={t('Channels')}
left={<HeaderItem label={t('Cancel')} onPressItem={goBack} left />}
/>
) : (
<CustomHeader title={t('Channels')} noShadow />
)}
<ScrollView>
{prevScreen === 'Home' && (
<ChannelItem
isSelected={selectedChannelId === ALL_CHANNEL.id}
channel={ALL_CHANNEL}
onPress={() => onPress(ALL_CHANNEL.id)}
/>
)}
{channels?.map((channel) => {
const { id } = channel;
return (
<ChannelItem
key={id}
isSelected={id === selectedChannelId}
channel={channel}
onPress={() => onPress(id)}
/>
);
})}
</ScrollView>
</SafeAreaView>
);
}
Example #18
Source File: WebViewScene.tsx From sellflow with MIT License | 5 votes |
export default function WebScene() {
let {
params: { type, webUrl },
} = useRoute<StackRouteProp<'WebView'>>();
let { navigate, setOptions } = useNavigation<StackNavProp<'WebView'>>();
let { resetShoppingCart } = useResetCart();
let title: string;
switch (type) {
case 'policy':
title = t('Privacy Policy');
break;
case 'terms':
title = t('Terms & Conditions');
break;
default:
title = t('Payment');
}
useEffect(() => {
setOptions({
title,
});
});
return webUrl ? (
<SafeAreaView style={styles.flex}>
<WebView
style={styles.container}
source={{ uri: webUrl }}
originWhitelist={['*']}
onShouldStartLoadWithRequest={({ url }) => {
if (url.endsWith('thank_you')) {
resetShoppingCart();
navigate('OrderPlacedConfirmation', { orderNumber: '' });
return false;
}
return true;
}}
startInLoadingState={true}
renderLoading={() => <ActivityIndicator style={styles.center} />}
/>
</SafeAreaView>
) : (
<SafeAreaView style={styles.text}>
<Text>{t('Please check your connection.')}</Text>
</SafeAreaView>
);
}
Example #19
Source File: BatteryPermission.tsx From hamagen-react-native with MIT License | 5 votes |
BatteryPermission: FunctionComponent<Props> = ({ onEnd }) => {
// const [userPressed,setUserPressed] = useState(false)
const dispatch = useDispatch();
const { strings: {
general: { additionalInfo },
battery: { title, description, approveButton, notApproveButton }
}
} = useSelector<Store, LocaleReducer>(state => state.locale);
const { params } = useRoute();
const [intervalDelay, setIntervalDelay] = useState<number | null>(null);
useInterval(async () => {
const isEnabled = await RNDisableBatteryOptimizationsAndroid.isBatteryOptimizationEnabled();
if (!isEnabled) {
dispatch({ type: USER_DISABLED_BATTERY, payload: true });
await AsyncStorage.setItem(USER_AGREED_TO_BATTERY, 'true');
onEnd();
}
}, intervalDelay);
// stop interval if user moved on
useFocusEffect(React.useCallback(() => () => setIntervalDelay(null), []));
return (
<>
<View style={[{ alignItems: 'center', paddingHorizontal: IS_SMALL_SCREEN ? 20 : 40 }, IS_SMALL_SCREEN && { paddingTop: 5 }]}>
{!IS_SMALL_SCREEN && (
<Icon
width={80}
customStyles={{ marginBottom: 20 }}
source={require('../../assets/onboarding/batteryBig.png')}
/>
)}
<Text style={styles.title} bold>{title}</Text>
<Text style={styles.description}>{description}</Text>
</View>
<View style={{ alignItems: 'center' }}>
<ActionButton
text={approveButton}
onPress={() => {
setIntervalDelay(200);
RNDisableBatteryOptimizationsAndroid.openBatteryModal();
}}
containerStyle={{ marginBottom: 20 }}
/>
{params?.showSkip && (
<TouchableOpacity onPress={async () => {
onEnd();
dispatch({ type: USER_DISABLED_BATTERY, payload: false });
AsyncStorage.setItem(USER_AGREED_TO_BATTERY, 'false');
}}
>
<Text style={{ color: MAIN_COLOR }} bold>{notApproveButton}</Text>
</TouchableOpacity>
)}
</View>
</>
);
}
Example #20
Source File: DetachedHeader.tsx From react-native-gallery-toolkit with MIT License | 5 votes |
function useHeaderProps() {
const route = useRoute();
return headerPropsMap.get(route.name);
}
Example #21
Source File: index.tsx From ecoleta with MIT License | 5 votes |
Detail = () => {
const [data, setData] = useState<Data>({} as Data);
const navigation = useNavigation();
const route = useRoute();
const routeParams = route.params as Params;
useEffect(() => {
api.get(`/points/${routeParams.point_id}`).then((response) => {
setData(response.data);
});
}, []);
function handleNavigateBack() {
navigation.goBack();
}
function handleWhatsapp() {
Linking.openURL(
`whatsapp://send?phone=${data.point.whatsapp}&text=Tenho interesse em ajudar na coleta de resíduos`
);
}
function handleComposeMail() {
MailComposer.composeAsync({
subject: 'Interesse na coleta de resíduos',
recipients: [data.point.email],
});
}
if (!data.point) {
return null;
}
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<TouchableOpacity onPress={handleNavigateBack}>
<Feather name="arrow-left" color="#34CB79" size={24} />
</TouchableOpacity>
<Image
style={styles.pointImage}
source={{
uri: data.point.image_url,
}}
/>
<Text style={styles.pointName}>{data.point.name}</Text>
<Text style={styles.pointItems}>
{data.items.map((item) => item.title).join(', ')}
</Text>
<View style={styles.address}>
<Text style={styles.addressTitle}>Endereço:</Text>
<Text style={styles.addressContent}>
{data.point.city}, {data.point.uf}
</Text>
</View>
</View>
<View style={styles.footer}>
<RectButton style={styles.button} onPress={handleWhatsapp}>
<FontAwesome name="whatsapp" size={20} color="#fff" />
<Text style={styles.buttonText}>Whatsapp</Text>
</RectButton>
<RectButton style={styles.button} onPress={handleComposeMail}>
<Feather name="mail" size={20} color="#fff" />
<Text style={styles.buttonText}>E-mail</Text>
</RectButton>
</View>
</SafeAreaView>
);
}
Example #22
Source File: PostImagePreview.tsx From lexicon with MIT License | 5 votes |
export default function PostImagePreview() {
const styles = useStyles();
const { colors } = useTheme();
const { navigate, goBack } = useNavigation<
RootStackNavProp<'PostImagePreview'>
>();
const {
params: { imageUri, prevScreen },
} = useRoute<RootStackRouteProp<'PostImagePreview'>>();
const uploading = () => {
navigate(prevScreen, { imageUri });
};
return (
<View style={styles.container}>
<StatusBar style={'light'} />
<SafeAreaView style={styles.fullContainer}>
<ImageBackground
source={{ uri: imageUri }}
resizeMode="contain"
style={styles.fullContainer}
>
<View
style={{ flexDirection: 'row', justifyContent: 'space-between' }}
>
<Icon
name="Close"
color={colors.pureWhite}
onPress={goBack}
style={styles.iconContainer}
/>
<Icon
name="Add"
color={colors.pureWhite}
onPress={uploading}
style={styles.iconContainer}
/>
</View>
</ImageBackground>
</SafeAreaView>
</View>
);
}
Example #23
Source File: index.tsx From ecoleta with MIT License | 5 votes |
Detail = () => {
const [data, setData] = useState<Data>({} as Data);
const navigation = useNavigation();
const route = useRoute();
const routeParams = route.params as Params;
useEffect(() => {
api.get(`points/${routeParams.point_id}`).then(response => {
setData(response.data);
});
}, []);
function handleNavigateBack() {
navigation.goBack();
}
function handleWhatsapp() {
Linking.openURL(`whatsapp://send?phone=${data.point.whatsapp}&text=Tenho interesse sobre coleta de resíduos.`)
}
function handleComposeMail() {
MailComposer.composeAsync({
subject: 'Interesse na coleta de resíduos',
recipients: [data.point.email],
})
}
if (!data.point) {
return null;
}
return (
<SafeAreaView style={{ flex: 1 }} >
<View style={styles.container}>
<TouchableOpacity onPress={handleNavigateBack}>
<Icon name="arrow-left" size={20} color="#34cb79" />
</TouchableOpacity>
<Image style={styles.pointImage} source={{ uri: data.point.image_url }} />
<Text style={styles.pointName}>{data.point.name}</Text>
<Text style={styles.pointItems}>
{data.items.map(item => item.title).join(',')}
</Text>
<View style={styles.address}>
<Text style={styles.addressTitle}>Endereço</Text>
<Text style={styles.addressContent}>{data.point.city}, {data.point.uf}</Text>
</View>
</View>
<View style={styles.footer}>
<RectButton style={styles.button} onPress={handleWhatsapp}>
<FontAwesome name="whatsapp" size={20} color="#FFF" />
<Text style={styles.buttonText}>WhatsApp</Text>
</RectButton>
<RectButton style={styles.button} onPress={handleComposeMail}>
<Icon name="mail" size={20} color="#FFF" />
<Text style={styles.buttonText}>E-mail</Text>
</RectButton>
</View>
</SafeAreaView>
);
}
Example #24
Source File: UserInformation.tsx From lexicon with MIT License | 4 votes |
export default function UserInformation() {
const styles = useStyles();
const { navigate } = useNavigation<StackNavProp<'UserInformation'>>();
const {
params: { username },
} = useRoute<StackRouteProp<'UserInformation'>>();
const storage = useStorage();
const channels = storage.getItem('channels');
const currentUser = storage.getItem('user')?.username;
const [show, setShow] = useState<boolean>();
const [refreshing, setRefreshing] = useState(false);
const {
data: profileData,
loading: profileLoading,
error: profileError,
} = useProfile(
{
variables: { username },
},
'HIDE_ALERT',
);
const name = profileData?.userProfile.user.name || '';
const userImage = getImage(profileData?.userProfile.user.avatar || '', 'xl');
const bio = profileData?.userProfile.user.bioRaw;
const splittedBio = bio ? bio.split(/\r\n|\r|\n/) : [''];
const {
data: topicsData,
loading: topicsLoading,
error: topicsError,
} = useTopicList({
variables: { sort: TopicsSortEnum.LATEST },
fetchPolicy: 'network-only',
});
const {
data,
loading,
error,
networkStatus,
refetch,
fetchMore,
} = useActivity(
{ variables: { username: username, offset: 0 } },
'HIDE_ALERT',
);
const activities = data?.userActivity ?? [];
let postActivities: Array<Post> = activities.map((activity) => {
const channel = channels?.find(
(channel) => channel.id === activity.categoryId,
);
let topic;
const listedTopics = topicsData?.topics.topicList;
if (listedTopics?.topics) {
topic = listedTopics.topics.find(
(topic) => topic.id === activity.topicId,
);
}
const { content, imageUrl, mentionedUsers } = anchorToMarkdown(
activity.excerpt,
);
return {
...activity,
id: activity.postId ?? 0,
content,
images: imageUrl ? [imageUrl] : undefined,
avatar: getImage(activity.avatarTemplate),
viewCount: 0,
replyCount: 0,
likeCount: 0,
isLiked: activity.actionType === 1,
channel: channel || DEFAULT_CHANNEL,
tags: topic?.tags || [],
freqPosters: [],
mentionedUsers,
};
});
const onEndReached = (distanceFromEnd: number) => {
if (distanceFromEnd === 0) {
return;
}
fetchMore({ variables: { offset: postActivities.length } });
};
const onRefresh = () => {
setRefreshing(true);
refetch();
setRefreshing(false);
};
const onPressCancel = () => {
if (!show) {
setShow(true);
}
setTimeout(() => setShow(false), 50);
};
const onPressNewMessage = () => {
navigate('NewMessage', {
users: [username],
listOfUser: [{ name, username, avatar: userImage }],
});
};
if (error || topicsError || profileError) {
let errorMessage = error
? errorHandler(error, true)
: topicsError
? errorHandler(topicsError, true)
: profileError
? errorHandler(profileError, true)
: undefined;
return <LoadingOrError message={errorMessage} />;
}
if (
((loading ||
topicsLoading ||
profileLoading ||
(data && data.userActivity.length !== 0)) &&
postActivities.length < 1) ||
topicsData?.topics.topicList?.topics?.length === undefined
) {
return <LoadingOrError loading />;
}
const Header = () => {
return (
<>
<View style={styles.headerContainer}>
<CustomHeader title="" noShadow />
<Avatar
src={userImage}
size="l"
label={username[0]}
onPress={() => {
setShow(true);
}}
/>
<View style={styles.usernameText}>
<Text variant="semiBold" size="l">
{username}
</Text>
</View>
<Markdown
content={
splittedBio
? splittedBio.length > 3
? `${splittedBio.slice(0, 3).join('\n')}...`
: bio
? bio
: ''
: ''
}
style={styles.bioContainer}
/>
<View style={styles.buttonContainer}>
{currentUser !== username && (
<Button content={t('Message')} onPress={onPressNewMessage} />
)}
{
// TODO: This LoC is meant for the next phase
/* <View style={styles.buttonDivider} />
<Button
content={t('Badges')}
style={styles.whiteButton}
textColor="textNormal"
disabled
/> */
}
</View>
</View>
<Text variant={'semiBold'} style={styles.activityText}>
{t('Activity')}
</Text>
</>
);
};
let content;
if (postActivities.length !== 0) {
content = (
<PostList
ListHeaderComponent={<Header />}
data={postActivities}
showLabel={true}
currentUser={username}
onRefresh={onRefresh}
refreshing={networkStatus === 4 || refreshing}
scrollEventThrottle={16}
alwaysBounceVertical={true}
hasFooter={false}
style={styles.fill}
showImageRow
onEndReachedThreshold={0.1}
onEndReached={({ distanceFromEnd }) => onEndReached(distanceFromEnd)}
/>
);
} else {
content = (
<View style={styles.noActivity}>
<Header />
<Text style={styles.noActivityText}>
{t("This user doesn't have any activity")}
</Text>
</View>
);
}
return (
<View style={styles.container}>
{content}
{show && (
<ShowImageModal
show={show}
userImage={{ uri: userImage }}
onPressCancel={onPressCancel}
/>
)}
</View>
);
}
Example #25
Source File: index.tsx From nlw-01-omnistack with MIT License | 4 votes |
Points = () => {
const [items, setItems] = useState<Item[]>([]);
const [points, setPoints] = useState<Point[]>([]);
const [selectedItems, setSelectedItems] = useState<number[]>([]);
const [initialPosition, setInitialPosition] = useState<[number, number]>([0, 0]);
const navigation = useNavigation();
const route = useRoute();
const routeParams = route.params as Params;
useEffect(() => {
async function loadPosition() {
const { status } = await Location.requestPermissionsAsync();
if (status !== 'granted') {
Alert.alert('Oooops...', 'Precisamos de sua permissão para obter a localização');
return;
}
const location = await Location.getCurrentPositionAsync();
const { latitude, longitude } = location.coords;
console.log(latitude, longitude);
setInitialPosition([
latitude,
longitude
])
}
loadPosition();
}, []);
useEffect(() => {
api.get('items').then(response => {
setItems(response.data);
});
}, []);
useEffect(() => {
api.get('points', {
params: {
city: routeParams.city,
uf: routeParams.uf,
items: selectedItems
}
}).then(response => {
setPoints(response.data);
})
}, [selectedItems]);
function handleNavigateBack() {
navigation.goBack();
}
function handleNavigateToDetail(id: number) {
navigation.navigate('Detail', { point_id: id });
}
function handleSelectItem(id: number) {
const alreadySelected = selectedItems.findIndex(item => item === id);
if (alreadySelected >= 0) {
const filteredItems = selectedItems.filter(item => item !== id);
setSelectedItems(filteredItems);
} else {
setSelectedItems([ ...selectedItems, id ]);
}
}
return (
<>
<View style={styles.container}>
<TouchableOpacity onPress={handleNavigateBack}>
<Icon name="arrow-left" size={20} color="#34cb79" />
</TouchableOpacity>
<Text style={styles.title}>Bem vindo.</Text>
<Text style={styles.description}>Encontre no mapa um ponto de coleta.</Text>
<View style={styles.mapContainer}>
{ initialPosition[0] !== 0 && (
<MapView
style={styles.map}
initialRegion={{
latitude: initialPosition[0],
longitude: initialPosition[1],
latitudeDelta: 0.014,
longitudeDelta: 0.014,
}}
>
{selectedItems[0] !== undefined && (points.map(point => (
<Marker
key={String(point.id)}
style={styles.mapMarker}
onPress={() => handleNavigateToDetail(point.id)}
coordinate={{
latitude: point.latitude,
longitude: point.longitude,
}}
>
<View style={styles.mapMarkerContainer}>
<Image style={styles.mapMarkerImage} source={{ uri: point.image_url }} />
<Text style={styles.mapMarkerTitle}>{point.name}</Text>
</View>
</Marker>
)))}
</MapView>
) }
</View>
</View>
<View style={styles.itemsContainer}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={{ paddingHorizontal: 20 }}
>
{items.map(item => (
<TouchableOpacity
key={String(item.id)}
style={[
styles.item,
selectedItems.includes(item.id) ? styles.selectedItem : {}
]}
onPress={() => handleSelectItem(item.id)}
activeOpacity={0.6}
>
<SvgUri width={42} height={42} uri={item.image_url} />
<Text style={styles.itemTitle}>{item.title}</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>
</>
);
}
Example #26
Source File: index.tsx From nlw-ecoleta with MIT License | 4 votes |
Points = () => {
const [items, setItems] = useState<Item[]>([]);
const [points, setPoints] = useState<Point[]>([]);
const [selectedItems, setSelectedItems] = useState<number[]>([]);
const [initialPosition, setInitialPosition] = useState<[number, number]>([0, 0]);
const navigation = useNavigation();
const route = useRoute();
const routeParams = route.params as Params;
useEffect(() => {
async function loadPosition(){
const { status } = await Location.requestPermissionsAsync();
if(status !== 'granted') {
Alert.alert('Oooops...', 'Precisamos da sua permissão para obter a localização');
return;
}
const location = await Location.getCurrentPositionAsync();
const { latitude, longitude } = location.coords;
setInitialPosition([
latitude,
longitude
])
}
loadPosition();
}, []);
useEffect(() => {
api.get('items').then(response => {
console.log(response.data);
setItems(response.data);
});
}, []);
useEffect(() => {
api.get('points', {
params: {
city: routeParams.city,
uf: routeParams.uf,
items: selectedItems
}
}).then(response => {
console.log(response.data);
setPoints(response.data);
})
}, [selectedItems]);
function handleNavigateBack() {
navigation.goBack();
}
function handleNavigateToDetail(id: number) {
navigation.navigate('Detail', { point_id: id });
}
function handleSelectItem(id: number) {
const alreadySelected = selectedItems.findIndex(item => item === id);
if (alreadySelected >= 0) {
const filteredItems = selectedItems.filter(item => item !== id);
setSelectedItems(filteredItems);
}
else {
setSelectedItems([ ...selectedItems, id ]);
}
}
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<TouchableOpacity onPress={handleNavigateBack}>
<Icon name="arrow-left" size={20} color="#34cb79" />
</TouchableOpacity>
<Text style={styles.title}>Bem vindo.</Text>
<Text style={styles.description}>Encontre no mapa um ponto de coleta.</Text>
<View style={styles.mapContainer}>
{ initialPosition[0] !== 0 && (
<MapView
style={styles.map}
initialRegion={{
latitude: initialPosition[0],
longitude: initialPosition[1],
latitudeDelta: 0.014,
longitudeDelta: 0.014,
}}
>
{points.map(point => (
<Marker
key={String(point.id)}
style={styles.mapMarker}
onPress={() => handleNavigateToDetail(point.id)}
coordinate={{
latitude: point.latitude,
longitude: point.longitude,
}}
>
<View style={styles.mapMarkerContainer}>
<Image style={styles.mapMarkerImage} source={{ uri: point.image_url }} />
<Text style={styles.mapMarkerTitle}>{point.name}</Text>
</View>
</Marker>
))}
</MapView>
) }
</View>
</View>
<View style={styles.itemsContainer}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={{ paddingHorizontal: 20 }}
>
{items.map(item => (
<TouchableOpacity
key={String(item.id)}
style={[
styles.item,
selectedItems.includes(item.id) ? styles.selectedItem : {}
]}
onPress={() => handleSelectItem(item.id)}
activeOpacity={0.6}
>
<SvgUri width={42} height={42} uri={item.image_url} />
<Text style={styles.itemTitle}>{item.title}</Text>
</TouchableOpacity>
))}
</ScrollView>
</View>
</SafeAreaView>
);
}
Example #27
Source File: PostReply.tsx From lexicon with MIT License | 4 votes |
export default function PostReply() {
const { modal, setModal } = useModal();
const styles = useStyles();
const { colors } = useTheme();
const navigation = useNavigation<RootStackNavProp<'PostReply'>>();
const { navigate, goBack } = useNavigation<RootStackNavProp<'PostReply'>>();
let {
params: {
title,
topicId,
post,
focusedPostNumber,
editPostId,
oldContent = '',
editedUser,
hyperlinkTitle = '',
hyperlinkUrl,
imageUri = '',
},
} = useRoute<RootStackRouteProp<'PostReply'>>();
const ios = Platform.OS === 'ios';
const repliedPost = useMemo(() => {
if (post) {
return <RepliedPost hideAuthor replyTo={post} />;
}
return undefined;
}, [post]);
const storage = useStorage();
const user = storage.getItem('user');
const { authorizedExtensions } = useSiteSettings();
const extensions = authorizedExtensions?.split('|');
const normalizedExtensions = formatExtensions(extensions);
const kasv = useKASVWorkaround();
const [cursorPosition, setCursorPosition] = useState<CursorPosition>({
start: 0,
end: 0,
});
const [mentionLoading, setMentionLoading] = useState(false);
const [mentionKeyword, setMentionKeyword] = useState('');
const { control, handleSubmit, setValue, getValues, formState } = useForm<
Form
>({ mode: 'onChange' });
const [imagesArray, setImagesArray] = useState<Array<Image>>([]);
const [uri, setUri] = useState('');
const [isValid, setValid] = useState(false);
const [showUserList, setShowUserList] = useState(false);
const [currentUploadToken, setCurrentUploadToken] = useState(1);
const uploadsInProgress = imagesArray.filter((image) => !image.done).length;
const [isKeyboardShow, setKeyboardShow] = useState(false);
const debounced = useDebouncedCallback((value, token) => {
if (imagesArray[token - 1]) {
reformatMarkdownAfterUpload(value, imagesArray, token, setValue);
}
}, 1500);
const postReplyRef = useRef<TextInputType>(null);
const { upload, tempArray, completedToken } = useStatefulUpload(
imagesArray,
currentUploadToken,
);
useEffect(() => {
const { raw } = getValues();
if (completedToken) {
debounced(raw, completedToken);
}
setImagesArray(tempArray);
}, [getValues, tempArray, debounced, completedToken]);
useEffect(() => setUri(imageUri), [imageUri]);
const { mentionMembers } = useMention(
mentionKeyword,
showUserList,
setMentionLoading,
);
useEffect(() => {
if (!uri || !user) {
return;
}
setImagesArray([...imagesArray, { link: '', done: false }]);
setCurrentUploadToken(currentUploadToken + 1);
const reactNativeFile = createReactNativeFile(uri);
const { raw } = getValues();
reformatMarkdownBeforeUpload(
raw,
cursorPosition.start,
imagesArray,
setValue,
);
upload({
variables: {
file: reactNativeFile,
userId: user.id || 0,
type: UploadTypeEnum.composer,
token: currentUploadToken,
},
});
setUri('');
}, [
currentUploadToken,
cursorPosition.start,
imagesArray,
getValues,
setValue,
upload,
uploadsInProgress,
uri,
user,
]);
if (hyperlinkUrl) {
let { newUrl, newTitle } = getHyperlink(hyperlinkUrl, hyperlinkTitle);
hyperlinkUrl = newUrl;
hyperlinkTitle = newTitle;
}
useEffect(() => {
setModal(true);
}, [setModal]);
useEffect(() => {
let postReplyObject = getValues();
let result = insertHyperlink(
postReplyObject.raw,
hyperlinkTitle,
hyperlinkUrl,
);
setValue('raw', result);
}, [hyperlinkTitle, hyperlinkUrl, getValues, setValue]);
const onNavigate = (
screen: 'PostImagePreview' | 'HyperLink',
params:
| RootStackParamList['PostImagePreview']
| RootStackParamList['HyperLink'],
) => {
navigate(screen, params);
};
const { onInsertImage, onInsertLink } = bottomMenu(
isKeyboardShow,
user,
onNavigate,
'PostReply',
normalizedExtensions,
title,
topicId,
post,
);
useEffect(
() =>
navigation.addListener('beforeRemove', (e) => {
if (
(!isValid || !formState.isValid || !modal) &&
uploadsInProgress < 1
) {
return;
}
e.preventDefault();
Alert.alert(
t('Discard Post Reply?'),
t('Are you sure you want to discard your post reply?'),
[
{ text: t('Cancel') },
{
text: t('Discard'),
onPress: () => navigation.dispatch(e.data.action),
},
],
);
}),
[formState.isValid, isValid, modal, navigation, uploadsInProgress],
);
const getData = () => {
const { raw } = getValues();
return {
title,
content: raw,
topicId,
post,
createdAt: new Date().toISOString(),
};
};
const onPreview = handleSubmit(() => {
Keyboard.dismiss();
navigate('PostPreview', {
reply: true,
postData: getData(),
focusedPostNumber,
editPostId,
editedUser,
});
});
useEffect(() => {
const { raw: content } = getValues();
let isValid;
if (editPostId) {
isValid = existingPostIsValid(
uploadsInProgress,
title,
title,
content,
oldContent,
);
} else {
isValid = newPostIsValid(title, content, uploadsInProgress);
}
setValid(isValid);
}, [editPostId, getValues, oldContent, title, uploadsInProgress]);
return (
<SafeAreaView style={styles.container}>
<CustomHeader
title={editPostId ? t('Edit Post') : t('Reply')}
rightTitle={t('Next')}
onPressRight={onPreview}
disabled={!isValid}
noShadow
/>
{ios && (
<ModalHeader
title={editPostId ? t('Edit Post') : t('Reply')}
left={<HeaderItem label={t('Cancel')} onPressItem={goBack} left />}
right={
<HeaderItem
label={t('Next')}
onPressItem={onPreview}
disabled={!isValid}
/>
}
/>
)}
<KeyboardTextAreaScrollView
{...kasv.props}
bottomMenu={
<View>
<MentionList
showUserList={showUserList}
members={mentionMembers}
mentionLoading={mentionLoading}
rawText={getValues('raw')}
textRef={postReplyRef}
setMentionValue={setValue}
setShowUserList={setShowUserList}
/>
<BottomMenu
onInsertImage={onInsertImage}
onInsertLink={onInsertLink}
/>
</View>
}
>
<IconWithLabel
icon="Replies"
color={colors.textLighter}
label={title}
fontStyle={styles.title}
style={styles.titleContainer}
numberOfLines={1}
/>
<Divider style={styles.spacingBottom} horizontalSpacing="xxl" />
{repliedPost}
<Controller
name="raw"
defaultValue={oldContent}
rules={{ required: true }}
control={control}
render={({ onChange, value }) => (
<TextArea
value={value}
large
isKeyboardShow={isKeyboardShow}
inputRef={postReplyRef}
placeholder={t('Share your thoughts')}
onChangeValue={(text) => {
mentionHelper(
text,
cursorPosition,
setShowUserList,
setMentionLoading,
setMentionKeyword,
);
onChange(text);
debounced(text, currentUploadToken);
let isValid;
if (editPostId) {
isValid = existingPostIsValid(
uploadsInProgress,
title,
title,
text,
oldContent,
);
} else {
isValid = newPostIsValid(title, text, uploadsInProgress);
}
setValid(isValid);
}}
onFocus={(event) => {
setKeyboardShow(true);
kasv.scrollToFocusedInput(event);
}}
onBlur={() => {
setKeyboardShow(false);
}}
onSelectedChange={(cursor) => {
setCursorPosition(cursor);
}}
style={styles.markdownContainer}
mentionToggled={showUserList}
/>
)}
/>
</KeyboardTextAreaScrollView>
</SafeAreaView>
);
}
Example #28
Source File: OrphanageData.tsx From nlw-03-omnistack with MIT License | 4 votes |
export default function OrphanageData() {
const route = useRoute();
const navigation = useNavigation();
const [open_on_weekends, setOpenOnWeekends] = useState(false);
const params = route.params as OrphanageDataRouteParams;
const position = params.position;
function handleCreateOrphanage() {
// todo
}
async function handleSelectImages() {
const { status } = await ImagePicker.requestCameraRollPermissionsAsync();
if (status !== 'granted') {
alert('Eita! Precisamos de acesso às suas fotos...');
}
const result = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
quality: 1,
});
console.log(result);
}
return (
<ScrollView style={styles.container} contentContainerStyle={{ padding: 24 }}>
<Text style={styles.title}>Dados</Text>
<Text style={styles.label}>Nome</Text>
<TextInput
style={styles.input}
/>
<Text style={styles.label}>Sobre</Text>
<TextInput
style={[styles.input, { height: 110 }]}
multiline
/>
<Text style={styles.label}>Whatsapp</Text>
<TextInput
style={styles.input}
/>
<Text style={styles.label}>Fotos</Text>
<TouchableOpacity style={styles.imagesInput} onPress={handleSelectImages}>
<Feather name="plus" size={24} color="#15B6D6" />
</TouchableOpacity>
<Text style={styles.title}>Visitação</Text>
<Text style={styles.label}>Instruções</Text>
<TextInput
style={[styles.input, { height: 110 }]}
multiline
/>
<Text style={styles.label}>Horario de visitas</Text>
<TextInput
style={styles.input}
/>
<View style={styles.switchContainer}>
<Text style={styles.label}>Atende final de semana?</Text>
<Switch
thumbColor="#fff"
trackColor={{ false: '#ccc', true: '#39CC83' }}
value={open_on_weekends}
onValueChange={setOpenOnWeekends}
/>
</View>
<RectButton style={styles.nextButton} onPress={handleCreateOrphanage}>
<Text style={styles.nextButtonText}>Cadastrar</Text>
</RectButton>
</ScrollView>
)
}
Example #29
Source File: AddEditAddressScene.tsx From sellflow with MIT License | 4 votes |
export default function AddEditAddressScene() {
let { authToken: customerAccessToken } = useAuth();
let { navigate, setOptions } = useNavigation<
StackNavProp<'AddEditAddress'>
>();
let {
params: { address, rootScene },
} = useRoute<StackRouteProp<'AddEditAddress'>>();
let [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false);
let [isCountryModalVisible, setIsCountryModalVisible] = useState(false);
let [addressData, setAddressData] = useState<
Omit<AddressItem, 'id' | 'name'>
>(newAddress);
let [isModalVisible, setIsModalVisible] = useState(false);
let [errorMessage, setErrorMessage] = useState('');
let [bottomButtonHeight, setBottomButtonHeight] = useState(0);
let isAddressDataEmpty =
addressData.address1 === '' ||
addressData.city === '' ||
addressData.country === '' ||
addressData.firstName === '' ||
addressData.lastName === '' ||
addressData.phone === '' ||
addressData.province === '' ||
addressData.zip === '';
let lastNameRef = useRef<TextInputType>(null);
let address1Ref = useRef<TextInputType>(null);
let provinceRef = useRef<TextInputType>(null);
let cityRef = useRef<TextInputType>(null);
let zipRef = useRef<TextInputType>(null);
let phoneRef = useRef<TextInputType>(null);
let {
addNewAddress,
loading: loadingAddNewAddress,
} = useCustomerAddNewAddress();
let { editAddress, loading: loadingEditAddress } = useCustomerEditAddress({
onCompleted: () => {
navigate(rootScene);
},
});
let toggleModalVisible = () => setIsModalVisible(!isModalVisible);
let {
customerAddressDelete,
loading: loadingDeleteAddress,
} = useCustomerAddressDelete({
onCompleted: () => {
navigate(rootScene);
},
});
useEffect(() => {
if (address) {
setAddressData({
firstName: address.firstName,
lastName: address.lastName,
address1: address.address1,
city: address.city,
province: address.province,
zip: address.zip,
country: address.country,
phone: address.phone,
});
}
}, [address]);
let toggleDeleteModal = () => {
setIsDeleteModalVisible(!isDeleteModalVisible);
};
let toggleCountryModal = () => {
setIsCountryModalVisible(!isCountryModalVisible);
};
let onPressCancel = () => {
toggleDeleteModal();
};
let onPressDelete = () => {
toggleDeleteModal();
customerAddressDelete({
variables: { id: address?.id ?? '', customerAccessToken },
});
};
let onPressCountry = (country: string) => {
toggleCountryModal();
setAddressData({ ...addressData, country });
provinceRef.current && provinceRef.current.focus();
};
let onPressSaveAddress = async () => {
if (address === undefined) {
let result = await addNewAddress({
variables: {
customerAccessToken,
address: addressData,
},
});
let customerUserErrors =
result?.data?.customerAddressCreate?.customerUserErrors;
if (customerUserErrors && customerUserErrors.length > 0) {
setErrorMessage(customerUserErrors[0].message);
toggleModalVisible();
} else {
navigate(rootScene);
}
} else {
let result = await editAddress({
variables: {
id: address?.id ?? '',
customerAccessToken,
address: addressData,
},
});
let customerUserErrors =
result?.data?.customerAddressUpdate?.customerUserErrors;
if (customerUserErrors && customerUserErrors.length > 0) {
setErrorMessage(customerUserErrors[0].message);
toggleModalVisible();
} else {
navigate(rootScene);
}
}
};
useEffect(() => {
setOptions({
title: address == null ? t('New Address') : t('Edit Address'),
headerRight: () => {
return address != null ? (
<Text
weight="medium"
style={styles.headerRightText}
onPress={toggleDeleteModal}
>
{t('Delete')}
</Text>
) : null;
},
});
});
if (loadingDeleteAddress) {
return <ActivityIndicator style={styles.centered} />;
}
return (
<KeyboardAvoidingView keyboardVerticalOffset={bottomButtonHeight}>
<ModalBottomSheet
title={t('An Error Occured!')}
isModalVisible={isModalVisible}
toggleModal={toggleModalVisible}
>
<ModalBottomSheetMessage
isError={true}
message={errorMessage}
onPressModalButton={toggleModalVisible}
buttonText={t('Close')}
/>
</ModalBottomSheet>
<DeleteAddressModal
deleteVisible={isDeleteModalVisible}
toggleModal={toggleDeleteModal}
onPressCancel={onPressCancel}
onPressDelete={onPressDelete}
/>
<CountryModal
countryVisible={isCountryModalVisible}
toggleModal={toggleCountryModal}
onPressCountry={onPressCountry}
/>
<ScrollView
style={styles.scrollView}
showsVerticalScrollIndicator={false}
>
<TextInput
onSubmitEditing={() => {
lastNameRef.current && lastNameRef.current.focus();
}}
returnKeyType="next"
mode="flat"
label={t('First Name')}
labelStyle={textInputLabel}
value={addressData.firstName}
onChangeText={(firstName: string) =>
setAddressData({ ...addressData, firstName })
}
containerStyle={flatTextInputContainerStyle}
style={flatTextInputStyle}
/>
<TextInput
onSubmitEditing={() => {
address1Ref.current && address1Ref.current.focus();
}}
ref={lastNameRef}
returnKeyType="next"
mode="flat"
label={t('Last Name')}
labelStyle={textInputLabel}
value={addressData.lastName}
onChangeText={(lastName: string) =>
setAddressData({ ...addressData, lastName })
}
containerStyle={flatTextInputContainerStyle}
style={flatTextInputStyle}
/>
<TextInput
onSubmitEditing={toggleCountryModal}
returnKeyType="next"
ref={address1Ref}
mode="flat"
label={t('Address')}
labelStyle={textInputLabel}
value={addressData.address1}
onChangeText={(address1: string) =>
setAddressData({ ...addressData, address1 })
}
containerStyle={flatTextInputContainerStyle}
style={flatTextInputStyle}
autoCapitalize="words"
/>
<TouchableOpacity onPress={toggleCountryModal}>
<TextInput
mode="flat"
label={t('Country')}
labelStyle={textInputLabel}
value={addressData.country}
pointerEvents="none"
editable={false}
containerStyle={flatTextInputContainerStyle}
style={flatTextInputStyle}
/>
</TouchableOpacity>
<TextInput
onSubmitEditing={() => {
cityRef.current && cityRef.current.focus();
}}
returnKeyType="next"
ref={provinceRef}
mode="flat"
label={t('State / Province')}
labelStyle={textInputLabel}
value={addressData.province}
onChangeText={(province: string) =>
setAddressData({ ...addressData, province })
}
containerStyle={flatTextInputContainerStyle}
style={flatTextInputStyle}
autoCapitalize="words"
/>
<TextInput
onSubmitEditing={() => {
zipRef.current && zipRef.current.focus();
}}
returnKeyType="next"
ref={cityRef}
mode="flat"
label={t('City')}
labelStyle={textInputLabel}
value={addressData.city}
onChangeText={(city: string) =>
setAddressData({ ...addressData, city })
}
containerStyle={flatTextInputContainerStyle}
style={flatTextInputStyle}
autoCapitalize="words"
/>
<TextInput
onSubmitEditing={() => {
phoneRef.current && phoneRef.current.focus();
}}
returnKeyType="next"
ref={zipRef}
mode="flat"
label={t('Postal / Zip Code')}
labelStyle={textInputLabel}
value={addressData.zip}
onChangeText={(zip: string) =>
setAddressData({ ...addressData, zip })
}
containerStyle={flatTextInputContainerStyle}
style={flatTextInputStyle}
/>
<TextInput
returnKeyType="done"
ref={phoneRef}
mode="flat"
label={t('Phone Number')}
labelStyle={textInputLabel}
value={addressData.phone}
onChangeText={(phone: string) =>
setAddressData({ ...addressData, phone })
}
keyboardType="number-pad"
textContentType="telephoneNumber"
containerStyle={flatTextInputContainerStyle}
style={flatTextInputStyle}
/>
</ScrollView>
<View
onLayout={({ nativeEvent }) =>
setBottomButtonHeight(nativeEvent.layout.height)
}
>
<Button
style={[defaultButton, styles.buttonStyle]}
labelStyle={defaultButtonLabel}
onPress={onPressSaveAddress}
disabled={isAddressDataEmpty}
loading={loadingAddNewAddress || loadingEditAddress}
>
<Text weight="medium" style={styles.buttonText}>
{!loadingAddNewAddress && !loadingEditAddress && t('Save Address')}
</Text>
</Button>
</View>
</KeyboardAvoidingView>
);
}