From 33baf35de6169bbc05c7f6c661150bfef86d804c Mon Sep 17 00:00:00 2001
From: Diego Mello <diegolmello@gmail.com>
Date: Mon, 7 May 2018 17:41:36 -0300
Subject: [PATCH] Better image cache component (#292)

* react-native-img-cache removed

* Improve list render

* Support <http://link/Text> inside markdown
---
 __tests__/__snapshots__/RoomItem.js.snap      | 132 +++-
 .../__snapshots__/Storyshots.test.js.snap     | 660 +++++++++++++++++-
 android/app/build.gradle                      |   6 +-
 .../reactnative}/CustomTabsAndroid.java       |   0
 .../reactnative}/CustomTabsHelper.java        |   0
 .../rocketchat/reactnative}/MainActivity.java |   0
 .../reactnative}/MainApplication.java         |   4 +-
 .../reactnative}/RocketChatNativePackage.java |   0
 android/build.gradle                          |   3 +
 android/settings.gradle                       |   2 +
 app/containers/Avatar.js                      |  21 +-
 app/containers/EmojiPicker/CustomEmoji.js     |   4 +-
 app/containers/message/Image.js               |   8 +-
 app/containers/message/Markdown.js            |  10 +-
 app/containers/message/PhotoModal.js          |   4 +-
 app/containers/message/Reply.js               |   9 +-
 app/views/Photo.js                            |  36 -
 app/views/RoomView/ListView.js                |  13 +-
 app/views/RoomsListView/Header/index.js       |   4 +-
 ios/RocketChatRN.xcodeproj/project.pbxproj    |  18 +-
 package-lock.json                             |  16 +-
 package.json                                  |   2 +-
 22 files changed, 854 insertions(+), 98 deletions(-)
 rename android/app/src/main/java/{com/rocketchatrn => chat/rocketchat/reactnative}/CustomTabsAndroid.java (100%)
 rename android/app/src/main/java/{com/rocketchatrn => chat/rocketchat/reactnative}/CustomTabsHelper.java (100%)
 rename android/app/src/main/java/{com/rocketchatrn => chat/rocketchat/reactnative}/MainActivity.java (100%)
 rename android/app/src/main/java/{com/rocketchatrn => chat/rocketchat/reactnative}/MainApplication.java (94%)
 rename android/app/src/main/java/{com/rocketchatrn => chat/rocketchat/reactnative}/RocketChatNativePackage.java (100%)
 delete mode 100644 app/views/Photo.js

diff --git a/__tests__/__snapshots__/RoomItem.js.snap b/__tests__/__snapshots__/RoomItem.js.snap
index 7322a46b6..9d388e323 100644
--- a/__tests__/__snapshots__/RoomItem.js.snap
+++ b/__tests__/__snapshots__/RoomItem.js.snap
@@ -546,7 +546,49 @@ exports[`render unread +999 1`] = `
         >
           NA
         </Text>
-        
+        <View
+          style={
+            Array [
+              Array [
+                Object {
+                  "position": "absolute",
+                },
+                Object {
+                  "borderRadius": 2,
+                  "height": 46,
+                  "width": 46,
+                },
+              ],
+              Object {
+                "overflow": "hidden",
+              },
+            ]
+          }
+        >
+          <FastImageView
+            onFastImageError={undefined}
+            onFastImageLoad={undefined}
+            onFastImageLoadEnd={undefined}
+            onFastImageLoadStart={undefined}
+            onFastImageProgress={undefined}
+            resizeMode="cover"
+            source={
+              Object {
+                "priority": "high",
+                "uri": "/avatar/name",
+              }
+            }
+            style={
+              Object {
+                "bottom": 0,
+                "left": 0,
+                "position": "absolute",
+                "right": 0,
+                "top": 0,
+              }
+            }
+          />
+        </View>
         <View
           style={
             Array [
@@ -741,7 +783,49 @@ exports[`render unread 1`] = `
         >
           NA
         </Text>
