浏览代码

[RN] Replace cached image implementation

Use react-native-fastimage, which uses 2 full-native image impleentations using
well known and mature (native) libraries.

This gets us rid of 2 libraries which were observerd as a source of bugs and
created trouble with dependencies: react-native-fetch-blob and
react-native-img-cache. They are also no longer well maintained.
master
Saúl Ibarra Corretgé 7 年前
父节点
当前提交
27021ea271

+ 6
- 0
android/app/proguard-rules.pro 查看文件

@@ -68,3 +68,9 @@
68 68
 -dontwarn java.nio.file.*
69 69
 -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
70 70
 -dontwarn okio.**
71
+
72
+# FastImage
73
+
74
+-keep public class com.dylanvann.fastimage.* {*;}
75
+-keep public class com.dylanvann.fastimage.** {*;}
76
+

+ 1
- 1
android/sdk/build.gradle 查看文件

@@ -25,7 +25,7 @@ dependencies {
25 25
     compile 'com.facebook.react:react-native:+'
26 26
 
27 27
     compile project(':react-native-background-timer')
28
-    compile project(':react-native-fetch-blob')
28
+    compile project(':react-native-fast-image')
29 29
     compile project(':react-native-immersive')
30 30
     compile project(':react-native-keep-awake')
31 31
     compile project(':react-native-linear-gradient')

+ 1
- 1
android/sdk/src/main/java/org/jitsi/meet/sdk/ReactInstanceManagerHolder.java 查看文件

@@ -122,12 +122,12 @@ class ReactInstanceManagerHolder {
122 122
                 .addPackage(new com.BV.LinearGradient.LinearGradientPackage())
123 123
                 .addPackage(new com.calendarevents.CalendarEventsPackage())
124 124
                 .addPackage(new com.corbt.keepawake.KCKeepAwakePackage())
125
+                .addPackage(new com.dylanvann.fastimage.FastImageViewPackage())
125 126
                 .addPackage(new com.facebook.react.shell.MainReactPackage())
126 127
                 .addPackage(new com.i18n.reactnativei18n.ReactNativeI18n())
127 128
                 .addPackage(new com.oblador.vectoricons.VectorIconsPackage())
128 129
                 .addPackage(new com.ocetnik.timer.BackgroundTimerPackage())
129 130
                 .addPackage(new com.oney.WebRTCModule.WebRTCModulePackage())
130
-                .addPackage(new com.RNFetchBlob.RNFetchBlobPackage())
131 131
                 .addPackage(new com.rnimmersive.RNImmersivePackage())
132 132
                 .addPackage(new com.zmxv.RNSound.RNSoundPackage())
133 133
                 .addPackage(new ReactPackageAdapter() {

+ 2
- 2
android/settings.gradle 查看文件

@@ -3,8 +3,8 @@ rootProject.name = 'jitsi-meet'
3 3
 include ':app', ':sdk'
4 4
 include ':react-native-background-timer'
5 5
 project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
6
-include ':react-native-fetch-blob'
7
-project(':react-native-fetch-blob').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fetch-blob/android')
6
+include ':react-native-fast-image'
7
+project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android')
8 8
 include ':react-native-immersive'
9 9
 project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
10 10
 include ':react-native-keep-awake'

+ 2
- 2
ios/Podfile 查看文件

@@ -28,8 +28,8 @@ target 'JitsiMeet' do
28 28
 
29 29
   pod 'react-native-background-timer',
30 30
     :path => '../node_modules/react-native-background-timer'
31
-  pod 'react-native-fetch-blob',
32
-    :path => '../node_modules/react-native-fetch-blob'
31
+  pod 'react-native-fast-image',
32
+    :path => '../node_modules/react-native-fast-image'
33 33
   pod 'react-native-keep-awake',
34 34
     :path => '../node_modules/react-native-keep-awake'
35 35
   pod 'react-native-locale-detector',

+ 19
- 7
ios/Podfile.lock 查看文件

@@ -1,6 +1,7 @@
1 1
 PODS:
2 2
   - boost-for-react-native (1.63.0)
3 3
   - DoubleConversion (1.1.5)
4
+  - FLAnimatedImage (1.0.12)
4 5
   - Folly (2016.09.26.00):
5 6
     - boost-for-react-native
6 7
     - DoubleConversion
@@ -12,8 +13,11 @@ PODS:
12 13
     - React
13 14
   - react-native-calendar-events (1.6.0):
14 15
     - React
15
-  - react-native-fetch-blob (0.10.6):
16
-    - React/Core
16
+  - react-native-fast-image (4.0.14):
17
+    - FLAnimatedImage
18
+    - React
19
+    - SDWebImage/Core
20
+    - SDWebImage/GIF
17 21
   - react-native-keep-awake (2.0.6):
18 22
     - React
19 23
   - react-native-locale-detector (1.0.0):
@@ -68,6 +72,10 @@ PODS:
68 72
     - React/Core
69 73
   - RNVectorIcons (4.4.2):
70 74
     - React
75
+  - SDWebImage/Core (4.4.1)
76
+  - SDWebImage/GIF (4.4.1):
77
+    - FLAnimatedImage (~> 1.0)
78
+    - SDWebImage/Core
71 79
   - yoga (0.55.4.React)
72 80
 
73 81
 DEPENDENCIES:
@@ -76,7 +84,7 @@ DEPENDENCIES:
76 84
   - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
77 85
   - react-native-background-timer (from `../node_modules/react-native-background-timer`)
78 86
   - react-native-calendar-events (from `../node_modules/react-native-calendar-events`)
79
-  - react-native-fetch-blob (from `../node_modules/react-native-fetch-blob`)
87
+  - react-native-fast-image (from `../node_modules/react-native-fast-image`)
80 88
   - react-native-keep-awake (from `../node_modules/react-native-keep-awake`)
81 89
   - react-native-locale-detector (from `../node_modules/react-native-locale-detector`)
82 90
   - react-native-webrtc (from `../node_modules/react-native-webrtc`)
@@ -98,6 +106,8 @@ DEPENDENCIES:
98 106
 SPEC REPOS:
99 107
   https://github.com/cocoapods/specs.git:
100 108
     - boost-for-react-native
109
+    - FLAnimatedImage
110
+    - SDWebImage
101 111
 
102 112
 EXTERNAL SOURCES:
103 113
   DoubleConversion:
@@ -112,8 +122,8 @@ EXTERNAL SOURCES:
112 122
     :path: "../node_modules/react-native-background-timer"
113 123
   react-native-calendar-events:
114 124
     :path: "../node_modules/react-native-calendar-events"
115
-  react-native-fetch-blob:
116
-    :path: "../node_modules/react-native-fetch-blob"
125
+  react-native-fast-image:
126
+    :path: "../node_modules/react-native-fast-image"
117 127
   react-native-keep-awake:
118 128
     :path: "../node_modules/react-native-keep-awake"
119 129
   react-native-locale-detector:
@@ -132,20 +142,22 @@ EXTERNAL SOURCES:
132 142
 SPEC CHECKSUMS:
133 143
   boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
134 144
   DoubleConversion: e22e0762848812a87afd67ffda3998d9ef29170c
145
+  FLAnimatedImage: 4a0b56255d9b05f18b6dd7ee06871be5d3b89e31
135 146
   Folly: 211775e49d8da0ca658aebc8eab89d642935755c
136 147
   glog: 1de0bb937dccdc981596d3b5825ebfb765017ded
137 148
   React: aa2040dbb6f317b95314968021bd2888816e03d5
138 149
   react-native-background-timer: 63dcbf37dbcf294b5c6c071afcdc661fa06a7594
139 150
   react-native-calendar-events: fe6fbc8ed337a7423c98f2c9012b25f20444de09
140
-  react-native-fetch-blob: 63394b1d7b0781547b3e4463b3195790177b1222
151
+  react-native-fast-image: cba3d9bf9c2cf8ddb643d887a686c53a5dd90a2c
141 152
   react-native-keep-awake: 0de4bd66de0c23178107dce0c2fcc3354b2a8e94
142 153
   react-native-locale-detector: d1b2c6fe5abb56e3a1efb6c2d6f308c05c4251f1
143 154
   react-native-webrtc: 31b6d3f1e3e2ce373aa43fd682b04367250f807d
144 155
   ReactNativePermissions: 9f2d9c45c98800795e6c2ed330e25d11a66a8169
145 156
   RNSound: b360b3862d3118ed1c74bb9825696b5957686ac4
146 157
   RNVectorIcons: c0dbfbf6068fefa240c37b0f71bd03b45dddac44
158
+  SDWebImage: 47e9b5b925cbce75946c23f0c42dd19464189af4
147 159
   yoga: a23273df0088bf7f2bb7e5d7b00044ea57a2a54a
148 160
 
149
-PODFILE CHECKSUM: e24d0131e937934fbe4d1f0b7ad5947ee0192f58
161
+PODFILE CHECKSUM: 1d5c8382f73d9540fac68d93b32e1d3b58d069ee
150 162
 
151 163
 COCOAPODS: 1.5.3

+ 5
- 33
package-lock.json 查看文件

@@ -5573,11 +5573,6 @@
5573 5573
         "randomfill": "^1.0.3"
5574 5574
       }
5575 5575
     },
5576
-    "crypto-js": {
5577
-      "version": "3.1.9-1",
5578
-      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz",
5579
-      "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg="
5580
-    },
5581 5576
     "css-color-list": {
5582 5577
       "version": "0.0.1",
5583 5578
       "resolved": "https://registry.npmjs.org/css-color-list/-/css-color-list-0.0.1.tgz",
@@ -12715,35 +12710,12 @@
12715 12710
         "jssha": "^2.2.0"
12716 12711
       }
12717 12712
     },
12718
-    "react-native-fetch-blob": {
12719
-      "version": "github:joltup/react-native-fetch-blob#1f9a1761aea4e37bd672bd0d233f3adf0e113a11",
12720
-      "from": "github:joltup/react-native-fetch-blob#1f9a1761aea4e37bd672bd0d233f3adf0e113a11",
12721
-      "requires": {
12722
-        "base-64": "0.1.0",
12723
-        "glob": "7.0.6"
12724
-      },
12725
-      "dependencies": {
12726
-        "glob": {
12727
-          "version": "7.0.6",
12728
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
12729
-          "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
12730
-          "requires": {
12731
-            "fs.realpath": "^1.0.0",
12732
-            "inflight": "^1.0.4",
12733
-            "inherits": "2",
12734
-            "minimatch": "^3.0.2",
12735
-            "once": "^1.3.0",
12736
-            "path-is-absolute": "^1.0.0"
12737
-          }
12738
-        }
12739
-      }
12740
-    },
12741
-    "react-native-img-cache": {
12742
-      "version": "1.5.2",
12743
-      "resolved": "https://registry.npmjs.org/react-native-img-cache/-/react-native-img-cache-1.5.2.tgz",
12744
-      "integrity": "sha1-6HG4MJk3t/mSbgmwFuTk5nWKOfo=",
12713
+    "react-native-fast-image": {
12714
+      "version": "4.0.14",
12715
+      "resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-4.0.14.tgz",
12716
+      "integrity": "sha512-MeRgL70JxoY/hn8ZRGBsDED9SGvTEeznneL//fWZyLaG0CM+w2CH4QXAMvADnIvu2RFd8WQWNii6c6VOpVe4Tg==",
12745 12717
       "requires": {
12746
-        "crypto-js": "^3.1.9-1"
12718
+        "prop-types": "^15.5.10"
12747 12719
       }
12748 12720
     },
12749 12721
     "react-native-immersive": {

+ 1
- 2
package.json 查看文件

@@ -60,8 +60,7 @@
60 60
     "react-native-background-timer": "2.0.0",
61 61
     "react-native-calendar-events": "github:jitsi/react-native-calendar-events#cad37355f36d17587d84af72b0095e8cc5fd3df9",
62 62
     "react-native-callstats": "3.52.0",
63
-    "react-native-fetch-blob": "github:joltup/react-native-fetch-blob#1f9a1761aea4e37bd672bd0d233f3adf0e113a11",
64
-    "react-native-img-cache": "1.5.2",
63
+    "react-native-fast-image": "4.0.14",
65 64
     "react-native-immersive": "1.1.0",
66 65
     "react-native-keep-awake": "2.0.6",
67 66
     "react-native-linear-gradient": "2.4.0",

+ 108
- 116
react/features/base/participants/components/Avatar.native.js 查看文件

@@ -1,10 +1,9 @@
1 1
 // @flow
2 2
 
3
-import React, { Component } from 'react';
3
+import React, { Component, Fragment } from 'react';
4 4
 import { Image, View } from 'react-native';
5
+import FastImage from 'react-native-fast-image';
5 6
 
6
-import { CachedImage, ImageCache } from '../../../mobile/image-cache';
7
-import { Platform } from '../../react';
8 7
 import { ColorPalette } from '../../styles';
9 8
 
10 9
 import styles from './styles';
@@ -46,7 +45,8 @@ type Props = {
46 45
  */
47 46
 type State = {
48 47
     backgroundColor: string,
49
-    source: number | { uri: string }
48
+    source: ?{ uri: string },
49
+    useDefaultAvatar: boolean
50 50
 };
51 51
 
52 52
 /**
@@ -68,6 +68,9 @@ export default class Avatar extends Component<Props, State> {
68 68
     constructor(props: Props) {
69 69
         super(props);
70 70
 
71
+        // Bind event handlers so they are only bound once per instance.
72
+        this._onAvatarLoaded = this._onAvatarLoaded.bind(this);
73
+
71 74
         // Fork (in Facebook/React speak) the prop uri because Image will
72 75
         // receive it through a source object. Additionally, other props may be
73 76
         // forked as well.
@@ -94,18 +97,8 @@ export default class Avatar extends Component<Props, State> {
94 97
         if (prevURI !== nextURI || assignState) {
95 98
             const nextState = {
96 99
                 backgroundColor: this._getBackgroundColor(nextProps),
97
-
98
-                /**
99
-                 * The source of the {@link Image} which is the actual
100
-                 * representation of this {@link Avatar}. The state
101
-                 * {@code source} was explicitly introduced in order to reduce
102
-                 * unnecessary renders.
103
-                 *
104
-                 * @type {{
105
-                 *     uri: string
106
-                 * }}
107
-                 */
108
-                source: _DEFAULT_SOURCE
100
+                source: undefined,
101
+                useDefaultAvatar: true
109 102
             };
110 103
 
111 104
             if (assignState) {
@@ -130,7 +123,14 @@ export default class Avatar extends Component<Props, State> {
130 123
             // an image retrieval action.
131 124
             if (nextURI && !nextURI.startsWith('#')) {
132 125
                 const nextSource = { uri: nextURI };
133
-                const observer = () => {
126
+
127
+                if (assignState) {
128
+                    // eslint-disable-next-line react/no-direct-mutation-state
129
+                    this.state = {
130
+                        ...this.state,
131
+                        source: nextSource
132
+                    };
133
+                } else {
134 134
                     this._unmounted || this.setState((prevState, props) => {
135 135
                         if (props.uri === nextURI
136 136
                                 && (!prevState.source
@@ -140,22 +140,6 @@ export default class Avatar extends Component<Props, State> {
140 140
 
141 141
                         return {};
142 142
                     });
143
-                };
144
-
145
-                // Wait for the source/URI to load.
146
-                if (ImageCache) {
147
-                    ImageCache.get().on(
148
-                        nextSource,
149
-                        observer,
150
-                        /* immutable */ true);
151
-                } else if (assignState) {
152
-                    // eslint-disable-next-line react/no-direct-mutation-state
153
-                    this.state = {
154
-                        ...this.state,
155
-                        source: nextSource
156
-                    };
157
-                } else {
158
-                    observer();
159 143
                 }
160 144
             }
161 145
         }
@@ -204,106 +188,114 @@ export default class Avatar extends Component<Props, State> {
204 188
     }
205 189
 
206 190
     /**
207
-     * Implements React's {@link Component#render()}.
191
+     * Helper which computes the style for the {@code Image} / {@code FastImage}
192
+     * component.
208 193
      *
209
-     * @inheritdoc
194
+     * @private
195
+     * @returns {Object}
210 196
      */
211
-    render() {
212
-        // Propagate all props of this Avatar but the ones consumed by this
213
-        // Avatar to the Image it renders.
214
-        const {
215
-            /* eslint-disable no-unused-vars */
216
-
217
-            // The following are forked in state:
218
-            uri: forked0,
197
+    _getImageStyle() {
198
+        const { size } = this.props;
219 199
 
220
-            /* eslint-enable no-unused-vars */
221
-
222
-            size,
223
-            ...props
224
-        } = this.props;
225
-        const {
226
-            backgroundColor,
227
-            source
228
-        } = this.state;
229
-
230
-        // Compute the base style
231
-        const borderRadius = size / 2;
232
-        const style = {
200
+        return {
233 201
             ...styles.avatar,
234
-
235
-            // XXX Workaround for Android: for radii < 80 the border radius
236
-            // doesn't work properly, but applying a radius twice as big seems
237
-            // to do the trick.
238
-            borderRadius:
239
-                Platform.OS === 'android' && borderRadius < 80
240
-                    ? size * 2
241
-                    : borderRadius,
202
+            borderRadius: size / 2,
242 203
             height: size,
243 204
             width: size
244 205
         };
206
+    }
245 207
 
246
-        // If we're rendering the _DEFAULT_SOURCE, then we want to do some
247
-        // additional fu like having automagical colors generated per
248
-        // participant, transparency to make the intermediate state while
249
-        // downloading the remote image a little less "in your face", etc.
250
-        let styleWithBackgroundColor;
251
-
252
-        if (source === _DEFAULT_SOURCE && backgroundColor) {
253
-            styleWithBackgroundColor = {
254
-                ...style,
255
-
256
-                backgroundColor,
257
-
258
-                // FIXME @lyubomir: Without the opacity bellow I feel like the
259
-                // avatar colors are too strong. Besides, we use opacity for the
260
-                // ToolbarButtons. That's where I copied the value from and we
261
-                // may want to think about "standardizing" the opacity in the
262
-                // app in a way similar to ColorPalette.
263
-                opacity: 0.1,
264
-                overflow: 'hidden'
265
-            };
266
-        }
208
+    _onAvatarLoaded: () => void;
267 209
 
268
-        // If we're styling with backgroundColor, we need to wrap the Image in a
269
-        // View because of a bug in React Native for Android:
210
+    /**
211
+     * Handler called when the remote image was loaded. When this happens we
212
+     * show that instead of the default locally generated one.
213
+     *
214
+     * @private
215
+     * @returns {void}
216
+     */
217
+    _onAvatarLoaded() {
218
+        this._unmounted || this.setState({ useDefaultAvatar: false });
219
+    }
220
+
221
+    /**
222
+     * Renders a default, locally generated avatar image.
223
+     *
224
+     * @private
225
+     * @returns {ReactElement}
226
+     */
227
+    _renderDefaultAvatar() {
228
+        // When using a local image, react-native-fastimage falls back to a
229
+        // regular Image, so we need to wrap it in a view to make it round.
270 230
         // https://github.com/facebook/react-native/issues/3198
271
-        let imageStyle;
272
-        let viewStyle;
273 231
 
274
-        if (styleWithBackgroundColor) {
275
-            if (Platform.OS === 'android') {
276
-                imageStyle = style;
277
-                viewStyle = styleWithBackgroundColor;
278
-            } else {
279
-                imageStyle = styleWithBackgroundColor;
280
-            }
281
-        } else {
282
-            imageStyle = style;
283
-        }
232
+        const { backgroundColor, useDefaultAvatar } = this.state;
233
+        const imageStyle = this._getImageStyle();
234
+        const viewStyle = {
235
+            ...imageStyle,
284 236
 
285
-        let element
286
-            = React.createElement(
237
+            backgroundColor,
238
+            display: useDefaultAvatar ? 'flex' : 'none',
239
+
240
+            // FIXME @lyubomir: Without the opacity bellow I feel like the
241
+            // avatar colors are too strong. Besides, we use opacity for the
242
+            // ToolbarButtons. That's where I copied the value from and we
243
+            // may want to think about "standardizing" the opacity in the
244
+            // app in a way similar to ColorPalette.
245
+            opacity: 0.1,
246
+            overflow: 'hidden'
247
+        };
287 248
 
288
-                // XXX CachedImage removed support for images which clearly do
289
-                // not need caching.
290
-                typeof source === 'number' ? Image : CachedImage,
291
-                {
292
-                    ...props,
249
+        return (
250
+            <View style = { viewStyle }>
251
+                <Image
293 252
 
294 253
                     // The Image adds a fade effect without asking, so lets
295 254
                     // explicitly disable it. More info here:
296 255
                     // https://github.com/facebook/react-native/issues/10194
297
-                    fadeDuration: 0,
298
-                    resizeMode: 'contain',
299
-                    source,
300
-                    style: imageStyle
301
-                });
302
-
303
-        if (viewStyle) {
304
-            element = React.createElement(View, { style: viewStyle }, element);
305
-        }
256
+                    fadeDuration = { 0 }
257
+                    resizeMode = 'contain'
258
+                    source = { _DEFAULT_SOURCE }
259
+                    style = { imageStyle } />
260
+            </View>
261
+        );
262
+    }
306 263
 
307
-        return element;
264
+    /**
265
+     * Renders an avatar using a remote image.
266
+     *
267
+     * @private
268
+     * @returns {ReactElement}
269
+     */
270
+    _renderAvatar() {
271
+        const { source, useDefaultAvatar } = this.state;
272
+        const style = {
273
+            ...this._getImageStyle(),
274
+            display: useDefaultAvatar ? 'none' : 'flex'
275
+        };
276
+
277
+        return (
278
+            <FastImage
279
+                onLoad = { this._onAvatarLoaded }
280
+                resizeMode = 'contain'
281
+                source = { source }
282
+                style = { style } />
283
+        );
284
+    }
285
+
286
+    /**
287
+     * Implements React's {@link Component#render()}.
288
+     *
289
+     * @inheritdoc
290
+     */
291
+    render() {
292
+        const { source, useDefaultAvatar } = this.state;
293
+
294
+        return (
295
+            <Fragment>
296
+                { source && this._renderAvatar() }
297
+                { useDefaultAvatar && this._renderDefaultAvatar() }
298
+            </Fragment>
299
+        );
308 300
     }
309 301
 }

+ 3
- 2
react/features/base/participants/components/ParticipantView.native.js 查看文件

@@ -2,6 +2,7 @@
2 2
 
3 3
 import React, { Component } from 'react';
4 4
 import { Text, View } from 'react-native';
5
+import FastImage from 'react-native-fast-image';
5 6
 import { connect } from 'react-redux';
6 7
 
7 8
 import { translate } from '../../i18n';
@@ -11,7 +12,6 @@ import {
11 12
     shouldRenderVideoTrack,
12 13
     VideoTrack
13 14
 } from '../../media';
14
-import { prefetch } from '../../../mobile/image-cache';
15 15
 import { Container, TintedView } from '../../react';
16 16
 import { TestHint } from '../../testing/components';
17 17
 import { getTrackByMediaTypeAndParticipant } from '../../tracks';
@@ -303,7 +303,8 @@ function _mapStateToProps(state, ownProps) {
303 303
 
304 304
         // ParticipantView knows before Avatar that an avatar URL will be used
305 305
         // so it's advisable to prefetch here.
306
-        avatar && prefetch({ uri: avatar });
306
+        avatar && !avatar.startsWith('#')
307
+            && FastImage.preload([ { uri: avatar } ]);
307 308
     }
308 309
 
309 310
     return {

+ 0
- 31
react/features/mobile/image-cache/functions.js 查看文件

@@ -1,31 +0,0 @@
1
-import { ImageCache } from './';
2
-
3
-/**
4
- * Notifies about the successful download of an {@code Image} source. The name
5
- * is inspired by {@code Image}. The downloaded {@code Image} source is not
6
- * available because (1) I do not know how to get it from {@link ImageCache} and
7
- * (2) we do not need it bellow. The function was explicitly introduced to cut
8
- * down on unnecessary {@code ImageCache} {@code observer} instances.
9
- *
10
- * @private
11
- * @returns {void}
12
- */
13
-function _onLoad() {
14
-    // ImageCache requires an observer; otherwise, we do not need it because we
15
-    // merely want to initiate the download and do not care what happens with it
16
-    // afterwards.
17
-}
18
-
19
-/**
20
- * Initiates the retrieval of a specific {@code Image} source (if it has not
21
- * been initiated already). Due to limitations of {@link ImageCache}, the source
22
- * may have at most one {@code uri}. The name is inspired by {@code Image}.
23
- *
24
- * @param {Object} source - The {@code Image} source with preferably exactly
25
- * one {@code uri}.
26
- * @public
27
- * @returns {void}
28
- */
29
-export function prefetch(source) {
30
-    ImageCache && ImageCache.get().on(source, _onLoad, /* immutable */ true);
31
-}

+ 0
- 4
react/features/mobile/image-cache/index.js 查看文件

@@ -1,4 +0,0 @@
1
-export * from './functions';
2
-export * from './react-native-img-cache';
3
-
4
-import './middleware';

+ 0
- 91
react/features/mobile/image-cache/middleware.js 查看文件

@@ -1,91 +0,0 @@
1
-/* @flow */
2
-
3
-import { APP_WILL_MOUNT } from '../../base/app';
4
-import {
5
-    getAvatarURL,
6
-    getLocalParticipant,
7
-    getParticipantById,
8
-    PARTICIPANT_ID_CHANGED,
9
-    PARTICIPANT_JOINED,
10
-    PARTICIPANT_UPDATED
11
-} from '../../base/participants';
12
-import { MiddlewareRegistry } from '../../base/redux';
13
-
14
-import { ImageCache, prefetch } from './';
15
-
16
-/**
17
- * The indicator which determines whether avatar URLs are to be prefetched in
18
- * the middleware here. Unless/until the implementation starts observing the
19
- * redux store instead of the respective redux actions, the value should very
20
- * likely be {@code false} because the middleware here is pretty much the last
21
- * to get a chance to figure out that an avatar URL may be used. Besides, it is
22
- * somewhat uninformed to download just about anything that may eventually be
23
- * used or not.
24
- *
25
- * @private
26
- * @type {boolean}
27
- */
28
-const _PREFETCH_AVATAR_URLS = false;
29
-
30
-/**
31
- * Middleware which captures app startup and conference actions in order to
32
- * clear the image cache.
33
- *
34
- * @returns {Function}
35
- */
36
-MiddlewareRegistry.register(({ getState }) => next => action => {
37
-    switch (action.type) {
38
-    case APP_WILL_MOUNT:
39
-        // XXX CONFERENCE_FAILED/LEFT are no longer used here because they
40
-        // are tricky to get right as detectors of the moments in time at which
41
-        // CachedImage is not used. Anyway, if ImageCache is to be cleared from
42
-        // time to time, SET_LOCATION_URL is a much easier detector of such
43
-        // opportune times. Fixes at least one 100%-reproducible case of
44
-        // "TypeError: Cannot read property handlers of undefined." Anyway, in
45
-        // order to reduce the re-downloading of the same avatars, eventually we
46
-        // decided to not clear during the runtime of the app (other that at the
47
-        // beginning that is).
48
-        ImageCache && ImageCache.get().clear();
49
-        break;
50
-
51
-    case PARTICIPANT_ID_CHANGED:
52
-    case PARTICIPANT_JOINED:
53
-    case PARTICIPANT_UPDATED: {
54
-        if (!_PREFETCH_AVATAR_URLS) {
55
-            break;
56
-        }
57
-
58
-        const result = next(action);
59
-
60
-        // Initiate the downloads of participants' avatars as soon as possible.
61
-
62
-        // 1. Figure out the participant (instance).
63
-        let { participant } = action;
64
-
65
-        if (participant) {
66
-            if (participant.id) {
67
-                participant = getParticipantById(getState, participant.id);
68
-            } else if (participant.local) {
69
-                participant = getLocalParticipant(getState);
70
-            } else {
71
-                participant = undefined;
72
-            }
73
-        } else if (action.oldValue && action.newValue) {
74
-            participant = getParticipantById(getState, action.newValue);
75
-        }
76
-        if (participant) {
77
-            // 2. Get the participant's avatar URL.
78
-            const uri = getAvatarURL(participant);
79
-
80
-            if (uri) {
81
-                // 3. Initiate the download of the participant's avatar.
82
-                prefetch({ uri });
83
-            }
84
-        }
85
-
86
-        return result;
87
-    }
88
-    }
89
-
90
-    return next(action);
91
-});

+ 0
- 1
react/features/mobile/image-cache/react-native-img-cache.android.js 查看文件

@@ -1 +0,0 @@
1
-export * from './react-native-img-cache.yes';

+ 0
- 1
react/features/mobile/image-cache/react-native-img-cache.ios.js 查看文件

@@ -1 +0,0 @@
1
-export * from './react-native-img-cache.yes';

+ 0
- 16
react/features/mobile/image-cache/react-native-img-cache.no.js 查看文件

@@ -1,16 +0,0 @@
1
-// XXX The third-party react-native modules react-native-fetch-blob utilizes the
2
-// same HTTP library as react-native i.e. okhttp. Unfortunately, that means that
3
-// the versions of okhttp on which react-native and react-native-fetch-blob
4
-// depend may have incompatible APIs. Such an incompatibility will be made
5
-// apparent at compile time and the developer doing the compilation may choose
6
-// to not compile react-native-fetch-blob's source code.
7
-
8
-// XXX The choice between the use of react-native-img-cache could've been done
9
-// at runtime based on whether NativeModules.RNFetchBlob is defined if only
10
-// react-native-fetch-blob would've completely protected itself. At the time of
11
-// this writing its source code appears to be attempting to protect itself from
12
-// missing native binaries but that protection is incomplete and there's a
13
-// TypeError.
14
-
15
-import { Image } from 'react-native';
16
-export { Image as CachedImage, undefined as ImageCache };

+ 0
- 1
react/features/mobile/image-cache/react-native-img-cache.yes.js 查看文件

@@ -1 +0,0 @@
1
-export { CachedImage, ImageCache } from 'react-native-img-cache';

正在加载...
取消
保存