Skip to content

Commit 5d310de

Browse files
authored
Fixes App crash when left for a long time (#160)
* Load URI preview based on network state * Handle URL preview endpoint failures * Inline response * Formats code * Improve performance * Improve code
1 parent 2b7062b commit 5d310de

File tree

3 files changed

+54
-18
lines changed

3 files changed

+54
-18
lines changed

app/components/Preview/Types/PreviewUri.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { JSONStringType } from "@jsonhero/json-infer-types/lib/@types";
22
import { useEffect } from "react";
33
import { useFetcher } from "remix";
44
import { Body } from "~/components/Primitives/Body";
5+
import { useLoadWhenOnline } from "~/hooks/useLoadWhenOnline";
56
import { PreviewBox } from "../PreviewBox";
67
import { PreviewResult } from "./preview.types";
78
import { PreviewUriElement } from "./PreviewUriElement";
@@ -13,11 +14,10 @@ export type PreviewUriProps = {
1314

1415
export function PreviewUri(props: PreviewUriProps) {
1516
const previewFetcher = useFetcher<PreviewResult>();
17+
const encodedUri = encodeURIComponent(props.value);
18+
const load = () => previewFetcher.load(`/actions/getPreview/${encodedUri}`);
1619

17-
useEffect(() => {
18-
const encodedUri = encodeURIComponent(props.value);
19-
previewFetcher.load(`/actions/getPreview/${encodedUri}`);
20-
}, [props.value]);
20+
useLoadWhenOnline(load, [encodedUri]);
2121

2222
return (
2323
<div>

app/hooks/useLoadWhenOnline.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { useEffect, useRef } from "react";
2+
3+
export function useLoadWhenOnline(callback: () => void, deps: unknown[] = []) {
4+
const callbackRef = useRef <() => void>(callback);
5+
6+
useEffect(() => {
7+
callbackRef.current = callback;
8+
});
9+
10+
useEffect(() => {
11+
const cb = () => callbackRef.current();
12+
13+
if (window.navigator.onLine) {
14+
cb();
15+
return;
16+
}
17+
18+
window.addEventListener("online", cb);
19+
20+
return () => {
21+
window.removeEventListener("online", cb);
22+
};
23+
}, [...deps]);
24+
}

app/routes/actions/getPreview.$url.ts

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,41 @@ import invariant from "tiny-invariant";
33
import { getUriPreview } from "~/services/uriPreview.server";
44

55
export const loader: LoaderFunction = async ({ params }) => {
6-
invariant(params.url, "expected params.url");
6+
try {
7+
invariant(params.url, "expected params.url");
78

8-
const decoded = decodeURIComponent(params.url);
9+
const decoded = decodeURIComponent(params.url);
910

10-
const earlyReturn = earlyRespondIfHomepagePreviewUri(decoded);
11+
const earlyReturn = earlyRespondIfHomepagePreviewUri(decoded);
1112

12-
if (earlyReturn) {
13-
return new Response(JSON.stringify(earlyReturn), {
13+
if (earlyReturn) {
14+
return new Response(JSON.stringify(earlyReturn), {
15+
headers: {
16+
"Content-Type": "application/json; charset=utf-8",
17+
"Cache-Control": "public, max-age=3600",
18+
},
19+
});
20+
}
21+
22+
const result = await getUriPreview(decoded);
23+
24+
return new Response(JSON.stringify(result), {
1425
headers: {
1526
"Content-Type": "application/json; charset=utf-8",
1627
"Cache-Control": "public, max-age=3600",
1728
},
1829
});
30+
} catch {
31+
return new Response(
32+
JSON.stringify({ error: "Unable to preview this URL" }),
33+
{
34+
headers: {
35+
"Content-Type": "application/json; charset=utf-8",
36+
"Cache-Control": "public, max-age=3600",
37+
},
38+
}
39+
);
1940
}
20-
21-
const result = await getUriPreview(decoded);
22-
23-
return new Response(JSON.stringify(result), {
24-
headers: {
25-
"Content-Type": "application/json; charset=utf-8",
26-
"Cache-Control": "public, max-age=3600",
27-
},
28-
});
2941
};
3042

3143
function earlyRespondIfHomepagePreviewUri(uri: string) {

0 commit comments

Comments
 (0)