mirror of
https://github.com/tooot-app/app
synced 2025-01-21 05:20:10 +01:00
Test #700
This commit is contained in:
parent
9259ee2995
commit
d1ed8a0d2a
@ -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<String, FastImageEnterTransition> FAST_IMAGE_ENTER_TRANSITION_MAP =
|
||||
+ new HashMap<String, FastImageEnterTransition>() {{
|
||||
+ 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<FastImageViewWithUrl> 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 <React/RCTResizeMode.h>
|
||||
|
||||
#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 <React/RCTViewManager.h>
|
||||
|
||||
+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;
|
@ -22,6 +22,12 @@ PODS:
|
||||
- ExpoModulesCore
|
||||
- ExpoHaptics (12.1.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):
|
||||
@ -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:
|
||||
@ -719,6 +735,7 @@ SPEC CHECKSUMS:
|
||||
Expo: b9fa98bf260992312ee3c424400819fb9beadafe
|
||||
ExpoCrypto: 6eb2a5ede7d95b7359a5f0391ee0c5d2ecd144b3
|
||||
ExpoHaptics: 129d3f8d44c2205adcdf8db760602818463d5437
|
||||
ExpoImage: 748f2b8d3974f1d51c7706fd61057b93241738aa
|
||||
ExpoKeepAwake: 69b59d0a8d2b24de9f82759c39b3821fec030318
|
||||
ExpoLocalization: e202d1e2a4950df17ac8d0889d65a1ffd7532d7e
|
||||
ExpoModulesCore: 485dff3a59b036a33b6050c0a5aea3cf1037fdd1
|
||||
@ -735,7 +752,10 @@ SPEC CHECKSUMS:
|
||||
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
|
||||
|
@ -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,8 +71,6 @@
|
||||
"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",
|
||||
@ -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",
|
||||
|
@ -38,7 +38,7 @@ const ComponentAccount: React.FC<PropsWithChildren & Props> = ({ account, props,
|
||||
<>
|
||||
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center' }}>
|
||||
<GracefullyImage
|
||||
uri={{ original: account.avatar, static: account.avatar_static }}
|
||||
sources={{ default: { uri: account.avatar }, static: { uri: account.avatar_static } }}
|
||||
style={{
|
||||
width: StyleConstants.Avatar.S,
|
||||
height: StyleConstants.Avatar.S,
|
||||
|
@ -40,7 +40,7 @@ const AccountButton: React.FC<Props> = ({ account, additionalActions }) => {
|
||||
}}
|
||||
>
|
||||
<GracefullyImage
|
||||
uri={{ original: account.avatar_static }}
|
||||
sources={{ default: { uri: account.avatar_static } }}
|
||||
dimension={{
|
||||
width: StyleConstants.Font.Size.L,
|
||||
height: StyleConstants.Font.Size.L
|
||||
|
@ -8,6 +8,7 @@ import { getAccountStorage, setAccountStorage } from '@utils/storage/actions'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import layoutAnimation from '@utils/styles/layoutAnimation'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { Image } from 'expo-image'
|
||||
import { chunk } from 'lodash'
|
||||
import React, { useContext, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -19,7 +20,6 @@ import {
|
||||
TextInput,
|
||||
View
|
||||
} from 'react-native'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import EmojisContext from './Context'
|
||||
|
||||
const EmojisList = () => {
|
||||
@ -129,9 +129,7 @@ const EmojisList = () => {
|
||||
}}
|
||||
style={{ padding: StyleConstants.Spacing.S }}
|
||||
>
|
||||
<FastImage
|
||||
enterTransition='fadeIn'
|
||||
transitionDuration={60}
|
||||
<Image
|
||||
accessibilityLabel={t('common:customEmoji.accessibilityLabel', {
|
||||
emoji: emoji.shortcode
|
||||
})}
|
||||
|
@ -1,36 +1,26 @@
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { connectMedia } from '@utils/api/helpers/connect'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import {
|
||||
AccessibilityProps,
|
||||
Image,
|
||||
Pressable,
|
||||
StyleProp,
|
||||
StyleSheet,
|
||||
View,
|
||||
ViewStyle
|
||||
} from 'react-native'
|
||||
import { Blurhash } from 'react-native-blurhash'
|
||||
import FastImage, { ImageStyle } from 'react-native-fast-image'
|
||||
|
||||
// blurhas -> 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<ViewStyle>
|
||||
imageStyle?: StyleProp<ImageStyle>
|
||||
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<string | undefined>(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 <Blurhash decodeAsync blurhash={blurhash} style={styles.placeholder} />
|
||||
} else {
|
||||
return <View style={[styles.placeholder, { backgroundColor: colors.shimmerDefault }]} />
|
||||
}
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
const [currentSource, setCurrentSource] = useState<ImageSource | undefined>(
|
||||
sources.default || sources.remote
|
||||
)
|
||||
const source: ImageSource | undefined =
|
||||
reduceMotionEnabled && sources.static ? sources.static : currentSource
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
@ -91,50 +62,40 @@ const GracefullyImage = ({
|
||||
style={[style, dimension]}
|
||||
{...(onPress ? (hidden ? { disabled: true } : { onPress }) : { disabled: true })}
|
||||
>
|
||||
{uri.preview && !imageLoaded ? (
|
||||
<FastImage
|
||||
source={connectMedia({ uri: uri.preview })}
|
||||
enterTransition='fadeIn'
|
||||
transitionDuration={60}
|
||||
style={[styles.placeholder]}
|
||||
/>
|
||||
) : null}
|
||||
<FastImage
|
||||
source={connectMedia(source)}
|
||||
enterTransition={!blurhash && !uri.preview ? 'fadeIn' : 'none'}
|
||||
transitionDuration={60}
|
||||
style={[{ flex: 1 }, imageStyle]}
|
||||
onLoad={() => {
|
||||
setImageLoaded(true)
|
||||
if (setImageDimensions && source.uri) {
|
||||
Image.getSize(source.uri, (width, height) => setImageDimensions({ width, height }))
|
||||
<Image
|
||||
placeholder={sources.blurhash || connectMedia(sources.preview)}
|
||||
source={hidden ? undefined : connectMedia(source)}
|
||||
transition={{ duration: 100 }}
|
||||
style={{ flex: 1, ...imageStyle }}
|
||||
onLoad={event => {
|
||||
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' ? (
|
||||
<View
|
||||
style={[
|
||||
styles.placeholder,
|
||||
{ backgroundColor: 'black', opacity: theme === 'dark_lighter' ? 0.18 : 0.36 }
|
||||
]}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
backgroundColor: 'black',
|
||||
opacity: theme === 'dark_lighter' ? 0.18 : 0.36
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</Pressable>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
placeholder: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'absolute'
|
||||
}
|
||||
})
|
||||
|
||||
export default GracefullyImage
|
||||
|
@ -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 { Image } from 'expo-image'
|
||||
import * as Random from 'expo-random'
|
||||
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'
|
||||
|
@ -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<Props> = ({
|
||||
return (
|
||||
<CustomText key={emojiShortcode + i}>
|
||||
{i === 0 ? ' ' : undefined}
|
||||
<FastImage
|
||||
source={connectMedia({ uri: uri.trim() })}
|
||||
<Image
|
||||
source={connectMedia({ uri })}
|
||||
style={{
|
||||
width: adaptedFontsize,
|
||||
height: adaptedFontsize,
|
||||
|
@ -79,7 +79,10 @@ const TimelineConversation: React.FC<Props> = ({ conversation, queryKey, highlig
|
||||
{conversation.accounts.slice(0, 4).map(account => (
|
||||
<GracefullyImage
|
||||
key={account.id}
|
||||
uri={{ original: account.avatar, static: account.avatar_static }}
|
||||
sources={{
|
||||
default: { uri: account.avatar },
|
||||
static: { uri: account.avatar_static }
|
||||
}}
|
||||
dimension={{
|
||||
width: StyleConstants.Avatar.M,
|
||||
height:
|
||||
|
@ -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')
|
||||
}}
|
||||
|
@ -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<Props> = ({ total, index, sensitiveShown, audio
|
||||
<View style={styles.overlay}>
|
||||
{sensitiveShown ? (
|
||||
audio.blurhash ? (
|
||||
<Blurhash
|
||||
blurhash={audio.blurhash}
|
||||
<GracefullyImage
|
||||
sources={{ blurhash: audio.blurhash }}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
}}
|
||||
dim
|
||||
/>
|
||||
) : null
|
||||
) : (
|
||||
<>
|
||||
{audio.preview_url ? (
|
||||
<GracefullyImage
|
||||
uri={{ original: audio.preview_url, remote: audio.preview_remote_url }}
|
||||
sources={{
|
||||
default: { uri: audio.preview_url },
|
||||
remote: { uri: audio.preview_remote_url }
|
||||
}}
|
||||
style={styles.background}
|
||||
dim
|
||||
/>
|
||||
|
@ -35,8 +35,11 @@ const AttachmentImage = ({
|
||||
<GracefullyImage
|
||||
accessibilityLabel={image.description}
|
||||
hidden={sensitiveShown}
|
||||
uri={{ original: image.preview_url, remote: image.remote_url }}
|
||||
blurhash={image.blurhash}
|
||||
sources={{
|
||||
default: { uri: image.preview_url },
|
||||
remote: { uri: image.remote_url },
|
||||
blurhash: image.blurhash
|
||||
}}
|
||||
onPress={() => navigateToImagesViewer(image.id)}
|
||||
style={{ aspectRatio: aspectRatio({ total, index, ...image.meta?.original }) }}
|
||||
dim
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Button from '@components/Button'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import openLink from '@components/openLink'
|
||||
import CustomText from '@components/Text'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
@ -6,7 +7,6 @@ import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { View } from 'react-native'
|
||||
import { Blurhash } from 'react-native-blurhash'
|
||||
import AttachmentAltText from './AltText'
|
||||
import { aspectRatio } from './dimensions'
|
||||
|
||||
@ -33,8 +33,8 @@ const AttachmentUnsupported: React.FC<Props> = ({ total, index, sensitiveShown,
|
||||
}}
|
||||
>
|
||||
{attachment.blurhash ? (
|
||||
<Blurhash
|
||||
blurhash={attachment.blurhash}
|
||||
<GracefullyImage
|
||||
sources={{ blurhash: attachment.blurhash }}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Button from '@components/Button'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { connectMedia } from '@utils/api/helpers/connect'
|
||||
import { useAccountStorage, useGlobalStorage } from '@utils/storage/actions'
|
||||
@ -8,7 +9,6 @@ import { Platform } from 'expo-modules-core'
|
||||
import * as ScreenOrientation from 'expo-screen-orientation'
|
||||
import React, { useRef, useState } from 'react'
|
||||
import { Pressable, View } from 'react-native'
|
||||
import { Blurhash } from 'react-native-blurhash'
|
||||
import AttachmentAltText from './AltText'
|
||||
import { aspectRatio } from './dimensions'
|
||||
|
||||
@ -120,7 +120,10 @@ const AttachmentVideo: React.FC<Props> = ({
|
||||
>
|
||||
{sensitiveShown ? (
|
||||
video.blurhash ? (
|
||||
<Blurhash blurhash={video.blurhash} style={{ width: '100%', height: '100%' }} />
|
||||
<GracefullyImage
|
||||
sources={{ blurhash: video.blurhash }}
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
/>
|
||||
) : null
|
||||
) : !gifv || (gifv && (reduceMotionEnabled || !shouldAutoplayGifv)) ? (
|
||||
<Button
|
||||
|
@ -33,7 +33,10 @@ const TimelineAvatar: React.FC<Props> = ({ account }) => {
|
||||
onPress={() =>
|
||||
!disableOnPress && navigation.push('Tab-Shared-Account', { account: actualAccount })
|
||||
}
|
||||
uri={{ original: actualAccount.avatar, static: actualAccount.avatar_static }}
|
||||
sources={{
|
||||
default: { uri: actualAccount.avatar },
|
||||
static: { uri: actualAccount.avatar_static }
|
||||
}}
|
||||
dimension={
|
||||
disableDetails || isConversation
|
||||
? {
|
||||
|
@ -82,8 +82,7 @@ const TimelineCard: React.FC = () => {
|
||||
<>
|
||||
{status.card?.image ? (
|
||||
<GracefullyImage
|
||||
uri={{ original: status.card.image }}
|
||||
blurhash={status.card.blurhash}
|
||||
sources={{ default: { uri: status.card.image }, blurhash: status.card.blurhash }}
|
||||
style={{ flexBasis: StyleConstants.Font.LineHeight.M * 5 }}
|
||||
imageStyle={{ borderTopLeftRadius: 6, borderBottomLeftRadius: 6 }}
|
||||
dim
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Button from '@components/Button'
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import haptics from '@components/haptics'
|
||||
import { Loading } from '@components/Loading'
|
||||
import { ParseHTML } from '@components/Parse'
|
||||
@ -6,7 +7,6 @@ import RelativeTime from '@components/RelativeTime'
|
||||
import CustomText from '@components/Text'
|
||||
import { BlurView } from '@react-native-community/blur'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { connectMedia } from '@utils/api/helpers/connect'
|
||||
import { RootStackScreenProps } from '@utils/navigation/navigators'
|
||||
import { useAnnouncementMutation, useAnnouncementQuery } from '@utils/queryHooks/announcement'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
@ -22,7 +22,6 @@ import {
|
||||
StyleSheet,
|
||||
View
|
||||
} from 'react-native'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import { FlatList, ScrollView } from 'react-native-gesture-handler'
|
||||
import { SafeAreaView } from 'react-native-safe-area-context'
|
||||
|
||||
@ -139,12 +138,13 @@ const ScreenAnnouncements: React.FC<RootStackScreenProps<'Screen-Announcements'>
|
||||
}
|
||||
>
|
||||
{reaction.url ? (
|
||||
<FastImage
|
||||
source={connectMedia({
|
||||
uri: reduceMotionEnabled ? reaction.static_url : reaction.url
|
||||
})}
|
||||
style={{
|
||||
width: StyleConstants.Font.LineHeight.M + 3,
|
||||
<GracefullyImage
|
||||
sources={{
|
||||
default: { uri: reaction.url },
|
||||
static: { uri: reaction.static_url }
|
||||
}}
|
||||
dimension={{
|
||||
width: StyleConstants.Font.LineHeight.M,
|
||||
height: StyleConstants.Font.LineHeight.M
|
||||
}}
|
||||
/>
|
||||
|
@ -9,10 +9,10 @@ import { ScreenComposeStackScreenProps } from '@utils/navigation/navigators'
|
||||
import { getAccountStorage, setAccountStorage, useAccountStorage } from '@utils/storage/actions'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { Image } from 'expo-image'
|
||||
import React, { useContext, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Dimensions, Modal, Pressable, View } from 'react-native'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import ComposeContext from './utils/createContext'
|
||||
import { formatText } from './utils/processText'
|
||||
import { ComposeStateDraft, ExtendedAttachment } from './utils/types'
|
||||
@ -140,7 +140,7 @@ const ComposeDraftsList: React.FC<ScreenComposeStackScreenProps<'Screen-Compose-
|
||||
}}
|
||||
>
|
||||
{item.attachments.uploads.map((attachment, index) => (
|
||||
<FastImage
|
||||
<Image
|
||||
key={index}
|
||||
style={{
|
||||
width:
|
||||
|
@ -11,10 +11,10 @@ import { featureCheck } from '@utils/helpers/featureCheck'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import layoutAnimation from '@utils/styles/layoutAnimation'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { Image } from 'expo-image'
|
||||
import React, { RefObject, useContext, useEffect, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FlatList, Pressable, StyleSheet, View } from 'react-native'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import ComposeContext from '../../utils/createContext'
|
||||
import { ExtendedAttachment } from '../../utils/types'
|
||||
import chooseAndUploadAttachment from './addAttachment'
|
||||
@ -104,9 +104,7 @@ const ComposeAttachments: React.FC<Props> = ({ accessibleRefAttachments }) => {
|
||||
width: calculateWidth(item)
|
||||
}}
|
||||
>
|
||||
<FastImage
|
||||
enterTransition='fadeIn'
|
||||
transitionDuration={60}
|
||||
<Image
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
source={
|
||||
item.local?.thumbnail
|
||||
|
@ -193,10 +193,10 @@ const ScreenImagesViewer = ({
|
||||
}}
|
||||
>
|
||||
<GracefullyImage
|
||||
uri={{
|
||||
preview: item.preview_url,
|
||||
remote: item.remote_url,
|
||||
original: item.url
|
||||
sources={{
|
||||
preview: { uri: item.preview_url, width: item.width, height: item.height },
|
||||
default: { uri: item.url, width: item.width, height: item.height },
|
||||
remote: { uri: item.remote_url, width: item.width, height: item.height }
|
||||
}}
|
||||
dimension={{
|
||||
width:
|
||||
@ -208,6 +208,7 @@ const ScreenImagesViewer = ({
|
||||
? WINDOW_HEIGHT
|
||||
: (WINDOW_WIDTH / imageWidth) * imageHeight
|
||||
}}
|
||||
enableLiveTextInteraction
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
|
@ -82,15 +82,25 @@ const AccountAttachments: React.FC = () => {
|
||||
} else {
|
||||
return (
|
||||
<GracefullyImage
|
||||
uri={{
|
||||
original:
|
||||
item.media_attachments[0]?.preview_url || item.media_attachments[0]?.url,
|
||||
remote: item.media_attachments[0]?.remote_url
|
||||
sources={{
|
||||
preview: {
|
||||
uri: item.media_attachments[0]?.preview_url,
|
||||
width: item.media_attachments[0]?.meta?.small?.width,
|
||||
height: item.media_attachments[0]?.meta?.small?.height
|
||||
},
|
||||
default: {
|
||||
uri: item.media_attachments[0]?.url,
|
||||
width: item.media_attachments[0]?.meta?.original?.width,
|
||||
height: item.media_attachments[0]?.meta?.original?.height
|
||||
},
|
||||
remote: {
|
||||
uri: item.media_attachments[0]?.remote_url,
|
||||
width: item.media_attachments[0]?.meta?.original?.width,
|
||||
height: item.media_attachments[0]?.meta?.original?.height
|
||||
},
|
||||
blurhash: item.media_attachments[0]?.blurhash
|
||||
}}
|
||||
blurhash={
|
||||
item.media_attachments[0] && (item.media_attachments[0].blurhash || undefined)
|
||||
}
|
||||
dimension={{ width: width, height: width }}
|
||||
dimension={{ width, height: width }}
|
||||
style={{ marginLeft: StyleConstants.Spacing.Global.PagePadding }}
|
||||
onPress={() => navigation.push('Tab-Shared-Toot', { toot: item })}
|
||||
dim
|
||||
|
@ -1,6 +1,5 @@
|
||||
import GracefullyImage from '@components/GracefullyImage'
|
||||
import navigationRef from '@utils/navigation/navigationRef'
|
||||
import { useGlobalStorage } from '@utils/storage/actions'
|
||||
import React, { useContext } from 'react'
|
||||
import { Dimensions, Image } from 'react-native'
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
||||
@ -11,11 +10,9 @@ const AccountHeader: React.FC = () => {
|
||||
|
||||
const topInset = useSafeAreaInsets().top
|
||||
|
||||
useGlobalStorage.string('account.active')
|
||||
|
||||
return (
|
||||
<GracefullyImage
|
||||
uri={{ original: account?.header, static: account?.header_static }}
|
||||
sources={{ default: { uri: account?.header }, static: { uri: account?.header_static } }}
|
||||
style={{ height: Dimensions.get('window').width / 3 + topInset }}
|
||||
onPress={() => {
|
||||
if (account) {
|
||||
|
@ -3,7 +3,6 @@ import { useNavigation } from '@react-navigation/native'
|
||||
import { StackNavigationProp } from '@react-navigation/stack'
|
||||
import navigationRef from '@utils/navigation/navigationRef'
|
||||
import { TabLocalStackParamList } from '@utils/navigation/navigators'
|
||||
import { useAccountStorage } from '@utils/storage/actions'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import React, { useContext } from 'react'
|
||||
import AccountContext from '../Context'
|
||||
@ -13,20 +12,13 @@ const AccountInformationAvatar: React.FC = () => {
|
||||
|
||||
const navigation = useNavigation<StackNavigationProp<TabLocalStackParamList>>()
|
||||
|
||||
const [accountAvatarStatic] = useAccountStorage.string('auth.account.avatar_static')
|
||||
|
||||
return (
|
||||
<GracefullyImage
|
||||
key={account?.avatar}
|
||||
style={{
|
||||
borderRadius: 8,
|
||||
overflow: 'hidden',
|
||||
width: StyleConstants.Avatar.L,
|
||||
height: StyleConstants.Avatar.L
|
||||
}}
|
||||
uri={{
|
||||
original: account?.avatar || (pageMe ? accountAvatarStatic : undefined),
|
||||
static: account?.avatar_static || (pageMe ? accountAvatarStatic : undefined)
|
||||
style={{ borderRadius: 8, overflow: 'hidden' }}
|
||||
dimension={{ width: StyleConstants.Avatar.L, height: StyleConstants.Avatar.L }}
|
||||
sources={{
|
||||
default: { uri: account?.avatar },
|
||||
static: { uri: account?.avatar_static }
|
||||
}}
|
||||
onPress={() => {
|
||||
if (account) {
|
||||
|
@ -52,7 +52,7 @@ const ScreenTabs = () => {
|
||||
return (
|
||||
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
|
||||
<GracefullyImage
|
||||
uri={{ original: avatarStatic }}
|
||||
sources={{ default: { uri: avatarStatic } }}
|
||||
dimension={{ width: size, height: size }}
|
||||
style={{
|
||||
borderRadius: size,
|
||||
|
@ -81,19 +81,18 @@ export const CONNECT_DOMAIN = (index?: number) =>
|
||||
development: 'connect-development.tooot.app'
|
||||
})
|
||||
|
||||
export const connectMedia = ({
|
||||
uri
|
||||
}: {
|
||||
export const connectMedia = (args?: {
|
||||
uri?: string
|
||||
}): { uri?: string; headers?: { 'x-tooot-domain': string } } => {
|
||||
if (GLOBAL.connect) {
|
||||
if (uri) {
|
||||
const host = parse(uri).host
|
||||
if (args?.uri) {
|
||||
const host = parse(args.uri).host
|
||||
return {
|
||||
uri: uri.replace(
|
||||
...args,
|
||||
uri: args.uri.replace(
|
||||
host,
|
||||
CONNECT_DOMAIN(
|
||||
uri
|
||||
args.uri
|
||||
.split('')
|
||||
.map(i => i.charCodeAt(0))
|
||||
.reduce((a, b) => a + b, 0) %
|
||||
@ -103,10 +102,10 @@ export const connectMedia = ({
|
||||
headers: { 'x-tooot-domain': host }
|
||||
}
|
||||
} else {
|
||||
return { uri }
|
||||
return { ...args }
|
||||
}
|
||||
} else {
|
||||
return { uri }
|
||||
return { ...args }
|
||||
}
|
||||
}
|
||||
|
||||
|
31
yarn.lock
31
yarn.lock
@ -5706,6 +5706,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-image@npm:^1.0.0-beta.6":
|
||||
version: 1.0.0-beta.6
|
||||
resolution: "expo-image@npm:1.0.0-beta.6"
|
||||
peerDependencies:
|
||||
expo: "*"
|
||||
checksum: d874d6779db813166a682be6f4c4ee3e101be90121376963946db85bcbef71f50bc027b18d5e07b4ca6a03337597a60df2cc2cfed66661149ec7cf53d6b6bae9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-keep-awake@npm:~11.0.1":
|
||||
version: 11.0.1
|
||||
resolution: "expo-keep-awake@npm:11.0.1"
|
||||
@ -9639,26 +9648,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-native-fast-image@npm:8.6.3":
|
||||
version: 8.6.3
|
||||
resolution: "react-native-fast-image@npm:8.6.3"
|
||||
peerDependencies:
|
||||
react: ^17 || ^18
|
||||
react-native: ">=0.60.0"
|
||||
checksum: 29289cb6b2eae0983c8922b22e2d9de3be07322bb7991c5def19f95eadefaedb0e308ff0b38cc1d0444e8bd4fe94a7621a99a2d3d9298100bcb60b3144677234
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-native-fast-image@patch:react-native-fast-image@npm%3A8.6.3#./.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch::locator=tooot%40workspace%3A.":
|
||||
version: 8.6.3
|
||||
resolution: "react-native-fast-image@patch:react-native-fast-image@npm%3A8.6.3#./.yarn/patches/react-native-fast-image-npm-8.6.3-03ee2d23c0.patch::version=8.6.3&hash=1a9a6d&locator=tooot%40workspace%3A."
|
||||
peerDependencies:
|
||||
react: ^17 || ^18
|
||||
react-native: ">=0.60.0"
|
||||
checksum: 4b2c6b2d6fc461f26936ff5033acccf7aef15f9d176ea835d09c87bee83accbb6c2b98a2435ad019a305c0751aa43040c153a6d5735664ace31e64aad0b2bc61
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-native-flash-message@npm:^0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "react-native-flash-message@npm:0.4.0"
|
||||
@ -11432,6 +11421,7 @@ __metadata:
|
||||
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
|
||||