UNPKG

4.29 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var slicedToArray = require('./slicedToArray-0711941d.js');
8require('./unsupportedIterableToArray-68db1d3b.js');
9var React = require('react');
10var React__default = _interopDefault(React);
11
12var A_DAY = 1000 * 60 * 60 * 24;
13
14function cachedMap() {
15 var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
16 _ref$expireAfter = _ref.expireAfter,
17 expireAfter = _ref$expireAfter === void 0 ? A_DAY : _ref$expireAfter,
18 _ref$size = _ref.size,
19 size = _ref$size === void 0 ? 100 : _ref$size;
20
21 var cache = new Map(); // Delete the first (oldest) entry if we are above `size`. `cache.size`
22 // should never be greater than `size + 1`, so no need for a loop here.
23
24 function trim() {
25 if (cache.size > size) {
26 cache.delete(cache.keys().next().value);
27 }
28 } // We are using delete() then set() to reset the position everytime the
29 // access is refreshed. That way, the oldest entry is always at the first
30 // position and we don’t need to iterate over the entire cache to find it.
31
32
33 function update(key, value, lastAccess) {
34 cache.delete(key);
35 cache.set(key, {
36 value: value,
37 lastAccess: lastAccess
38 });
39 trim();
40 }
41
42 function get(key) {
43 var now = new Date();
44 var cachedEntry = cache.get(key);
45
46 if (!cachedEntry) {
47 return null;
48 } // Expired: delete the entry
49
50
51 if (now - cachedEntry.lastAccess > expireAfter) {
52 cache.delete(key);
53 return null;
54 }
55
56 update(key, cachedEntry.value, now);
57 return cachedEntry.value;
58 }
59
60 function set(key, value) {
61 update(key, value, new Date());
62 }
63
64 return {
65 clear: function clear() {
66 return cache.clear();
67 },
68 delete: function _delete(key) {
69 return cache.delete(key);
70 },
71 get: get,
72 set: set
73 };
74}
75
76var srcCache = cachedMap(); // Check if a remote image exists and can be loaded within a specific amount of time.
77
78function useImageExists(src) {
79 var timeUntilFallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 50;
80
81 var _useState = React.useState(false),
82 _useState2 = slicedToArray._slicedToArray(_useState, 2),
83 exists = _useState2[0],
84 setExists = _useState2[1];
85
86 var _useState3 = React.useState(true),
87 _useState4 = slicedToArray._slicedToArray(_useState3, 2),
88 loading = _useState4[0],
89 setLoading = _useState4[1];
90
91 var _useState5 = React.useState(false),
92 _useState6 = slicedToArray._slicedToArray(_useState5, 2),
93 displayFallback = _useState6[0],
94 setDisplayFallback = _useState6[1];
95
96 React.useEffect(function () {
97 var image = new Image();
98 var fallbackTimer = setTimeout(function () {
99 return setDisplayFallback(true);
100 }, timeUntilFallback);
101
102 var init = function init() {
103 if (!src) {
104 setExists(false);
105 setLoading(false);
106 return;
107 }
108
109 if (srcCache.get(src)) {
110 success();
111 return;
112 }
113
114 setExists(false);
115 setLoading(true); // TODO: ensure only one image is loading at a time for a given src.
116
117 image.addEventListener('load', success);
118 image.src = src;
119 };
120
121 var success = function success() {
122 setLoading(false);
123 setExists(true);
124 srcCache.set(src, true);
125 done();
126 };
127
128 var done = function done() {
129 clearTimeout(fallbackTimer);
130
131 if (image) {
132 image.removeEventListener('load', success);
133 image = null;
134 }
135 };
136
137 init();
138 return done;
139 }, [src, timeUntilFallback]);
140 return React.useMemo(function () {
141 return {
142 src: src,
143 displayFallback: displayFallback,
144 exists: exists,
145 loading: loading
146 };
147 }, [src, displayFallback, exists, loading]);
148} // render prop
149
150var ImageExists = function ImageExists(_ref) {
151 var timeUntilFallback = _ref.timeUntilFallback,
152 src = _ref.src,
153 children = _ref.children;
154 return children(useImageExists(src, timeUntilFallback));
155};
156
157exports.ImageExists = ImageExists;
158exports.useImageExists = useImageExists;
159//# sourceMappingURL=useImageExists.js.map