diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0933bddc..a18712e5 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -158,6 +158,15 @@ PODS: - GoogleUtilities/Logger - GoogleUtilities/UserDefaults (6.7.2): - GoogleUtilities/Logger + - libwebp (1.1.0): + - libwebp/demux (= 1.1.0) + - libwebp/mux (= 1.1.0) + - libwebp/webp (= 1.1.0) + - libwebp/demux (1.1.0): + - libwebp/webp + - libwebp/mux (1.1.0): + - libwebp/demux + - libwebp/webp (1.1.0) - nanopb (0.3.9011): - nanopb/decode (= 0.3.9011) - nanopb/encode (= 0.3.9011) @@ -402,6 +411,10 @@ PODS: - React-Core - RNCMaskedView (0.1.10): - React + - RNFastImage (8.3.4): + - React-Core + - SDWebImage (~> 5.8) + - SDWebImageWebPCoder (~> 0.6.1) - RNGestureHandler (1.8.0): - React - RNReanimated (2.0.0-rc.0): @@ -440,6 +453,12 @@ PODS: - Sentry (= 6.0.9) - RNSVG (12.1.0): - React + - SDWebImage (5.10.3): + - SDWebImage/Core (= 5.10.3) + - SDWebImage/Core (5.10.3) + - SDWebImageWebPCoder (0.6.1): + - libwebp (~> 1.0) + - SDWebImage/Core (~> 5.7) - Sentry (6.0.9): - Sentry/Core (= 6.0.9) - Sentry/Core (6.0.9) @@ -525,6 +544,7 @@ DEPENDENCIES: - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)" + - RNFastImage (from `../node_modules/react-native-fast-image`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNReanimated (from `../node_modules/react-native-reanimated`) - RNScreens (from `../node_modules/react-native-screens`) @@ -558,8 +578,11 @@ SPEC REPOS: - GoogleDataTransport - GoogleDataTransportCCTSupport - GoogleUtilities + - libwebp - nanopb - PromisesObjC + - SDWebImage + - SDWebImageWebPCoder - Sentry EXTERNAL SOURCES: @@ -683,6 +706,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-async-storage/async-storage" RNCMaskedView: :path: "../node_modules/@react-native-community/masked-view" + RNFastImage: + :path: "../node_modules/react-native-fast-image" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" RNReanimated: @@ -768,6 +793,7 @@ SPEC CHECKSUMS: GoogleDataTransport: 9a8a16f79feffc7f42096743de2a7c4815e84020 GoogleDataTransportCCTSupport: 0f39025e8cf51f168711bd3fb773938d7e62ddb5 GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 + libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3 nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97 RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e @@ -796,11 +822,14 @@ SPEC CHECKSUMS: ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b RNCAsyncStorage: da95b83e241a7f5efe3da1a949b3ec3175380be0 RNCMaskedView: 5a8ec07677aa885546a0d98da336457e2bea557f + RNFastImage: d4870d58f5936111c56218dbd7fcfc18e65b58ff RNGestureHandler: 7a5833d0f788dbd107fbb913e09aa0c1ff333c39 RNReanimated: b9c929bfff7dedc9c89ab1875f1c6151023358d9 RNScreens: 3d682bcaba69a4f8e55543d90818704f34338db1 RNSentry: 6b46b6fc1d715a378fbaa5d7d43bc9ce99b500e5 RNSVG: ce9d996113475209013317e48b05c21ee988d42e + SDWebImage: e378178472b735e84b007bfb55514c97948a0598 + SDWebImageWebPCoder: d0dac55073088d24b2ac1b191a71a8f8d0adac21 Sentry: 388c9dc093b2fd3a264466a5c5b21e25959610a9 UMAppLoader: 92d044af52626af3d81a69796ad666fc7a9a7d78 UMBarCodeScannerInterface: 3f6c1b09ef4b867ce752b8c0b3893bcf9cd85f32 diff --git a/package.json b/package.json index 3ffd62d4..6e3aacf7 100644 --- a/package.json +++ b/package.json @@ -50,13 +50,12 @@ "gl-react-expo": "^4.0.1", "i18next": "^19.8.4", "lodash": "^4.17.20", - "pretty-bytes": "^5.5.0", "react": "16.13.1", "react-dom": "16.13.1", "react-i18next": "^11.8.5", "react-native": "~0.63.4", "react-native-animated-spinkit": "^1.4.2", - "react-native-expo-image-cache": "^4.1.0", + "react-native-fast-image": "^8.3.4", "react-native-feather": "^1.0.2", "react-native-gesture-handler": "~1.8.0", "react-native-htmlview": "^0.16.0", diff --git a/src/components/GracefullyImage.tsx b/src/components/GracefullyImage.tsx index 127ea09b..dca51fd7 100644 --- a/src/components/GracefullyImage.tsx +++ b/src/components/GracefullyImage.tsx @@ -1,80 +1,20 @@ import { StyleConstants } from '@utils/styles/constants' import { Surface } from 'gl-react-expo' import { Blurhash } from 'gl-react-blurhash' -import React, { useCallback, useEffect, useState } from 'react' +import React, { useCallback, useState } from 'react' import { - Image, ImageStyle, Pressable, StyleProp, StyleSheet, - View, ViewStyle } from 'react-native' -import { Image as ImageCache } from 'react-native-expo-image-cache' +import FastImage from 'react-native-fast-image' import { useTheme } from '@utils/styles/ThemeManager' -type CancelPromise = ((reason?: Error) => void) | undefined -interface ImageSizeOperation { - start: () => Promise - cancel: CancelPromise -} -const getImageSize = ({ - preview, - original, - remote -}: { - preview?: string - original: string - remote?: string -}): ImageSizeOperation => { - let cancel: CancelPromise - const start = (): Promise => - new Promise((resolve, reject) => { - cancel = reject - Image.getSize( - preview || '', - () => { - cancel = undefined - resolve(preview!) - }, - () => { - cancel = reject - Image.getSize( - original, - () => { - cancel = undefined - resolve(original) - }, - () => { - cancel = reject - if (!remote) { - reject() - } else { - Image.getSize( - remote, - () => { - cancel = undefined - resolve(remote) - }, - error => { - reject(error) - } - ) - } - } - ) - } - ) - }) - - return { start, cancel } -} - export interface Props { hidden?: boolean - cache?: boolean - uri: { preview?: string; original?: string; remote?: string } + uri: { preview?: string; original: string; remote?: string } blurhash?: string dimension?: { width: number; height: number } onPress?: () => void @@ -84,7 +24,6 @@ export interface Props { const GracefullyImage: React.FC = ({ hidden = false, - cache = false, uri, blurhash, dimension, @@ -93,68 +32,32 @@ const GracefullyImage: React.FC = ({ imageStyle }) => { const { mode, theme } = useTheme() - - const [imageVisible, setImageVisible] = useState() - - useEffect(() => { - let mounted = true - let cancel: CancelPromise - const sideEffect = async (): Promise => { - try { - const prefetchImage = getImageSize(uri as { original: string }) - cancel = prefetchImage.cancel - const res = await prefetchImage.start() - if (mounted) { - setImageVisible(res) - } - return - } catch (error) { - if (__DEV__) console.warn('Image', error) - } - } - - if (uri.original) { - sideEffect() - } - - return () => { - mounted = false - if (cancel) { - cancel() - } - } - }, [uri]) + const [imageLoaded, setImageLoaded] = useState(false) const children = useCallback(() => { - if (imageVisible && !hidden) { - if (cache) { - return ( - - ) - } else { - return ( - - ) - } - } else if (blurhash) { - return ( - - - - ) - } - }, [hidden, mode, imageVisible]) + return ( + <> + setImageLoaded(true)} + /> + {blurhash && (hidden || !imageLoaded) ? ( + + + + ) : null} + + ) + }, [hidden, imageLoaded, mode, uri]) return ( = ({ {/* When emoji starts a paragraph, lineHeight will break */} {i === 0 ? : null} - ) diff --git a/src/components/Timelines/Timeline/Conversation.tsx b/src/components/Timelines/Timeline/Conversation.tsx index aab14748..91f9f0cd 100644 --- a/src/components/Timelines/Timeline/Conversation.tsx +++ b/src/components/Timelines/Timeline/Conversation.tsx @@ -32,7 +32,6 @@ const Avatars: React.FC<{ accounts: Mastodon.Account[] }> = ({ accounts }) => { {accounts.slice(0, 4).map(account => ( = ({ ) ) : ( <> - {(audio.preview_url || audio.preview_remote_url) && ( + {audio.preview_url && ( diff --git a/src/components/Timelines/Timeline/Shared/Avatar.tsx b/src/components/Timelines/Timeline/Shared/Avatar.tsx index c308844a..5806ef97 100644 --- a/src/components/Timelines/Timeline/Shared/Avatar.tsx +++ b/src/components/Timelines/Timeline/Shared/Avatar.tsx @@ -23,7 +23,6 @@ const TimelineAvatar: React.FC = ({ queryKey, account }) => { return ( { @@ -28,11 +26,6 @@ const SettingsApp: React.FC = () => { const settingsTheme = useSelector(getSettingsTheme) const settingsBrowser = useSelector(getSettingsBrowser) - const [cacheSize, setCacheSize] = useState() - useEffect(() => { - CacheManager.getCacheSize().then(size => setCacheSize(size)) - }, []) - return ( { ) } /> - { - analytics('settings_cache_press', { - size: cacheSize ? prettyBytes(cacheSize) : 'empty' - }) - await CacheManager.clearCache() - haptics('Success') - setCacheSize(0) - }} - /> ) } diff --git a/src/screens/Shared/Account/Information/Avatar.tsx b/src/screens/Shared/Account/Information/Avatar.tsx index f8453655..6dc5b61f 100644 --- a/src/screens/Shared/Account/Information/Avatar.tsx +++ b/src/screens/Shared/Account/Information/Avatar.tsx @@ -35,7 +35,7 @@ const AccountInformationAvatar: React.FC = ({ account, myInfo }) => { > diff --git a/yarn.lock b/yarn.lock index 9ff3b413..32662795 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7289,7 +7289,7 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= -lodash@^4, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.0: +lodash@^4, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.3.0, lodash@^4.5.0, lodash@^4.6.0: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -8791,13 +8791,10 @@ react-native-animated-spinkit@^1.4.2: resolved "https://registry.yarnpkg.com/react-native-animated-spinkit/-/react-native-animated-spinkit-1.5.1.tgz#a251d3c30f6c1876896252d8d2febf03759bf457" integrity sha512-n4zXVY2Ro3iprmznLEGmcmG/H8oXdG3AmHrXMa1lfH+gM+zL8gGTL91BGlrJC7Th9gEbB7Q2Glxt+GFW62GLQw== -react-native-expo-image-cache@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/react-native-expo-image-cache/-/react-native-expo-image-cache-4.1.0.tgz#649cbe9786249134d3eafed5baba50bbfa80c029" - integrity sha512-U6xHtuyalNZThhM11lu4+mRNSpJFkdh4dSLbWkKAj5QfY63cKlTnDVtv8c88njn71GHL4exEzf8hNKBMWhH37Q== - dependencies: - crypto-js "^3.1.9-1" - lodash "^4.17.4" +react-native-fast-image@^8.3.4: + version "8.3.4" + resolved "https://registry.yarnpkg.com/react-native-fast-image/-/react-native-fast-image-8.3.4.tgz#79edca177e30311b19d59ff335625bcbe22650d7" + integrity sha512-LpzAdjUphihUpVEBn5fEv5AILe55rHav0YiZroPZ1rumKDhAl4u2cG01ku2Pb7l8sayjTsNu7FuURAlXUUDsow== react-native-feather@^1.0.2: version "1.0.2"