diff --git a/.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch b/.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch deleted file mode 100644 index 3d890062..00000000 --- a/.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch +++ /dev/null @@ -1,363 +0,0 @@ -diff --git a/RNFastImage.podspec b/RNFastImage.podspec -index db0fada63fc06191f8620d336d244edde6c3dba3..9c22c36f6978530da21afe143324ff79b4e96454 100644 ---- a/RNFastImage.podspec -+++ b/RNFastImage.podspec -@@ -16,6 +16,6 @@ Pod::Spec.new do |s| - s.source_files = "ios/**/*.{h,m}" - - s.dependency 'React-Core' -- s.dependency 'SDWebImage', '~> 5.11.1' -- s.dependency 'SDWebImageWebPCoder', '~> 0.8.4' -+ s.dependency 'SDWebImage', '~> 5.15.0' -+ s.dependency 'SDWebImageWebPCoder', '~> 0.9.1' - end -diff --git a/android/build.gradle b/android/build.gradle -index 5b21cd59c40a5754f5d19c77e2a0eb0229925911..19d82f826e88125c5e6d87ee7c348fac621f548c 100644 ---- a/android/build.gradle -+++ b/android/build.gradle -@@ -65,4 +65,5 @@ dependencies { - implementation "com.github.bumptech.glide:glide:${glideVersion}" - implementation "com.github.bumptech.glide:okhttp3-integration:${glideVersion}" - annotationProcessor "com.github.bumptech.glide:compiler:${glideVersion}" -+ implementation 'com.github.penfeizhou.android.animation:glide-plugin:2.12.0' - } -diff --git a/android/src/main/java/com/dylanvann/fastimage/FastImageEnterTransition.java b/android/src/main/java/com/dylanvann/fastimage/FastImageEnterTransition.java -new file mode 100644 -index 0000000000000000000000000000000000000000..55e3b4e0d463654f62d942ba05c2a5e51ae9d6d7 ---- /dev/null -+++ b/android/src/main/java/com/dylanvann/fastimage/FastImageEnterTransition.java -@@ -0,0 +1,6 @@ -+package com.dylanvann.fastimage; -+ -+public enum FastImageEnterTransition { -+ TRANSITION_NONE, -+ FADE_IN -+} -diff --git a/android/src/main/java/com/dylanvann/fastimage/FastImageTransitions.java b/android/src/main/java/com/dylanvann/fastimage/FastImageTransitions.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d764cc4b8d110f087120a4f0dc5d986754806dec ---- /dev/null -+++ b/android/src/main/java/com/dylanvann/fastimage/FastImageTransitions.java -@@ -0,0 +1,20 @@ -+package com.dylanvann.fastimage; -+ -+import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; -+import com.bumptech.glide.TransitionOptions; -+import com.facebook.react.bridge.JSApplicationIllegalArgumentException; -+import android.view.animation.DecelerateInterpolator; -+ -+public class FastImageTransitions { -+ static final DecelerateInterpolator mInterpolator = new DecelerateInterpolator(); -+ -+ public static TransitionOptions getEnterTransition(FastImageEnterTransition transition, int duration) { -+ switch (transition) { -+ case FADE_IN: -+ return DrawableTransitionOptions.withCrossFade(duration); -+ -+ default: -+ throw new JSApplicationIllegalArgumentException("FastImage, invalid enterTransition argument"); -+ } -+ } -+} -\ No newline at end of file -diff --git a/android/src/main/java/com/dylanvann/fastimage/FastImageViewConverter.java b/android/src/main/java/com/dylanvann/fastimage/FastImageViewConverter.java -index 86ca00d018d7ded0edff733373d80976c8dbb961..e6220f57b38a3fe3ae9d5a75228f791e0ec978bb 100644 ---- a/android/src/main/java/com/dylanvann/fastimage/FastImageViewConverter.java -+++ b/android/src/main/java/com/dylanvann/fastimage/FastImageViewConverter.java -@@ -50,6 +50,12 @@ class FastImageViewConverter { - put("center", ScaleType.CENTER_INSIDE); - }}; - -+ private static final Map FAST_IMAGE_ENTER_TRANSITION_MAP = -+ new HashMap() {{ -+ put("none", FastImageEnterTransition.TRANSITION_NONE); -+ put("fadeIn", FastImageEnterTransition.FADE_IN); -+ }}; -+ - // Resolve the source uri to a file path that android understands. - static @Nullable - FastImageSource getImageSource(Context context, @Nullable ReadableMap source) { -@@ -125,6 +131,10 @@ class FastImageViewConverter { - return getValueFromSource("cache", "immutable", FAST_IMAGE_CACHE_CONTROL_MAP, source); - } - -+ static FastImageEnterTransition getEnterTransition(String propValue) { -+ return getValue("enterTransition", "none", FAST_IMAGE_ENTER_TRANSITION_MAP, propValue); -+ } -+ - private static Priority getPriority(ReadableMap source) { - return getValueFromSource("priority", "normal", FAST_IMAGE_PRIORITY_MAP, source); - } -diff --git a/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java b/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java -index c7a795471c8f8b48163c778836406bc5ead75dab..53b481547b44224e7791a8d3f39815c9c9a4be59 100644 ---- a/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java -+++ b/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java -@@ -83,6 +83,17 @@ class FastImageViewManager extends SimpleViewManager imple - view.setScaleType(scaleType); - } - -+ @ReactProp(name = "enterTransition") -+ public void setEnterTransition(FastImageViewWithUrl view, String enterTransition) { -+ final FastImageEnterTransition transition = FastImageViewConverter.getEnterTransition(enterTransition); -+ view.setEnterTransition(transition); -+ } -+ -+ @ReactProp(name = "transitionDuration") -+ public void setTransitionDuration(FastImageViewWithUrl view, int transitionDuration) { -+ view.setTransitionDuration(transitionDuration); -+ } -+ - @Override - public void onDropViewInstance(@NonNull FastImageViewWithUrl view) { - // This will cancel existing requests. -diff --git a/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java b/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java -index 34fcf898d17d82fd52375e9028b71ad815b9b15b..fd57ac68de093d2a8ee53aeede45328c8d52aa39 100644 ---- a/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java -+++ b/android/src/main/java/com/dylanvann/fastimage/FastImageViewWithUrl.java -@@ -30,6 +30,8 @@ class FastImageViewWithUrl extends AppCompatImageView { - private boolean mNeedsReload = false; - private ReadableMap mSource = null; - private Drawable mDefaultSource = null; -+ private FastImageEnterTransition mEnterTransition = FastImageEnterTransition.TRANSITION_NONE; -+ private int mTransitionDuration = 350; - - public GlideUrl glideUrl; - -@@ -47,6 +49,14 @@ class FastImageViewWithUrl extends AppCompatImageView { - mDefaultSource = source; - } - -+ public void setEnterTransition(@Nullable FastImageEnterTransition transition) { -+ mEnterTransition = transition; -+ } -+ -+ public void setTransitionDuration(int duration) { -+ mTransitionDuration = duration == 0 ? 350 : duration; -+ } -+ - private boolean isNullOrEmpty(final String url) { - return url == null || url.trim().isEmpty(); - } -@@ -147,6 +157,10 @@ class FastImageViewWithUrl extends AppCompatImageView { - if (key != null) - builder.listener(new FastImageRequestListener(key)); - -+ if (mEnterTransition != FastImageEnterTransition.TRANSITION_NONE) { -+ builder.transition(FastImageTransitions.getEnterTransition(mEnterTransition, mTransitionDuration)); -+ } -+ - builder.into(this); - } - } -diff --git a/dist/index.cjs.js b/dist/index.cjs.js -index 2df6a29769978d8d947dfb50b422e1f56bd97fb6..f3904e20edac5f19cc26f41a4ff02eecd73ac627 100644 ---- a/dist/index.cjs.js -+++ b/dist/index.cjs.js -@@ -9,6 +9,10 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau - var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends); - var React__default = /*#__PURE__*/_interopDefaultLegacy(React); - -+const enterTransition = { -+ none: 'none', -+ fadeIn: 'fadeIn' -+} - const resizeMode = { - contain: 'contain', - cover: 'cover', -@@ -115,6 +119,7 @@ const FastImageComponent = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PU - }, props))); - FastImageComponent.displayName = 'FastImage'; - const FastImage = FastImageComponent; -+FastImage.enterTransition = enterTransition - FastImage.resizeMode = resizeMode; - FastImage.cacheControl = cacheControl; - FastImage.priority = priority; -diff --git a/dist/index.d.ts b/dist/index.d.ts -index 5abb7c98b767cd0709b53f5ab2dd50c752a9377b..2da22817e3136673d40a177ae8c9fc2209f143d8 100644 ---- a/dist/index.d.ts -+++ b/dist/index.d.ts -@@ -1,5 +1,10 @@ - import React from 'react'; - import { FlexStyle, LayoutChangeEvent, ShadowStyleIOS, StyleProp, TransformsStyle, ImageRequireSource, AccessibilityProps, ViewProps, ColorValue } from 'react-native'; -+export declare type EnterTransition = 'none' | 'fadeIn'; -+declare const enterTransition: { -+ readonly none: "none"; -+ readonly fadeIn: "fadeIn"; -+}; - export declare type ResizeMode = 'contain' | 'cover' | 'stretch' | 'center'; - declare const resizeMode: { - readonly contain: "contain"; -@@ -57,6 +62,16 @@ export interface FastImageProps extends AccessibilityProps, ViewProps { - defaultSource?: ImageRequireSource; - resizeMode?: ResizeMode; - fallback?: boolean; -+ /** -+ * Transition durations. -+ * @default none -+ */ -+ enterTransition?: EnterTransition -+ /** -+ * Enter transition duration in ms. -+ * @default 500ms -+ */ -+ transitionDuration?: number - onLoadStart?(): void; - onProgress?(event: OnProgressEvent): void; - onLoad?(event: OnLoadEvent): void; -@@ -91,6 +106,7 @@ export interface FastImageProps extends AccessibilityProps, ViewProps { - children?: React.ReactNode; - } - export interface FastImageStaticProperties { -+ enterTransition: typeof enterTransition; - resizeMode: typeof resizeMode; - priority: typeof priority; - cacheControl: typeof cacheControl; -diff --git a/dist/index.js b/dist/index.js -index 58e0308bd44836aad3e4979b5c1151083956c295..5853b3b2fd05c91be8c70819fe6fc45606f26f8d 100644 ---- a/dist/index.js -+++ b/dist/index.js -@@ -2,6 +2,10 @@ import _extends from '@babel/runtime/helpers/extends'; - import React, { forwardRef, memo } from 'react'; - import { NativeModules, StyleSheet, requireNativeComponent, Image, View, Platform } from 'react-native'; - -+const enterTransition = { -+ none: 'none', -+ fadeIn: 'fadeIn' -+} - const resizeMode = { - contain: 'contain', - cover: 'cover', -@@ -57,6 +61,8 @@ function FastImageBase({ - children, - // eslint-disable-next-line no-shadow - resizeMode = 'cover', -+ enterTransition = 'none', -+ transitionDuration = 350, - forwardedRef, - ...props - }) { -@@ -79,7 +85,9 @@ function FastImageBase({ - onLoad: onLoad, - onError: onError, - onLoadEnd: onLoadEnd, -- resizeMode: resizeMode -+ resizeMode: resizeMode, -+ enterTransition: enterTransition, -+ transitionDuration: transitionDuration - })), children); - } - -@@ -98,7 +106,9 @@ function FastImageBase({ - onFastImageLoad: onLoad, - onFastImageError: onError, - onFastImageLoadEnd: onLoadEnd, -- resizeMode: resizeMode -+ resizeMode: resizeMode, -+ enterTransition: enterTransition, -+ transitionDuration: transitionDuration - })), children); - } - -@@ -108,6 +118,7 @@ const FastImageComponent = /*#__PURE__*/forwardRef((props, ref) => /*#__PURE__*/ - }, props))); - FastImageComponent.displayName = 'FastImage'; - const FastImage = FastImageComponent; -+FastImage.enterTransition = enterTransition - FastImage.resizeMode = resizeMode; - FastImage.cacheControl = cacheControl; - FastImage.priority = priority; -diff --git a/ios/FastImage/FFFastImageView.h b/ios/FastImage/FFFastImageView.h -index e52fca79882ad2a678487a46b2fe158427e06f3a..6c9c41b0b1a3c967a3715a24bb692447b76ef365 100644 ---- a/ios/FastImage/FFFastImageView.h -+++ b/ios/FastImage/FFFastImageView.h -@@ -7,6 +7,7 @@ - #import - - #import "FFFastImageSource.h" -+#import "FFFastImageViewManager.h" - - @interface FFFastImageView : SDAnimatedImageView - -@@ -16,6 +17,8 @@ - @property (nonatomic, copy) RCTDirectEventBlock onFastImageLoad; - @property (nonatomic, copy) RCTDirectEventBlock onFastImageLoadEnd; - @property (nonatomic, assign) RCTResizeMode resizeMode; -+@property (nonatomic, assign) FFFEnterTransition enterTransition; -+@property (nonatomic, assign) NSTimeInterval transitionDuration; - @property (nonatomic, strong) FFFastImageSource *source; - @property (nonatomic, strong) UIImage *defaultSource; - @property (nonatomic, strong) UIColor *imageColor; -diff --git a/ios/FastImage/FFFastImageView.m b/ios/FastImage/FFFastImageView.m -index f7100815e652539b29b1fa70ff1477c5f5db08dc..ecb79eafe566fe52090adada3cdf16eb10a67513 100644 ---- a/ios/FastImage/FFFastImageView.m -+++ b/ios/FastImage/FFFastImageView.m -@@ -71,6 +71,18 @@ - (void) setImageColor: (UIColor*)imageColor { - } - } - -+- (void) setTransitionDuration: (NSTimeInterval)transitionDuration { -+ self.sd_imageTransition.duration = transitionDuration; -+} -+ -+- (void) setEnterTransition: (FFFEnterTransition)enterTransition { -+ switch (enterTransition) { -+ case FFFFadeIn: -+ self.sd_imageTransition = SDWebImageTransition.fadeTransition; -+ break; -+ } -+} -+ - - (UIImage*) makeImage: (UIImage*)image withTint: (UIColor*)color { - UIImage* newImage = [image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate]; - UIGraphicsBeginImageContextWithOptions(image.size, NO, newImage.scale); -diff --git a/ios/FastImage/FFFastImageViewManager.h b/ios/FastImage/FFFastImageViewManager.h -index 8ba6020e2c6e5757ed778d00e3f43a6ff4c1d50a..a269669301ea00ef3c2714123d17e822094635d6 100644 ---- a/ios/FastImage/FFFastImageViewManager.h -+++ b/ios/FastImage/FFFastImageViewManager.h -@@ -1,5 +1,10 @@ - #import - -+typedef NS_ENUM(NSInteger, FFFEnterTransition) { -+ FFFTransitionNone, -+ FFFFadeIn, -+}; -+ - @interface FFFastImageViewManager : RCTViewManager - - @end -diff --git a/ios/FastImage/FFFastImageViewManager.m b/ios/FastImage/FFFastImageViewManager.m -index 84ca94e26e546d4d139dabca6c3efd0a890eda63..2184bac31f0d547e6119356bb4fc7931be87446d 100644 ---- a/ios/FastImage/FFFastImageViewManager.m -+++ b/ios/FastImage/FFFastImageViewManager.m -@@ -13,6 +13,8 @@ - (FFFastImageView*)view { - } - - RCT_EXPORT_VIEW_PROPERTY(source, FFFastImageSource) -+RCT_EXPORT_VIEW_PROPERTY(enterTransition, FFFEnterTransition) -+RCT_EXPORT_VIEW_PROPERTY(transitionDuration, NSTimeInterval) - RCT_EXPORT_VIEW_PROPERTY(defaultSource, UIImage) - RCT_EXPORT_VIEW_PROPERTY(resizeMode, RCTResizeMode) - RCT_EXPORT_VIEW_PROPERTY(onFastImageLoadStart, RCTDirectEventBlock) -diff --git a/ios/FastImage/RCTConvert+FFFastImage.m b/ios/FastImage/RCTConvert+FFFastImage.m -index 43f8922157655a7497f56a3909ef6b2a886f07d8..0705f8e05f44f3053e7239fcc9a30d986e7aaab7 100644 ---- a/ios/FastImage/RCTConvert+FFFastImage.m -+++ b/ios/FastImage/RCTConvert+FFFastImage.m -@@ -1,5 +1,6 @@ - #import "RCTConvert+FFFastImage.h" - #import "FFFastImageSource.h" -+#import "FFFastImageViewManager.h" - - @implementation RCTConvert (FFFastImage) - -@@ -15,6 +16,11 @@ @implementation RCTConvert (FFFastImage) - @"cacheOnly": @(FFFCacheControlCacheOnly), - }), FFFCacheControlImmutable, integerValue); - -+RCT_ENUM_CONVERTER(FFFEnterTransition, (@{ -+ @"none": @(FFFTransitionNone), -+ @"fadeIn": @(FFFFadeIn), -+ }), FFFTransitionNone, integerValue); -+ - + (FFFastImageSource *)FFFastImageSource:(id)json { - if (!json) { - return nil; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index d82e3a1d..4f7f6b9f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -3,14 +3,14 @@ PODS: - DoubleConversion (1.1.6) - EXApplication (5.0.1): - ExpoModulesCore - - EXAV (13.1.0): + - EXAV (13.2.0): - ExpoModulesCore - ReactCommon/turbomodule/core - - EXConstants (14.1.0): + - EXConstants (14.2.0): - ExpoModulesCore - EXErrorRecovery (4.0.1): - ExpoModulesCore - - EXFileSystem (15.1.1): + - EXFileSystem (15.2.0): - ExpoModulesCore - EXFont (11.0.1): - ExpoModulesCore @@ -18,31 +18,37 @@ PODS: - ExpoModulesCore - Expo (47.0.13): - ExpoModulesCore - - ExpoCrypto (12.1.0): + - ExpoCrypto (12.2.0): - ExpoModulesCore - - ExpoHaptics (12.1.0): + - ExpoHaptics (12.2.0): - ExpoModulesCore + - ExpoImage (1.0.0-beta.6): + - ExpoModulesCore + - SDWebImage (~> 5.15.0) + - SDWebImageAVIFCoder (~> 0.9.4) + - SDWebImageSVGCoder (~> 1.6.1) + - SDWebImageWebPCoder (~> 0.9.1) - ExpoKeepAwake (11.0.1): - ExpoModulesCore - - ExpoLocalization (14.0.0): + - ExpoLocalization (14.1.0): - ExpoModulesCore - ExpoModulesCore (1.1.1): - React-Core - ReactCommon/turbomodule/core - - ExpoRandom (13.0.0): + - ExpoRandom (13.1.0): - ExpoModulesCore - - ExpoStoreReview (6.1.0): + - ExpoStoreReview (6.2.0): - ExpoModulesCore - - ExpoVideoThumbnails (7.1.0): + - ExpoVideoThumbnails (7.2.0): - ExpoModulesCore - ExpoWebBrowser (12.0.0): - ExpoModulesCore - - EXScreenCapture (5.0.0): + - EXScreenCapture (5.1.0): - ExpoModulesCore - - EXScreenOrientation (5.0.1): + - EXScreenOrientation (5.1.0): - ExpoModulesCore - React-Core - - EXSecureStore (12.0.0): + - EXSecureStore (12.1.0): - ExpoModulesCore - EXSplashScreen (0.17.5): - ExpoModulesCore @@ -58,7 +64,16 @@ PODS: - fmt (6.2.1) - glog (0.3.5) - hermes-engine (0.70.7) + - libaom (2.0.2): + - libvmaf + - libavif (0.10.1): + - libavif/libaom (= 0.10.1) + - libavif/core (0.10.1) + - libavif/libaom (0.10.1): + - libaom (>= 2.0.0) + - libavif/core - libevent (2.1.12) + - libvmaf (2.2.0) - libwebp (1.2.4): - libwebp/demux (= 1.2.4) - libwebp/mux (= 1.2.4) @@ -299,8 +314,6 @@ PODS: - glog - react-native-blur (4.3.0): - React-Core - - react-native-blurhash (1.1.10): - - React-Core - react-native-cameraroll (5.2.3): - React-Core - react-native-image-picker (5.0.1): @@ -401,10 +414,6 @@ PODS: - React-Core - RNCClipboard (1.11.1): - React-Core - - RNFastImage (8.6.3): - - React-Core - - SDWebImage (~> 5.15.0) - - SDWebImageWebPCoder (~> 0.9.1) - RNGestureHandler (2.9.0): - React-Core - RNReanimated (2.14.4): @@ -447,6 +456,11 @@ PODS: - SDWebImage (5.15.0): - SDWebImage/Core (= 5.15.0) - SDWebImage/Core (5.15.0) + - SDWebImageAVIFCoder (0.9.5): + - libavif (>= 0.9.1) + - SDWebImage (~> 5.10) + - SDWebImageSVGCoder (1.6.1): + - SDWebImage/Core (~> 5.6) - SDWebImageWebPCoder (0.9.1): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.13) @@ -467,6 +481,7 @@ DEPENDENCIES: - Expo (from `../node_modules/expo`) - ExpoCrypto (from `../node_modules/expo-crypto/ios`) - ExpoHaptics (from `../node_modules/expo-haptics/ios`) + - ExpoImage (from `../node_modules/expo-image/ios`) - ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`) - ExpoLocalization (from `../node_modules/expo-localization/ios`) - ExpoModulesCore (from `../node_modules/expo-modules-core`) @@ -500,7 +515,6 @@ DEPENDENCIES: - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - - react-native-blurhash (from `../node_modules/react-native-blurhash`) - "react-native-cameraroll (from `../node_modules/@react-native-camera-roll/camera-roll`)" - react-native-image-picker (from `../node_modules/react-native-image-picker`) - react-native-ios-context-menu (from `../node_modules/react-native-ios-context-menu`) @@ -527,7 +541,6 @@ DEPENDENCIES: - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)" - - 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`) @@ -539,11 +552,16 @@ DEPENDENCIES: SPEC REPOS: trunk: - fmt + - libaom + - libavif - libevent + - libvmaf - libwebp - MMKV - MMKVCore - SDWebImage + - SDWebImageAVIFCoder + - SDWebImageSVGCoder - SDWebImageWebPCoder - Sentry - Swime @@ -573,6 +591,8 @@ EXTERNAL SOURCES: :path: "../node_modules/expo-crypto/ios" ExpoHaptics: :path: "../node_modules/expo-haptics/ios" + ExpoImage: + :path: "../node_modules/expo-image/ios" ExpoKeepAwake: :path: "../node_modules/expo-keep-awake/ios" ExpoLocalization: @@ -635,8 +655,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/logger" react-native-blur: :path: "../node_modules/@react-native-community/blur" - react-native-blurhash: - :path: "../node_modules/react-native-blurhash" react-native-cameraroll: :path: "../node_modules/@react-native-camera-roll/camera-roll" react-native-image-picker: @@ -689,8 +707,6 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-async-storage/async-storage" RNCClipboard: :path: "../node_modules/@react-native-clipboard/clipboard" - RNFastImage: - :path: "../node_modules/react-native-fast-image" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" RNReanimated: @@ -710,32 +726,36 @@ SPEC CHECKSUMS: boost: a7c83b31436843459a1961bfd74b96033dc77234 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 EXApplication: 034b1c40a8e9fe1bff76a1e511ee90dff64ad834 - EXAV: 4b92292fb107520a25956bea940a94a3bb4911ca - EXConstants: 44f7d347d0432a66f469d0ce1dc4e3a0ca1b8b2d + EXAV: 1242c4c206fc522058a2749019064e979a4c0b76 + EXConstants: 397186c7e312c33eb1ab85fa1f434dc123778136 EXErrorRecovery: ae43433feb0608a64dc5b1c8363b3e7769a9ea24 - EXFileSystem: 60602b6eefa6873f97172c684b7537c9760b50d6 + EXFileSystem: d9fea7fe7a4390a0ef226cac33958de9178388b9 EXFont: 319606bfe48c33b5b5063fb0994afdc496befe80 EXNotifications: babce2a87b7922051354fcfe7a74dd279b7e272a Expo: b9fa98bf260992312ee3c424400819fb9beadafe - ExpoCrypto: 6eb2a5ede7d95b7359a5f0391ee0c5d2ecd144b3 - ExpoHaptics: 129d3f8d44c2205adcdf8db760602818463d5437 + ExpoCrypto: 98c71864077c4d0fe798a6a5aee1a8c1294cef85 + ExpoHaptics: 97c532f311c3e638c14a6134f23564d007b76de4 + ExpoImage: 748f2b8d3974f1d51c7706fd61057b93241738aa ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318 - ExpoLocalization: e202d1e2a4950df17ac8d0889d65a1ffd7532d7e + ExpoLocalization: 28ce7cfa174a752f7ace84189710f1385373655b ExpoModulesCore: 485dff3a59b036a33b6050c0a5aea3cf1037fdd1 - ExpoRandom: 58b7e0a5fe1adf1cb6dc1cbe503a6fe9524f36ce - ExpoStoreReview: 713336ff504db3a6983475bf7c67519cc5efc86f - ExpoVideoThumbnails: 424db02cedfbbe2d498bcb2712ea4ba8a9dcb453 + ExpoRandom: d8fc05d0d071485b06a97ab2a78cb7f8082052cd + ExpoStoreReview: e96ba0690ea21dc5d341cfafd0b26bac7bc974f5 + ExpoVideoThumbnails: 865fa65f2b4f006ff02ef9e3e9c10370d9442d0a ExpoWebBrowser: 073e50f16669d498fb49063b9b7fe780b24f7fda - EXScreenCapture: d9f1ec31042dfef109290d06c2b4789b7444d16d - EXScreenOrientation: 07e5aeff07bce09a2b214981e612d87fd7719997 - EXSecureStore: daec0117c922a67c658cb229152a9e252e5c1750 + EXScreenCapture: bcf94c8199cd1876166e384b2398ff519a8ef7ee + EXScreenOrientation: d43067a93e75234a7ce5154e2759fff2238dbfd5 + EXSecureStore: ec150f49b22269022c6184f1711abb05fe98d72d EXSplashScreen: 3e989924f61a8dd07ee4ea584c6ba14be9b51949 FBLazyVector: a6454570f573a0f6f1d397e5a95c13e8e45d1700 FBReactNativeSpec: 09e8dfba44487e5dc4882a9f5318cde67549549c fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: 566e656aa95456a3f3f739fd76ea9a9656f2633f + libaom: 9bb51e0f8f9192245e3ca2a1c9e4375d9cbccc52 + libavif: e242998ccec1c83bcba0bbdc256f460ad5077348 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 + libvmaf: 8d61aabc2f4ed3e6591cf7406fa00a223ec11289 libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef MMKV: 7f34558bbb5a33b0eaefae2de4b6a20a2ffdad6f MMKVCore: ddf41b9d9262f058419f9ba7598719af56c02cd3 @@ -755,7 +775,6 @@ SPEC CHECKSUMS: React-jsinspector: 1c34fea1868136ecde647bc11fae9266d4143693 React-logger: e9f407f9fdf3f3ce7749ae6f88affe63e8446019 react-native-blur: 50c9feabacbc5f49b61337ebc32192c6be7ec3c3 - react-native-blurhash: add4df9a937b4e021a24bc67a0714f13e0bd40b7 react-native-cameraroll: 5b25d0be40185d02e522bf2abf8a1ba4e8faa107 react-native-image-picker: 8cb4280e2c1efc3daeb2d9d597f9429a60472e40 react-native-ios-context-menu: e529171ba760a1af7f2ef0729f5a7f4d226171c5 @@ -782,7 +801,6 @@ SPEC CHECKSUMS: ReactCommon: 0253d197eaa7f6689dcd3e7d5360449ab93e10df RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60 RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd - RNFastImage: bd611b5635f1e0f43c8ccf597b1ef6ee0d0f966d RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39 RNReanimated: 6668b0587bebd4b15dd849b99e5a9c70fc12ed95 RNScreens: ea4cd3a853063cda19a4e3c28d2e52180c80f4eb @@ -790,6 +808,8 @@ SPEC CHECKSUMS: RNShareMenu: cb9dac548c8bf147d06f0bf07296ad51ea9f5fc3 RNSVG: c1e76b81c76cdcd34b4e1188852892dc280eb902 SDWebImage: 9bec4c5cdd9579e1f57104735ee0c37df274d593 + SDWebImageAVIFCoder: d759e21cf4efb640cc97250566aa556ad8bb877c + SDWebImageSVGCoder: 6fc109f9c2a82ab44510fff410b88b1a6c271ee8 SDWebImageWebPCoder: 18503de6621dd2c420d680e33d46bf8e1d5169b0 Sentry: 4c9babff9034785067c896fd580b1f7de44da020 Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b diff --git a/package.json b/package.json index d602f225..cc378172 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tooot", - "version": "4.8.7", + "version": "4.8.8", "description": "tooot for Mastodon", "author": "xmflsct ", "license": "GPL-3.0-or-later", @@ -50,6 +50,7 @@ "expo-crypto": "^12.1.0", "expo-file-system": "^15.1.1", "expo-haptics": "^12.1.0", + "expo-image": "^1.0.0-beta.6", "expo-linking": "^3.3.0", "expo-localization": "^14.0.0", "expo-notifications": "^0.17.0", @@ -70,14 +71,12 @@ "react-i18next": "^12.1.4", "react-intl": "^6.2.7", "react-native": "^0.70.7", - "react-native-blurhash": "^1.1.10", - "react-native-fast-image": "^8.6.3", "react-native-flash-message": "^0.4.0", "react-native-gesture-handler": "~2.9.0", "react-native-image-picker": "^5.0.1", "react-native-ios-context-menu": "^1.15.3", "react-native-language-detection": "^0.2.2", - "react-native-mmkv": "^2.5.1", + "react-native-mmkv": "~2.5.1", "react-native-pager-view": "^6.1.2", "react-native-quick-base64": "^2.0.5", "react-native-reanimated": "^2.14.4", @@ -116,7 +115,6 @@ }, "packageManager": "yarn@3.3.1", "resolutions": { - "react-native-fast-image@^8.6.3": "patch:react-native-fast-image@npm%3A8.6.3#./.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch", "expo-av@^13.0.2": "patch:expo-av@npm%3A13.0.2#./.yarn/patches/expo-av-npm-13.0.2-7a651776f1.patch", "react-native-share-menu@^6.0.0": "patch:react-native-share-menu@npm%3A6.0.0#./.yarn/patches/react-native-share-menu-npm-6.0.0-f1094c3204.patch", "@types/react-native-share-menu@^5.0.2": "patch:@types/react-native-share-menu@npm%3A5.0.2#./.yarn/patches/@types-react-native-share-menu-npm-5.0.2-373df17ecc.patch", diff --git a/src/App.tsx b/src/App.tsx index 32072655..89748fed 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,6 +11,7 @@ import log from '@utils/startup/log' import netInfo from '@utils/startup/netInfo' import push from '@utils/startup/push' import sentry from '@utils/startup/sentry' +import { GLOBAL } from '@utils/storage' import { getGlobalStorage, setAccount, setGlobalStorage } from '@utils/storage/actions' import { migrateFromAsyncStorage, versionStorageGlobal } from '@utils/storage/migrations/toMMKV' import ThemeManager from '@utils/styles/ThemeManager' @@ -24,10 +25,6 @@ import { enableFreeze } from 'react-native-screens' import i18n from './i18n' import Screens from './screens' -export const GLOBAL: { connect?: boolean } = { - connect: undefined -} - Platform.select({ android: LogBox.ignoreLogs(['Setting a timer for a long period of time']) }) diff --git a/src/components/Account.tsx b/src/components/Account.tsx index da062c03..b0b9fdba 100644 --- a/src/components/Account.tsx +++ b/src/components/Account.tsx @@ -38,7 +38,7 @@ const ComponentAccount: React.FC = ({ account, props, <> = ({ account, additionalActions }) => { }} > { @@ -129,9 +129,7 @@ const EmojisList = () => { }} style={{ padding: StyleConstants.Spacing.S }} > - if blurhash, show before any loading succeed -// original -> load original -// original, remote -> if original failed, then remote -// preview, original -> first show preview, then original -// preview, original, remote -> first show preview, then original, if original failed, then remote +import { Image, ImageSource, ImageStyle } from 'expo-image' +import React, { useState } from 'react' +import { AccessibilityProps, Pressable, StyleProp, View, ViewStyle } from 'react-native' export interface Props { accessibilityLabel?: AccessibilityProps['accessibilityLabel'] accessibilityHint?: AccessibilityProps['accessibilityHint'] hidden?: boolean - uri: { preview?: string; original?: string; remote?: string; static?: string } - blurhash?: string + sources: { + preview?: ImageSource + default?: ImageSource + remote?: ImageSource + static?: ImageSource + blurhash?: string + } dimension?: { width: number; height: number } onPress?: () => void style?: StyleProp - imageStyle?: StyleProp + imageStyle?: ImageStyle // For image viewer when there is no image size available setImageDimensions?: React.Dispatch< React.SetStateAction<{ @@ -39,49 +29,30 @@ export interface Props { }> > dim?: boolean + enableLiveTextInteraction?: boolean } const GracefullyImage = ({ accessibilityLabel, accessibilityHint, hidden = false, - uri, - blurhash, + sources, dimension, onPress, style, imageStyle, setImageDimensions, - dim + dim, + enableLiveTextInteraction = false }: Props) => { const { reduceMotionEnabled } = useAccessibility() - const { colors, theme } = useTheme() - const [imageLoaded, setImageLoaded] = useState(false) + const { theme } = useTheme() - const [currentUri, setCurrentUri] = useState(uri.original || uri.remote) - const source: { uri?: string } = { - uri: reduceMotionEnabled && uri.static ? uri.static : currentUri - } - useEffect(() => { - if ( - (uri.original ? currentUri !== uri.original : true) && - (uri.remote ? currentUri !== uri.remote : true) - ) { - setCurrentUri(uri.original || uri.remote) - } - }, [currentUri, uri.original, uri.remote]) - - const blurhashView = () => { - if (hidden || !imageLoaded) { - if (blurhash) { - return - } else { - return - } - } else { - return null - } - } + const [currentSource, setCurrentSource] = useState( + sources.default || sources.remote + ) + const source: ImageSource | undefined = + reduceMotionEnabled && sources.static ? sources.static : currentSource return ( - {uri.preview && !imageLoaded ? ( - - ) : null} - { - setImageLoaded(true) - if (setImageDimensions && source.uri) { - Image.getSize(source.uri, (width, height) => setImageDimensions({ width, height })) + { + if (setImageDimensions && event.source) { + setImageDimensions(event.source) } }} onError={() => { - if (uri.original && uri.original === currentUri && uri.remote) { - setCurrentUri(uri.remote) + if ( + sources.default?.uri && + sources.default?.uri === currentSource?.uri && + sources.remote + ) { + setCurrentSource(sources.remote) } }} + enableLiveTextInteraction={enableLiveTextInteraction} /> - {blurhashView()} {dim && theme !== 'light' ? ( ) : null} ) } -const styles = StyleSheet.create({ - placeholder: { - width: '100%', - height: '100%', - position: 'absolute' - } -}) - export default GracefullyImage diff --git a/src/components/Instance/index.tsx b/src/components/Instance/index.tsx index efe90d19..d9997133 100644 --- a/src/components/Instance/index.tsx +++ b/src/components/Instance/index.tsx @@ -19,12 +19,13 @@ import { import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import * as AuthSession from 'expo-auth-session' -import * as Random from 'expo-random' +import * as Crypto from 'expo-crypto' +import { Image } from 'expo-image' import * as WebBrowser from 'expo-web-browser' import { debounce } from 'lodash' import React, { RefObject, useCallback, useState } from 'react' import { Trans, useTranslation } from 'react-i18next' -import { Alert, Image, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native' +import { Alert, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native' import { ScrollView } from 'react-native-gesture-handler' import { fromByteArray } from 'react-native-quick-base64' import parse from 'url-parse' @@ -78,7 +79,8 @@ const ComponentInstance: React.FC = ({ clientId, clientSecret, scopes: variables.scopes, - redirectUri + redirectUri, + usePKCE: !['pawoo.net'].includes(domain) }) await request.makeAuthUrlAsync(discovery) @@ -160,7 +162,7 @@ const ComponentInstance: React.FC = ({ 'admin.sign_up': false, 'admin.report': false }, - key: fromByteArray(Random.getRandomBytes(16)) + key: fromByteArray(Crypto.getRandomBytes(16)) }, page_local: { showBoosts: true, @@ -231,7 +233,7 @@ const ComponentInstance: React.FC = ({ ) : null} diff --git a/src/components/Parse/Emojis.tsx b/src/components/Parse/Emojis.tsx index ec5362ff..fd616fbd 100644 --- a/src/components/Parse/Emojis.tsx +++ b/src/components/Parse/Emojis.tsx @@ -5,9 +5,9 @@ import { useGlobalStorage } from '@utils/storage/actions' import { StyleConstants } from '@utils/styles/constants' import { adaptiveScale } from '@utils/styles/scaling' import { useTheme } from '@utils/styles/ThemeManager' +import { Image } from 'expo-image' import React from 'react' import { ColorValue, Platform, TextStyle } from 'react-native' -import FastImage from 'react-native-fast-image' const regexEmoji = new RegExp(/(:[A-Za-z0-9_]+:)/) @@ -77,8 +77,8 @@ const ParseEmojis: React.FC = ({ return ( {i === 0 ? ' ' : undefined} - = ({ conversation, queryKey, highlig {conversation.accounts.slice(0, 4).map(account => ( = ({ const { colors } = useTheme() const navigation = useNavigation>() - const [accountId] = useAccountStorage.string('auth.account.id') const { data: preferences } = usePreferencesQuery() - const ownAccount = status.account?.id === accountId + const isMyAccount = checkIsMyAccount(status.account.id) const [spoilerExpanded, setSpoilerExpanded] = useState( preferences?.['reading:expand:spoilers'] || false ) @@ -136,7 +135,7 @@ const TimelineDefault: React.FC = ({ const mStatus = menuStatus({ status, queryKey }) const mInstance = menuInstance({ status, queryKey }) - if (!ownAccount) { + if (!isMyAccount) { let filterResults: FilteredProps['filterResults'] = [] const [filterRevealed, setFilterRevealed] = useState(false) const hasFilterServerSide = featureCheck('filter_server_side') @@ -166,7 +165,7 @@ const TimelineDefault: React.FC = ({ value={{ queryKey, status, - ownAccount, + isMyAccount, spoilerHidden, rawContent, detectedLanguage, diff --git a/src/components/Timeline/Notifications.tsx b/src/components/Timeline/Notifications.tsx index 8f2ad75f..2c7f4892 100644 --- a/src/components/Timeline/Notifications.tsx +++ b/src/components/Timeline/Notifications.tsx @@ -12,10 +12,10 @@ import TimelinePoll from '@components/Timeline/Shared/Poll' import { useNavigation } from '@react-navigation/native' import { StackNavigationProp } from '@react-navigation/stack' import { featureCheck } from '@utils/helpers/featureCheck' +import { checkIsMyAccount } from '@utils/helpers/isMyAccount' import { TabLocalStackParamList } from '@utils/navigation/navigators' import { usePreferencesQuery } from '@utils/queryHooks/preferences' import { QueryKeyTimeline } from '@utils/queryHooks/timeline' -import { useAccountStorage } from '@utils/storage/actions' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import React, { Fragment, useState } from 'react' @@ -32,7 +32,6 @@ export interface Props { } const TimelineNotifications: React.FC = ({ notification, queryKey }) => { - const [accountId] = useAccountStorage.string('auth.account.id') const { data: preferences } = usePreferencesQuery() const status = notification.status?.reblog ? notification.status.reblog : notification.status @@ -42,7 +41,7 @@ const TimelineNotifications: React.FC = ({ notification, queryKey }) => { : notification.status ? notification.status.account : notification.account - const ownAccount = notification.account?.id === accountId + const isMyAccount = checkIsMyAccount(notification.account?.id) const [spoilerExpanded, setSpoilerExpanded] = useState( preferences?.['reading:expand:spoilers'] || false ) @@ -109,7 +108,7 @@ const TimelineNotifications: React.FC = ({ notification, queryKey }) => { const mStatus = menuStatus({ status: notification.status, queryKey }) const mInstance = menuInstance({ status: notification.status, queryKey }) - if (!ownAccount) { + if (!isMyAccount) { let filterResults: FilteredProps['filterResults'] = [] const [filterRevealed, setFilterRevealed] = useState(false) const hasFilterServerSide = featureCheck('filter_server_side') @@ -140,7 +139,7 @@ const TimelineNotifications: React.FC = ({ notification, queryKey }) => { value={{ queryKey, status, - ownAccount, + isMyAccount, spoilerHidden }} > diff --git a/src/components/Timeline/Shared/Actions.tsx b/src/components/Timeline/Shared/Actions.tsx index ec3dfdb7..3178e62a 100644 --- a/src/components/Timeline/Shared/Actions.tsx +++ b/src/components/Timeline/Shared/Actions.tsx @@ -22,7 +22,7 @@ import { Pressable, StyleSheet, View } from 'react-native' import StatusContext from './Context' const TimelineActions: React.FC = () => { - const { queryKey, status, ownAccount, highlighted, disableDetails } = useContext(StatusContext) + const { queryKey, status, isMyAccount, highlighted, disableDetails } = useContext(StatusContext) if (!queryKey || !status || disableDetails) return null const navigationState = useNavState() @@ -182,7 +182,7 @@ const TimelineActions: React.FC = () => { const childrenReblog = () => { const color = (state: boolean) => (state ? colors.green : colors.secondary) const disabled = - status.visibility === 'direct' || (status.visibility === 'private' && !ownAccount) + status.visibility === 'direct' || (status.visibility === 'private' && !isMyAccount) return ( <> { fontStyle='S' style={{ color: - status.visibility === 'private' && !ownAccount + status.visibility === 'private' && !isMyAccount ? colors.disabled : color(status.reblogged), marginLeft: StyleConstants.Spacing.XS @@ -258,7 +258,7 @@ const TimelineActions: React.FC = () => { onPress={onPressReblog} children={childrenReblog()} disabled={ - status.visibility === 'direct' || (status.visibility === 'private' && !ownAccount) + status.visibility === 'direct' || (status.visibility === 'private' && !isMyAccount) } /> diff --git a/src/components/Timeline/Shared/Attachment.tsx b/src/components/Timeline/Shared/Attachment.tsx index 73a181d1..a10fb3dd 100644 --- a/src/components/Timeline/Shared/Attachment.tsx +++ b/src/components/Timeline/Shared/Attachment.tsx @@ -9,7 +9,6 @@ import { StackNavigationProp } from '@react-navigation/stack' import { RootStackParamList } from '@utils/navigation/navigators' import { usePreferencesQuery } from '@utils/queryHooks/preferences' import { StyleConstants } from '@utils/styles/constants' -import layoutAnimation from '@utils/styles/layoutAnimation' import React, { useContext, useState } from 'react' import { useTranslation } from 'react-i18next' import { Pressable, View } from 'react-native' @@ -207,7 +206,6 @@ const TimelineAttachment = () => { content={t('shared.attachment.sensitive.button')} overlay onPress={() => { - layoutAnimation() setSensitiveShown(false) haptics('Light') }} diff --git a/src/components/Timeline/Shared/Attachment/Audio.tsx b/src/components/Timeline/Shared/Attachment/Audio.tsx index 18970ede..ca78968d 100644 --- a/src/components/Timeline/Shared/Attachment/Audio.tsx +++ b/src/components/Timeline/Shared/Attachment/Audio.tsx @@ -7,7 +7,6 @@ import { useTheme } from '@utils/styles/ThemeManager' import { Audio } from 'expo-av' import React, { useCallback, useEffect, useRef, useState } from 'react' import { AppState, AppStateStatus, StyleSheet, View } from 'react-native' -import { Blurhash } from 'react-native-blurhash' import AttachmentAltText from './AltText' import { aspectRatio } from './dimensions' @@ -72,19 +71,23 @@ const AttachmentAudio: React.FC = ({ total, index, sensitiveShown, audio {sensitiveShown ? ( audio.blurhash ? ( - ) : null ) : ( <> {audio.preview_url ? ( diff --git a/src/components/Timeline/Shared/Attachment/Image.tsx b/src/components/Timeline/Shared/Attachment/Image.tsx index 902bfcce..55cfdabb 100644 --- a/src/components/Timeline/Shared/Attachment/Image.tsx +++ b/src/components/Timeline/Shared/Attachment/Image.tsx @@ -35,8 +35,11 @@ const AttachmentImage = ({