1
1
(ns react-native.fast-image
2
2
(:require
3
- [" react-native-fast-image" :as FastImage]
4
- [react-native.core :as rn]
5
- [reagent.core :as reagent]))
3
+ [" react-native-fast-image" :as FastImage]
4
+ [clojure.string :as string]
5
+ [oops.core :as oops]
6
+ [react-native.core :as rn]
7
+ [reagent.core :as reagent]))
6
8
7
- (def internal-fast-image (reagent/adapt-react-class ^js FastImage))
9
+ (defn- build-source
10
+ [source]
11
+ (if (string? source)
12
+ {:uri source
13
+ :priority :high }
14
+ source))
15
+
16
+ (defn- remove-port
17
+ [source]
18
+ (if (string? source)
19
+ (string/replace-first source #":\d +" " " )
20
+ (string/replace-first (oops/oget source :uri ) #":\d +" " " )))
8
21
9
22
(defn- placeholder
10
23
[{:keys [style fallback-content error? loaded?]}]
11
- [rn/view
12
- {:style (assoc style
13
- :flex 1
14
- :justify-content :center
15
- :align-items :center )}
24
+ [rn/view {:style (assoc style
25
+ :flex 1
26
+ :justify-content :center
27
+ :align-items :center )}
16
28
(cond
17
29
(and error? fallback-content) fallback-content
18
30
error? [rn/text " X" ]
19
31
(not loaded?) [rn/activity-indicator {:animating true }])])
20
32
21
- (defn- get-source
22
- [source]
23
- (if (string? source)
24
- {:uri source
25
- :priority :high }
26
- source))
27
-
28
- ; ; NOTE: We need to use ratoms to avoid the flickering since their state is updated
29
- ; ; altogether at the end of the frame (different from hooks), this allows us to display
30
- ; ; both uses of `internal-fast-image` always in sync.
31
- (defn fast-image
33
+ ; ; We cannot use hooks since `reactify-component` seems to ignore the functional compiler
34
+ (defn- internal-fast-image
32
35
[_]
33
36
(let [loaded? (reagent/atom false )
34
37
error? (reagent/atom false )
35
- previous-source (reagent/atom nil )
36
38
on-image-error (fn [event on-error]
37
39
(when (fn? on-error) (on-error event))
38
40
(reset! error? true ))
39
- on-image-loaded (fn [event on-load source ]
41
+ on-image-loaded (fn [event on-load]
40
42
(when (fn? on-load) (on-load event))
41
43
(reset! loaded? true )
42
- (reset! error? false )
43
- (reset! previous-source source))]
44
+ (reset! error? false ))]
44
45
(fn [{:keys [source fallback-content on-error on-load] :as props}]
45
- [internal-fast-image
46
+ [:> FastImage
46
47
(assoc props
47
- :source (get-source source)
48
- :on-error #(on-image-error % on-error)
49
- :on-load #(on-image-loaded % on-load source))
50
- (cond
51
- @previous-source
52
- [internal-fast-image (assoc props :source (get-source @previous-source))]
53
-
54
- (or @error? (not @loaded?))
48
+ :source (build-source source)
49
+ :on-error #(on-image-error % on-error)
50
+ :on-load #(on-image-loaded % on-load))
51
+ (when (or @error? (not @loaded?))
55
52
[placeholder
56
- {:style (:style props)
53
+ {:style (js->clj ( :style props) )
57
54
:fallback-content fallback-content
58
55
:error? @error?
59
56
:loaded? @loaded?}])])))
57
+
58
+ (defn- compare-sources [old-props new-props]
59
+ (let [old-source (oops/oget old-props :source )
60
+ new-source (oops/oget new-props :source )]
61
+ (and old-source
62
+ new-source
63
+ (= (remove-port old-source) (remove-port new-source)))))
64
+
65
+ (def fast-image
66
+ (-> internal-fast-image
67
+ (reagent/reactify-component )
68
+ (rn/memo compare-sources)
69
+ (reagent/adapt-react-class )))
0 commit comments