Преглед изворни кода

[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.
j8
Saúl Ibarra Corretgé пре 7 година
родитељ
комит
27021ea271

+ 6
- 0
android/app/proguard-rules.pro Прегледај датотеку

68
 -dontwarn java.nio.file.*
68
 -dontwarn java.nio.file.*
69
 -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
69
 -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
70
 -dontwarn okio.**
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
     compile 'com.facebook.react:react-native:+'
25
     compile 'com.facebook.react:react-native:+'
26
 
26
 
27
     compile project(':react-native-background-timer')
27
     compile project(':react-native-background-timer')
28
-    compile project(':react-native-fetch-blob')
28
+    compile project(':react-native-fast-image')
29
     compile project(':react-native-immersive')
29
     compile project(':react-native-immersive')
30
     compile project(':react-native-keep-awake')
30
     compile project(':react-native-keep-awake')
31
     compile project(':react-native-linear-gradient')
31
     compile project(':react-native-linear-gradient')

+ 1
- 1
android/sdk/src/main/java/org/jitsi/meet/sdk/ReactInstanceManagerHolder.java Прегледај датотеку

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

+ 2
- 2
android/settings.gradle Прегледај датотеку

3
 include ':app', ':sdk'
3
 include ':app', ':sdk'
4
 include ':react-native-background-timer'
4
 include ':react-native-background-timer'
5
 project(':react-native-background-timer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-timer/android')
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
 include ':react-native-immersive'
8
 include ':react-native-immersive'
9
 project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
9
 project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
10
 include ':react-native-keep-awake'
10
 include ':react-native-keep-awake'

+ 2
- 2
ios/Podfile Прегледај датотеку

28
 
28
 
29
   pod 'react-native-background-timer',
29
   pod 'react-native-background-timer',
30
     :path => '../node_modules/react-native-background-timer'
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
   pod 'react-native-keep-awake',
33
   pod 'react-native-keep-awake',
34
     :path => '../node_modules/react-native-keep-awake'
34
     :path => '../node_modules/react-native-keep-awake'
35
   pod 'react-native-locale-detector',
35
   pod 'react-native-locale-detector',

+ 19
- 7
ios/Podfile.lock Прегледај датотеку

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

+ 5
- 33
package-lock.json Прегледај датотеку

5573
         "randomfill": "^1.0.3"
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
     "css-color-list": {
5576
     "css-color-list": {
5582
       "version": "0.0.1",
5577
       "version": "0.0.1",
5583
       "resolved": "https://registry.npmjs.org/css-color-list/-/css-color-list-0.0.1.tgz",
5578
       "resolved": "https://registry.npmjs.org/css-color-list/-/css-color-list-0.0.1.tgz",
12715
         "jssha": "^2.2.0"
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
       "requires": {
12717
       "requires": {
12746
-        "crypto-js": "^3.1.9-1"
12718
+        "prop-types": "^15.5.10"
12747
       }
12719
       }
12748
     },
12720
     },
12749
     "react-native-immersive": {
12721
     "react-native-immersive": {

+ 1
- 2
package.json Прегледај датотеку

60
     "react-native-background-timer": "2.0.0",
60
     "react-native-background-timer": "2.0.0",
61
     "react-native-calendar-events": "github:jitsi/react-native-calendar-events#cad37355f36d17587d84af72b0095e8cc5fd3df9",
61
     "react-native-calendar-events": "github:jitsi/react-native-calendar-events#cad37355f36d17587d84af72b0095e8cc5fd3df9",
62
     "react-native-callstats": "3.52.0",
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
     "react-native-immersive": "1.1.0",
64
     "react-native-immersive": "1.1.0",
66
     "react-native-keep-awake": "2.0.6",
65
     "react-native-keep-awake": "2.0.6",
67
     "react-native-linear-gradient": "2.4.0",
66
     "react-native-linear-gradient": "2.4.0",

+ 108
- 116
react/features/base/participants/components/Avatar.native.js Прегледај датотеку

1
 // @flow
1
 // @flow
2
 
2
 
3
-import React, { Component } from 'react';
3
+import React, { Component, Fragment } from 'react';
4
 import { Image, View } from 'react-native';
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
 import { ColorPalette } from '../../styles';
7
 import { ColorPalette } from '../../styles';
9
 
8
 
10
 import styles from './styles';
9
 import styles from './styles';
46
  */
45
  */
47
 type State = {
46
 type State = {
48
     backgroundColor: string,
47
     backgroundColor: string,
49
-    source: number | { uri: string }
48
+    source: ?{ uri: string },
49
+    useDefaultAvatar: boolean
50
 };
50
 };
51
 
51
 
52
 /**
52
 /**
68
     constructor(props: Props) {
68
     constructor(props: Props) {
69
         super(props);
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
         // Fork (in Facebook/React speak) the prop uri because Image will
74
         // Fork (in Facebook/React speak) the prop uri because Image will
72
         // receive it through a source object. Additionally, other props may be
75
         // receive it through a source object. Additionally, other props may be
73
         // forked as well.
76
         // forked as well.
94
         if (prevURI !== nextURI || assignState) {
97
         if (prevURI !== nextURI || assignState) {
95
             const nextState = {
98
             const nextState = {
96
                 backgroundColor: this._getBackgroundColor(nextProps),
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
             if (assignState) {
104
             if (assignState) {
130
             // an image retrieval action.
123
             // an image retrieval action.
131
             if (nextURI && !nextURI.startsWith('#')) {
124
             if (nextURI && !nextURI.startsWith('#')) {
132
                 const nextSource = { uri: nextURI };
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
                     this._unmounted || this.setState((prevState, props) => {
134
                     this._unmounted || this.setState((prevState, props) => {
135
                         if (props.uri === nextURI
135
                         if (props.uri === nextURI
136
                                 && (!prevState.source
136
                                 && (!prevState.source
140
 
140
 
141
                         return {};
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
     }
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
             ...styles.avatar,
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
             height: size,
203
             height: size,
243
             width: size
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
         // https://github.com/facebook/react-native/issues/3198
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
                     // The Image adds a fade effect without asking, so lets
253
                     // The Image adds a fade effect without asking, so lets
295
                     // explicitly disable it. More info here:
254
                     // explicitly disable it. More info here:
296
                     // https://github.com/facebook/react-native/issues/10194
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
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
 import { Text, View } from 'react-native';
4
 import { Text, View } from 'react-native';
5
+import FastImage from 'react-native-fast-image';
5
 import { connect } from 'react-redux';
6
 import { connect } from 'react-redux';
6
 
7
 
7
 import { translate } from '../../i18n';
8
 import { translate } from '../../i18n';
11
     shouldRenderVideoTrack,
12
     shouldRenderVideoTrack,
12
     VideoTrack
13
     VideoTrack
13
 } from '../../media';
14
 } from '../../media';
14
-import { prefetch } from '../../../mobile/image-cache';
15
 import { Container, TintedView } from '../../react';
15
 import { Container, TintedView } from '../../react';
16
 import { TestHint } from '../../testing/components';
16
 import { TestHint } from '../../testing/components';
17
 import { getTrackByMediaTypeAndParticipant } from '../../tracks';
17
 import { getTrackByMediaTypeAndParticipant } from '../../tracks';
303
 
303
 
304
         // ParticipantView knows before Avatar that an avatar URL will be used
304
         // ParticipantView knows before Avatar that an avatar URL will be used
305
         // so it's advisable to prefetch here.
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
     return {
310
     return {

+ 0
- 31
react/features/mobile/image-cache/functions.js Прегледај датотеку

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
-export * from './functions';
2
-export * from './react-native-img-cache';
3
-
4
-import './middleware';

+ 0
- 91
react/features/mobile/image-cache/middleware.js Прегледај датотеку

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
-export * from './react-native-img-cache.yes';

+ 0
- 1
react/features/mobile/image-cache/react-native-img-cache.ios.js Прегледај датотеку

1
-export * from './react-native-img-cache.yes';

+ 0
- 16
react/features/mobile/image-cache/react-native-img-cache.no.js Прегледај датотеку

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
-export { CachedImage, ImageCache } from 'react-native-img-cache';

Loading…
Откажи
Сачувај