-        
+        <View
+          style={
+            Array [
+              Array [
+                Object {
+                  "position": "absolute",
+                },
+                Object {
+                  "borderRadius": 2,
+                  "height": 46,
+                  "width": 46,
+                },
+              ],
+              Object {
+                "overflow": "hidden",
+              },
+            ]
+          }
+        >
+          <FastImageView
+            onFastImageError={undefined}
+            onFastImageLoad={undefined}
+            onFastImageLoadEnd={undefined}
+            onFastImageLoadStart={undefined}
+            onFastImageProgress={undefined}
+            resizeMode="cover"
+            source={
+              Object {
+                "priority": "high",
+                "uri": "/avatar/name",
+              }
+            }
+            style={
+              Object {
+                "bottom": 0,
+                "left": 0,
+                "position": "absolute",
+                "right": 0,
+                "top": 0,
+              }
+            }
+          />
+        </View>
         <View
           style={
             Array [
@@ -936,7 +1020,49 @@ exports[`renders correctly 1`] = `
         >
           NA
         </Text>
-        
+        <View
+          style={
+            Array [
+              Array [
+                Object {
+                  "position": "absolute",
+                },
+                Object {
+                  "borderRadius": 2,
+                  "height": 46,
+                  "width": 46,
+                },
+              ],
+              Object {
+                "overflow": "hidden",
+              },
+            ]
+          }
+        >
+          <FastImageView
+            onFastImageError={undefined}
+            onFastImageLoad={undefined}
+            onFastImageLoadEnd={undefined}
+            onFastImageLoadStart={undefined}
+            onFastImageProgress={undefined}
+            resizeMode="cover"
+            source={
+              Object {
+                "priority": "high",
+                "uri": "/avatar/name",
+              }
+            }
+            style={
+              Object {
+                "bottom": 0,
+                "left": 0,
+                "position": "absolute",
+                "right": 0,
+                "top": 0,
+              }
+            }
+          />
+        </View>
         <View
           style={
             Array [
diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap
index a735dc7f5..9310dc94c 100644
--- a/__tests__/__snapshots__/Storyshots.test.js.snap
+++ b/__tests__/__snapshots__/Storyshots.test.js.snap
@@ -37,7 +37,49 @@ exports[`Storyshots Avatar avatar 1`] = `
       >
         TE
       </Text>
-      
+      <View
+        style={
+          Array [
+            Array [
+              Object {
+                "position": "absolute",
+              },
+              Object {
+                "borderRadius": 2,
+                "height": 25,
+                "width": 25,
+              },
+            ],
+            Object {
+              "overflow": "hidden",
+            },
+          ]
+        }
+      >
+        <FastImageView
+          onFastImageError={undefined}
+          onFastImageLoad={undefined}
+          onFastImageLoadEnd={undefined}
+          onFastImageLoadStart={undefined}
+          onFastImageProgress={undefined}
+          resizeMode="cover"
+          source={
+            Object {
+              "priority": "high",
+              "uri": "/avatar/test",
+            }
+          }
+          style={
+            Object {
+              "bottom": 0,
+              "left": 0,
+              "position": "absolute",
+              "right": 0,
+              "top": 0,
+            }
+          }
+        />
+      </View>
     </View>
     <View
       style={
@@ -73,7 +115,49 @@ exports[`Storyshots Avatar avatar 1`] = `
       >
         AA
       </Text>
-      
+      <View
+        style={
+          Array [
+            Array [
+              Object {
+                "position": "absolute",
+              },
+              Object {
+                "borderRadius": 2,
+                "height": 40,
+                "width": 40,
+              },
+            ],
+            Object {
+              "overflow": "hidden",
+            },
+          ]
+        }
+      >
+        <FastImageView
+          onFastImageError={undefined}
+          onFastImageLoad={undefined}
+          onFastImageLoadEnd={undefined}
+          onFastImageLoadStart={undefined}
+          onFastImageProgress={undefined}
+          resizeMode="cover"
+          source={
+            Object {
+              "priority": "high",
+              "uri": "/avatar/aa",
+            }
+          }
+          style={
+            Object {
+              "bottom": 0,
+              "left": 0,
+              "position": "absolute",
+              "right": 0,
+              "top": 0,
+            }
+          }
+        />
+      </View>
     </View>
     <View
       style={
@@ -109,7 +193,49 @@ exports[`Storyshots Avatar avatar 1`] = `
       >
         BB
       </Text>
-      
+      <View
+        style={
+          Array [
+            Array [
+              Object {
+                "position": "absolute",
+              },
+              Object {
+                "borderRadius": 2,
+                "height": 30,
+                "width": 30,
+              },
+            ],
+            Object {
+              "overflow": "hidden",
+            },
+          ]
+        }
+      >
+        <FastImageView
+          onFastImageError={undefined}
+          onFastImageLoad={undefined}
+          onFastImageLoadEnd={undefined}
+          onFastImageLoadStart={undefined}
+          onFastImageProgress={undefined}
+          resizeMode="cover"
+          source={
+            Object {
+              "priority": "high",
+              "uri": "/avatar/bb",
+            }
+          }
+          style={
+            Object {
+              "bottom": 0,
+              "left": 0,
+              "position": "absolute",
+              "right": 0,
+              "top": 0,
+            }
+          }
+        />
+      </View>
     </View>
     <View
       style={
@@ -145,7 +271,49 @@ exports[`Storyshots Avatar avatar 1`] = `
       >
         TE
       </Text>
-      
+      <View
+        style={
+          Array [
+            Array [
+              Object {
+                "position": "absolute",
+              },
+              Object {
+                "borderRadius": 2,
+                "height": 25,
+                "width": 25,
+              },
+            ],
+            Object {
+              "overflow": "hidden",
+            },
+          ]
+        }
+      >
+        <FastImageView
+          onFastImageError={undefined}
+          onFastImageLoad={undefined}
+          onFastImageLoadEnd={undefined}
+          onFastImageLoadStart={undefined}
+          onFastImageProgress={undefined}
+          resizeMode="cover"
+          source={
+            Object {
+              "priority": "high",
+              "uri": "/avatar/test",
+            }
+          }
+          style={
+            Object {
+              "bottom": 0,
+              "left": 0,
+              "position": "absolute",
+              "right": 0,
+              "top": 0,
+            }
+          }
+        />
+      </View>
     </View>
   </View>
 </RCTScrollView>
@@ -223,7 +391,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             RC
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/rocket.cat",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -390,7 +600,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             RC
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/rocket.cat",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -561,7 +813,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             RC
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/rocket.cat",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -751,7 +1045,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             LC
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -945,7 +1281,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             LC
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -1135,7 +1513,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             LC
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -1325,7 +1745,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             LC
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -1515,7 +1977,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             LC
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -1705,7 +2209,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             W
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/W",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -1872,7 +2418,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             WW
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/WW",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
@@ -2039,7 +2627,49 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
           >
             
           </Text>
-          
+          <View
+            style={
+              Array [
+                Array [
+                  Object {
+                    "position": "absolute",
+                  },
+                  Object {
+                    "borderRadius": 2,
+                    "height": 46,
+                    "width": 46,
+                  },
+                ],
+                Object {
+                  "overflow": "hidden",
+                },
+              ]
+            }
+          >
+            <FastImageView
+              onFastImageError={undefined}
+              onFastImageLoad={undefined}
+              onFastImageLoadEnd={undefined}
+              onFastImageLoadStart={undefined}
+              onFastImageProgress={undefined}
+              resizeMode="cover"
+              source={
+                Object {
+                  "priority": "high",
+                  "uri": "/avatar/",
+                }
+              }
+              style={
+                Object {
+                  "bottom": 0,
+                  "left": 0,
+                  "position": "absolute",
+                  "right": 0,
+                  "top": 0,
+                }
+              }
+            />
+          </View>
           <View
             style={
               Array [
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 793040f61..cbef9d709 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -90,8 +90,8 @@ def enableSeparateBuildPerCPUArchitecture = false
 def enableProguardInReleaseBuilds = false
 
 android {
-    compileSdkVersion 25
-    buildToolsVersion "25.0.1"
+    compileSdkVersion 27
+    buildToolsVersion "27.0.1"
 
     defaultConfig {
         applicationId "chat.rocket.reactnative"
@@ -184,9 +184,11 @@ dependencies {
     compile project(':react-native-fetch-blob')
     compile project(':react-native-zeroconf')
     compile project(':react-native-toast')
+    compile project(':react-native-fast-image')
     compile project(':realm')
     compile fileTree(dir: "libs", include: ["*.jar"])
     compile "com.android.support:appcompat-v7:23.0.1"
+    compile "com.android.support:support-v4:27.1.0"
     compile 'com.android.support:customtabs:23.0.1'
     compile "com.facebook.react:react-native:+"  // From node_modules
     compile 'com.facebook.fresco:fresco:1.7.1'
diff --git a/android/app/src/main/java/com/rocketchatrn/CustomTabsAndroid.java b/android/app/src/main/java/chat/rocketchat/reactnative/CustomTabsAndroid.java
similarity index 100%
rename from android/app/src/main/java/com/rocketchatrn/CustomTabsAndroid.java
rename to android/app/src/main/java/chat/rocketchat/reactnative/CustomTabsAndroid.java
diff --git a/android/app/src/main/java/com/rocketchatrn/CustomTabsHelper.java b/android/app/src/main/java/chat/rocketchat/reactnative/CustomTabsHelper.java
similarity index 100%
rename from android/app/src/main/java/com/rocketchatrn/CustomTabsHelper.java
rename to android/app/src/main/java/chat/rocketchat/reactnative/CustomTabsHelper.java
diff --git a/android/app/src/main/java/com/rocketchatrn/MainActivity.java b/android/app/src/main/java/chat/rocketchat/reactnative/MainActivity.java
similarity index 100%
rename from android/app/src/main/java/com/rocketchatrn/MainActivity.java
rename to android/app/src/main/java/chat/rocketchat/reactnative/MainActivity.java
diff --git a/android/app/src/main/java/com/rocketchatrn/MainApplication.java b/android/app/src/main/java/chat/rocketchat/reactnative/MainApplication.java
similarity index 94%
rename from android/app/src/main/java/com/rocketchatrn/MainApplication.java
rename to android/app/src/main/java/chat/rocketchat/reactnative/MainApplication.java
index 689cee99f..7883ed1b2 100644
--- a/android/app/src/main/java/com/rocketchatrn/MainApplication.java
+++ b/android/app/src/main/java/chat/rocketchat/reactnative/MainApplication.java
@@ -19,6 +19,7 @@ import com.remobile.toast.RCTToastPackage;
 import com.wix.reactnativekeyboardinput.KeyboardInputPackage;
 import com.rnim.rn.audio.ReactNativeAudioPackage;
 import com.smixx.fabric.FabricPackage;
+import com.dylanvann.fastimage.FastImageViewPackage;
 
 import java.util.Arrays;
 import java.util.List;
@@ -49,7 +50,8 @@ public class MainApplication extends Application implements ReactApplication {
         new ReactNativeAudioPackage(),
         new KeyboardInputPackage(MainApplication.this),
         new RocketChatNativePackage(),
-        new FabricPackage()
+        new FabricPackage(),
+        new FastImageViewPackage()
       );
     }
   };
diff --git a/android/app/src/main/java/com/rocketchatrn/RocketChatNativePackage.java b/android/app/src/main/java/chat/rocketchat/reactnative/RocketChatNativePackage.java
similarity index 100%
rename from android/app/src/main/java/com/rocketchatrn/RocketChatNativePackage.java
rename to android/app/src/main/java/chat/rocketchat/reactnative/RocketChatNativePackage.java
diff --git a/android/build.gradle b/android/build.gradle
index eed9972b5..d29444e96 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -16,6 +16,9 @@ allprojects {
     repositories {
         mavenLocal()
         jcenter()
+        maven {
+            url 'https://maven.google.com'
+        }
         maven {
             // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
             url "$rootDir/../node_modules/react-native/android"
diff --git a/android/settings.gradle b/android/settings.gradle
index bba1bd27f..1259f2ba9 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,4 +1,6 @@
 rootProject.name = 'RocketChatRN'
+include ':react-native-fast-image'
+project(':react-native-fast-image').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fast-image/android')
 include ':react-native-fabric'
 project(':react-native-fabric').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fabric/android')
 include ':react-native-audio'
diff --git a/app/containers/Avatar.js b/app/containers/Avatar.js
index 6842218e2..7d1b40053 100644
--- a/app/containers/Avatar.js
+++ b/app/containers/Avatar.js
@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { connect } from 'react-redux';
 import { StyleSheet, Text, View, ViewPropTypes } from 'react-native';
-import { CachedImage } from 'react-native-img-cache';
+import FastImage from 'react-native-fast-image';
 import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
 import avatarInitialsAndColor from '../utils/avatarInitialsAndColor';
 
@@ -34,6 +34,7 @@ export default class Avatar extends React.PureComponent {
 		type: PropTypes.string,
 		children: PropTypes.object
 	};
+	state = { showInitials: true };
 	render() {
 		const {
 			text = '', size = 25, baseUrl, borderRadius = 2, style, avatar, type = 'd'
@@ -59,15 +60,25 @@ export default class Avatar extends React.PureComponent {
 
 		if (type === 'd') {
 			const uri = avatar || `${ baseUrl }/avatar/${ text }`;
-			const image = (avatar || baseUrl) && (
-				<CachedImage
+			const image = uri && (
+				<FastImage
 					style={[styles.avatar, avatarStyle]}
-					source={{ uri }}
+					source={{
+						uri,
+						priority: FastImage.priority.high
+					}}
 				/>
 			);
 			return (
 				<View style={[styles.iconContainer, iconContainerStyle, style]}>
-					<Text style={[styles.avatarInitials, avatarInitialsStyle]} allowFontScaling={false}>{initials}</Text>
+					{this.state.showInitials &&
+						<Text
+							style={[styles.avatarInitials, avatarInitialsStyle]}
+							allowFontScaling={false}
+						>
+							{initials}
+						</Text>
+					}
 					{image}
 					{this.props.children}
 				</View>);
diff --git a/app/containers/EmojiPicker/CustomEmoji.js b/app/containers/EmojiPicker/CustomEmoji.js
index 8215f0ea6..2f10cb771 100644
--- a/app/containers/EmojiPicker/CustomEmoji.js
+++ b/app/containers/EmojiPicker/CustomEmoji.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import { ViewPropTypes } from 'react-native';
 import PropTypes from 'prop-types';
-import { CachedImage } from 'react-native-img-cache';
+import FastImage from 'react-native-fast-image';
 import { connect } from 'react-redux';
 
 @connect(state => ({
@@ -19,7 +19,7 @@ export default class CustomEmoji extends React.Component {
 	render() {
 		const { baseUrl, emoji, style } = this.props;
 		return (
-			<CachedImage
+			<FastImage
 				style={style}
 				source={{ uri: `${ baseUrl }/emoji-custom/${ encodeURIComponent(emoji.content || emoji.name) }.${ emoji.extension }` }}
 			/>
diff --git a/app/containers/message/Image.js b/app/containers/message/Image.js
index 2bf78435c..7724edbef 100644
--- a/app/containers/message/Image.js
+++ b/app/containers/message/Image.js
@@ -1,6 +1,6 @@
 import PropTypes from 'prop-types';
 import React from 'react';
-import { CachedImage } from 'react-native-img-cache';
+import FastImage from 'react-native-fast-image';
 import { TouchableOpacity, StyleSheet } from 'react-native';
 import { connect } from 'react-redux';
 import PhotoModal from './PhotoModal';
@@ -13,8 +13,8 @@ const styles = StyleSheet.create({
 	},
 	image: {
 		width: 320,
-		height: 200,
-		resizeMode: 'cover'
+		height: 200
+		// resizeMode: 'cover'
 	},
 	labelContainer: {
 		alignItems: 'flex-start'
@@ -56,7 +56,7 @@ export default class extends React.PureComponent {
 					onPress={() => this._onPressButton()}
 					style={styles.button}
 				>
-					<CachedImage
+					<FastImage
 						style={styles.image}
 						source={{ uri: encodeURI(img) }}
 					/>
diff --git a/app/containers/message/Markdown.js b/app/containers/message/Markdown.js
index 3c88b09d5..1dc11b8ff 100644
--- a/app/containers/message/Markdown.js
+++ b/app/containers/message/Markdown.js
@@ -94,6 +94,13 @@ const defaultRules = {
 
 const codeStyle = StyleSheet.flatten(styles.codeStyle);
 
+// Support <http://link|Text>
+const formatText = text =>
+	text.replace(
+		new RegExp('(?:<|<)((?:https|http):\\/\\/[^\\|]+)\\|(.+?)(?=>|>)(?:>|>)', 'gm'),
+		(match, url, title) => `[${ title }](${ url })`
+	);
+
 @connect(state => ({
 	customEmojis: state.customEmojis
 }))
@@ -108,7 +115,8 @@ export default class Markdown extends React.Component {
 		if (!msg) {
 			return null;
 		}
-		const m = emojify(msg, { output: 'unicode' });
+		let m = formatText(msg);
+		m = emojify(m, { output: 'unicode' });
 
 		const s = StyleSheet.flatten(style);
 		return (
diff --git a/app/containers/message/PhotoModal.js b/app/containers/message/PhotoModal.js
index 7d378794e..0bb21888e 100644
--- a/app/containers/message/PhotoModal.js
+++ b/app/containers/message/PhotoModal.js
@@ -1,6 +1,6 @@
 import React from 'react';
 import { ScrollView, View, Text, TouchableWithoutFeedback } from 'react-native';
-import { CachedImage } from 'react-native-img-cache';
+import FastImage from 'react-native-fast-image';
 import PropTypes from 'prop-types';
 import Modal from 'react-native-modal';
 
@@ -50,7 +50,7 @@ export default class PhotoModal extends React.PureComponent {
 				<View style={styles.imageWrapper}>
 					<ScrollView contentContainerStyle={styles.imageWrapper} maximumZoomScale={5}>
 						<TouchableWithoutFeedback onPress={onClose}>
-							<CachedImage
+							<FastImage
 								style={styles.image}
 								source={{ uri: encodeURI(image) }}
 								mutable
diff --git a/app/containers/message/Reply.js b/app/containers/message/Reply.js
index f6df68380..592482bb6 100644
--- a/app/containers/message/Reply.js
+++ b/app/containers/message/Reply.js
@@ -65,13 +65,6 @@ const onPress = (attachment) => {
 	openLink(attachment.title_link || attachment.author_link);
 };
 
-// Support <http://link|Text>
-const formatText = text =>
-	text.replace(
-		new RegExp('(?:<|<)((?:https|http):\\/\\/[^\\|]+)\\|(.+?)(?=>|>)(?:>|>)', 'gm'),
-		(match, url, title) => `[${ title }](${ url })`
-	);
-
 const Reply = ({ attachment, timeFormat }) => {
 	if (!attachment) {
 		return null;
@@ -113,7 +106,7 @@ const Reply = ({ attachment, timeFormat }) => {
 	};
 
 	const renderText = () => (
-		attachment.text ? <Markdown msg={formatText(attachment.text)} /> : null
+		attachment.text ? <Markdown msg={attachment.text} /> : null
 	);
 
 	const renderFields = () => {
diff --git a/app/views/Photo.js b/app/views/Photo.js
deleted file mode 100644
index a13dd4adb..000000000
--- a/app/views/Photo.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react';
-import { ScrollView, View } from 'react-native';
-import { CachedImage } from 'react-native-img-cache';
-import PropTypes from 'prop-types';
-
-const styles = {
-	imageWrapper: {
-		flex: 1,
-		alignItems: 'stretch',
-		backgroundColor: '#000'
-	},
-	image: {
-		flex: 1
-	}
-};
-
-export default class Photo extends React.PureComponent {
-	static propTypes = {
-		navigation: PropTypes.object.isRequired
-	}
-	render() {
-		const { image } = this.props.navigation.state.params;
-		return (
-			<View style={styles.imageWrapper}>
-				<ScrollView contentContainerStyle={styles.imageWrapper} maximumZoomScale={1.5}>
-					<CachedImage
-						style={{ ...styles.image }}
-						source={{ uri: encodeURI(image) }}
-						mutable
-						resizeMode='contain'
-					/>
-				</ScrollView>
-			</View>
-		);
-	}
-}
diff --git a/app/views/RoomView/ListView.js b/app/views/RoomView/ListView.js
index 0c0d587b8..3dd10fbea 100644
--- a/app/views/RoomView/ListView.js
+++ b/app/views/RoomView/ListView.js
@@ -9,7 +9,6 @@ import PropTypes from 'prop-types';
 import DateSeparator from './DateSeparator';
 import UnreadSeparator from './UnreadSeparator';
 import styles from './styles';
-import throttle from '../../utils/throttle';
 import Typing from '../../containers/Typing';
 import database from '../../lib/realm';
 import scrollPersistTaps from '../../utils/scrollPersistTaps';
@@ -52,17 +51,16 @@ export class List extends React.Component {
 		return this.props.end !== nextProps.end;
 	}
 	componentWillUnmount() {
-		this.date.removeListener(this.updateState);
-		this.date.removeAllListeners();
+		this.data.removeAllListeners();
 		this.updateState.stop();
 	}
-	updateState = throttle(() => {
+	updateState = () => {
 		// this.setState({
 		this.dataSource = this.dataSource.cloneWithRows(this.data);
 		LayoutAnimation.easeInEaseOut();
 		this.forceUpdate();
 		// });
-	}, 2500);
+	};
 
 	render() {
 		return (<ListView
@@ -70,13 +68,14 @@ export class List extends React.Component {
 			style={styles.list}
 			data={this.data}
 			keyExtractor={item => item._id}
-			onEndReachedThreshold={0.5}
+			onEndReachedThreshold={100}
 			renderFooter={this.props.renderFooter}
 			renderHeader={() => <Typing />}
 			onEndReached={() => this.props.onEndReached(this.data)}
 			dataSource={this.dataSource}
 			renderRow={(item, previousItem) => this.props.renderRow(item, previousItem)}
-			initialListSize={10}
+			initialListSize={20}
+			pageSize={20}
 			{...scrollPersistTaps}
 		/>);
 	}
diff --git a/app/views/RoomsListView/Header/index.js b/app/views/RoomsListView/Header/index.js
index 3850acb72..e07b3dc37 100644
--- a/app/views/RoomsListView/Header/index.js
+++ b/app/views/RoomsListView/Header/index.js
@@ -4,7 +4,7 @@ import Icon from 'react-native-vector-icons/Ionicons';
 import PropTypes from 'prop-types';
 import { connect } from 'react-redux';
 import Modal from 'react-native-modal';
-import { CachedImage } from 'react-native-img-cache';
+import FastImage from 'react-native-fast-image';
 import { HeaderBackButton } from 'react-navigation';
 
 import Avatar from '../../../containers/Avatar';
@@ -118,7 +118,7 @@ export default class RoomsListHeaderView extends React.PureComponent {
 					style={styles.headerButton}
 					onPress={() => this.props.navigation.navigate({ key: 'DrawerOpen', routeName: 'DrawerOpen' })}
 				>
-					<CachedImage
+					<FastImage
 						style={styles.serverImage}
 						source={{ uri: encodeURI(`${ this.props.baseUrl }/assets/favicon_32.png`) }}
 					/>
diff --git a/ios/RocketChatRN.xcodeproj/project.pbxproj b/ios/RocketChatRN.xcodeproj/project.pbxproj
index 0bf4d04e1..800e7e1a1 100644
--- a/ios/RocketChatRN.xcodeproj/project.pbxproj
+++ b/ios/RocketChatRN.xcodeproj/project.pbxproj
@@ -5,7 +5,6 @@
 	};
 	objectVersion = 46;
 	objects = {
-
 /* Begin PBXBuildFile section */
 		00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
 		00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
@@ -71,6 +70,7 @@
 		CBD0E0A35B174C4DBFED3B31 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E528DE3A405E43B4A37ABA68 /* Zocial.ttf */; };
 		D6408D9E4A864FF6BA986857 /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8A2DD67ADD954AD9873F45FC /* SimpleLineIcons.ttf */; };
 		EF736EF520A64AE8820E684A /* libRealmReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DF26CC845883492D8AC8869B /* libRealmReact.a */; };
+		BAB7DC22804246F3923A1833 /* libFastImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD2E2837F110483CA29EE0D4 /* libFastImage.a */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -535,6 +535,8 @@
 		DF26CC845883492D8AC8869B /* libRealmReact.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRealmReact.a; sourceTree = "<group>"; };
 		E528DE3A405E43B4A37ABA68 /* Zocial.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Zocial.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Zocial.ttf"; sourceTree = "<group>"; };
 		F88C6541BD764BEEABB87272 /* Octicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Octicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = "<group>"; };
+		1845C223DA364898A8400573 /* FastImage.xcodeproj */ = {isa = PBXFileReference; name = "FastImage.xcodeproj"; path = "../node_modules/react-native-fast-image/ios/FastImage.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
+		FD2E2837F110483CA29EE0D4 /* libFastImage.a */ = {isa = PBXFileReference; name = "libFastImage.a"; path = "libFastImage.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -580,6 +582,7 @@
 				0F026E58B8A6427D9A204D89 /* libSplashScreen.a in Frameworks */,
 				2C800DF680F8451599E80AF1 /* libSafariViewManager.a in Frameworks */,
 				74815BBCB91147C08C8F7B3D /* libRNAudio.a in Frameworks */,
+				BAB7DC22804246F3923A1833 /* libFastImage.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -839,6 +842,7 @@
 				30FCE1B6376C423E94C9FBB0 /* SplashScreen.xcodeproj */,
 				4019A5E1911B4C61944FBCEC /* SafariViewManager.xcodeproj */,
 				C21010507E5B4B37BA0E4C9D /* RNAudio.xcodeproj */,
+				1845C223DA364898A8400573 /* FastImage.xcodeproj */,
 			);
 			name = Libraries;
 			sourceTree = "<group>";
@@ -1768,6 +1772,7 @@
 					"$(SRCROOT)/../node_modules/react-native-splash-screen/ios",
 					"$(SRCROOT)/../node_modules/react-native-safari-view",
 					"$(SRCROOT)/../node_modules/react-native-audio/ios",
+					"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
 				);
 				INFOPLIST_FILE = RocketChatRNTests/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -1781,6 +1786,7 @@
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				OTHER_LDFLAGS = (
 					"-ObjC",
@@ -1811,6 +1817,7 @@
 					"$(SRCROOT)/../node_modules/react-native-splash-screen/ios",
 					"$(SRCROOT)/../node_modules/react-native-safari-view",
 					"$(SRCROOT)/../node_modules/react-native-audio/ios",
+					"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
 				);
 				INFOPLIST_FILE = RocketChatRNTests/Info.plist;
 				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
@@ -1824,6 +1831,7 @@
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				OTHER_LDFLAGS = (
 					"-ObjC",
@@ -1864,6 +1872,7 @@
 					"$(SRCROOT)/../node_modules/react-native-safari-view",
 					"$(SRCROOT)/../node_modules/react-native-audio/ios",
 					"$(SRCROOT)/../../../react-native/React/**",
+					"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
 				);
 				INFOPLIST_FILE = RocketChatRN/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -1909,6 +1918,7 @@
 					"$(SRCROOT)/../node_modules/react-native-safari-view",
 					"$(SRCROOT)/../node_modules/react-native-audio/ios",
 					"$(SRCROOT)/../../../react-native/React/**",
+					"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
 				);
 				INFOPLIST_FILE = RocketChatRN/Info.plist;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -1952,6 +1962,7 @@
 					"$(SRCROOT)/../node_modules/react-native-splash-screen/ios",
 					"$(SRCROOT)/../node_modules/react-native-safari-view",
 					"$(SRCROOT)/../node_modules/react-native-audio/ios",
+					"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
 				);
 				INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -1964,6 +1975,7 @@
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				OTHER_LDFLAGS = (
 					"-ObjC",
@@ -2004,6 +2016,7 @@
 					"$(SRCROOT)/../node_modules/react-native-splash-screen/ios",
 					"$(SRCROOT)/../node_modules/react-native-safari-view",
 					"$(SRCROOT)/../node_modules/react-native-audio/ios",
+					"$(SRCROOT)/../node_modules/react-native-fast-image/ios/FastImage/**",
 				);
 				INFOPLIST_FILE = "RocketChatRN-tvOS/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -2016,6 +2029,7 @@
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				OTHER_LDFLAGS = (
 					"-ObjC",
@@ -2052,6 +2066,7 @@
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests";
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -2084,6 +2099,7 @@
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 					"\"$(SRCROOT)/$(TARGET_NAME)\"",
+					"\"$(SRCROOT)/$(TARGET_NAME)\"",
 				);
 				PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.RocketChatRN-tvOSTests";
 				PRODUCT_NAME = "$(TARGET_NAME)";
diff --git a/package-lock.json b/package-lock.json
index af04587d6..3cb4700d2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15869,6 +15869,14 @@
       "resolved": "https://registry.npmjs.org/react-native-fabric/-/react-native-fabric-0.5.1.tgz",
       "integrity": "sha512-NKYXiH8w/DjNXoozko1twjAd5F8shL/UiTVx/PQ8QNaasWpbxlXgeJ5exhDSIcDXao0AUdcPWJunYdSCjq208g=="
     },
+    "react-native-fast-image": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-4.0.8.tgz",
+      "integrity": "sha512-/FC2M3ZDqmQRERQpYlyMhyr7eX5euvi9bXkowNY5A7t/bRB09LSsfQbk8FtI2stgSgA6d0YUXHt3ll7m/ZB0SQ==",
+      "requires": {
+        "prop-types": "15.6.1"
+      }
+    },
     "react-native-fetch-blob": {
       "version": "0.10.8",
       "resolved": "https://registry.npmjs.org/react-native-fetch-blob/-/react-native-fetch-blob-0.10.8.tgz",
@@ -15898,14 +15906,6 @@
       "resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-0.26.7.tgz",
       "integrity": "sha1-rS7pV/f2zAE5aJPqA9hMsq2y43Y="
     },
-    "react-native-img-cache": {
-      "version": "1.5.3",
-      "resolved": "https://registry.npmjs.org/react-native-img-cache/-/react-native-img-cache-1.5.3.tgz",
-      "integrity": "sha1-zP+6hmAwd9C+T53Aiv9Z4/VRCQs=",
-      "requires": {
-        "crypto-js": "3.1.9-1"
-      }
-    },
     "react-native-iphone-x-helper": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.0.2.tgz",
diff --git a/package.json b/package.json
index 53125930e..949dfa320 100644
--- a/package.json
+++ b/package.json
@@ -46,9 +46,9 @@
     "react-native-cached-image": "^1.4.3",
     "react-native-easy-markdown": "git+https://github.com/diegolmello/react-native-easy-markdown.git",
     "react-native-fabric": "^0.5.1",
+    "react-native-fast-image": "^4.0.8",
     "react-native-fetch-blob": "^0.10.8",
     "react-native-image-picker": "^0.26.7",
-    "react-native-img-cache": "^1.5.2",
     "react-native-keyboard-aware-scroll-view": "^0.5.0",
     "react-native-keyboard-input": "git+https://github.com/RocketChat/react-native-keyboard-input.git",
     "react-native-keyboard-tracking-view": "git+https://github.com/RocketChat/react-native-keyboard-tracking-view.git",
-- 
GitLab