Skip to content

Commit

Permalink
Feat request timeout (#25)
Browse files Browse the repository at this point in the history
* feat: add request timeout

* feat: add prop `requestTimeout`

* add docs for `requestTimeout` prop

* Update README.md

Co-authored-by: Thomas P. <[email protected]>

Co-authored-by: Thomas P. <[email protected]>
  • Loading branch information
ammarahm-ed and TPXP authored Jan 27, 2022
1 parent 16d6892 commit 5ecd937
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ return (
| renderTitle | (string) => ReactNode | Custom title render prop |
| textContainerStyle | [ViewStyle](https://reactnative.dev/docs/view-style-props) | Text, title, description and minimized image container style |
| touchableWithoutFeedbackProps | TouchableWithoutFeedbackProps | Top level touchable props |
| requestTimeout | number | Timeout after which request to get preview data should abort |

## License

Expand Down
6 changes: 4 additions & 2 deletions src/LinkPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ export interface LinkPreviewProps {
renderTitle?: (title: string) => React.ReactNode
text: string
textContainerStyle?: StyleProp<ViewStyle>
touchableWithoutFeedbackProps?: TouchableWithoutFeedbackProps
touchableWithoutFeedbackProps?: TouchableWithoutFeedbackProps,
requestTimeout?:number
}

export const LinkPreview = React.memo(
Expand All @@ -59,6 +60,7 @@ export const LinkPreview = React.memo(
text,
textContainerStyle,
touchableWithoutFeedbackProps,
requestTimeout = 5000
}: LinkPreviewProps) => {
const [containerWidth, setContainerWidth] = React.useState(0)
const [data, setData] = React.useState(previewData)
Expand All @@ -75,7 +77,7 @@ export const LinkPreview = React.memo(

const fetchData = async () => {
setData(undefined)
const newData = await getPreviewData(text)
const newData = await getPreviewData(text, requestTimeout)
// Set data only if component is still mounted
/* istanbul ignore next */
if (!isCancelled) {
Expand Down
15 changes: 13 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const getImageSize = (url: string) => {

// Functions below use functions from the same file and mocks are not working
/* istanbul ignore next */
export const getPreviewData = async (text: string) => {
export const getPreviewData = async (text: string, requestTimeout=5000) => {
const previewData: PreviewData = {
description: undefined,
image: undefined,
Expand All @@ -77,13 +77,24 @@ export const getPreviewData = async (text: string) => {
url = 'https://' + url
}

const response = await fetch(url, {
let abortControllerTimeout: NodeJS.Timeout;
const abortController = new AbortController();

const request = fetch(url, {
headers: {
'User-Agent':
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
},
signal:abortController.signal
})

abortControllerTimeout = setTimeout(() => {
abortController.abort();
}, requestTimeout);
const response = await request;

clearTimeout(abortControllerTimeout);

previewData.link = url

const contentType = response.headers.get('content-type') ?? ''
Expand Down

0 comments on commit 5ecd937

Please sign in to comment.