From f538c307c0cce2d4e35a5fe9f671e502c3a11905 Mon Sep 17 00:00:00 2001 From: sieu-db <159281348+sieu-db@users.noreply.github.com> Date: Wed, 4 Dec 2024 13:49:03 +0700 Subject: [PATCH] Support expo image - Expo 51 (#973) * support expo image * update yarn lock * remove duplicate style of expo image * update example --- example/src/App.tsx | 2 + example/src/ExpoImageExample.tsx | 158 +++++++++++++++++++++ packages/core/package.json | 1 + packages/core/src/components/ExpoImage.tsx | 86 +++++++++++ packages/core/src/index.tsx | 1 + packages/ui/src/index.tsx | 1 + yarn.lock | 5 + 7 files changed, 254 insertions(+) create mode 100644 example/src/ExpoImageExample.tsx create mode 100644 packages/core/src/components/ExpoImage.tsx diff --git a/example/src/App.tsx b/example/src/App.tsx index 1a901a43d..af365bf2b 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -76,6 +76,7 @@ import ThemeExample from "./ThemeExample"; import LoadingIndicatorExample from "./LoadingIndicatorExample"; import TimerExample from "./TimerExample"; import LottieAnimationExample from "./LottieAnimationExample"; +import ExpoImageExample from "./ExpoImageExample"; const ROUTES = { LottieAnimationExample: LottieAnimationExample, @@ -120,6 +121,7 @@ const ROUTES = { VideoPlayer: VideoPlayerExample, PinInput: PinInputExample, KeyboardAvoidingView: KeyboardAvoidingViewExample, + ExpoImage: ExpoImageExample, }; const customFonts = { diff --git a/example/src/ExpoImageExample.tsx b/example/src/ExpoImageExample.tsx new file mode 100644 index 000000000..06259b8ad --- /dev/null +++ b/example/src/ExpoImageExample.tsx @@ -0,0 +1,158 @@ +import * as React from "react"; +import { View, StyleSheet, Text } from "react-native"; +import { ExpoImage, withTheme } from "@draftbit/ui"; +import Section, { Container } from "./Section"; + +interface WrapperProps { + label: string; + children: React.ReactNode; +} + +const Wrapper: React.FC = ({ label, children }) => { + return ( + + + {label} + + {children} + + ); +}; + +const ExpoImageExample: React.FC = () => { + return ( + +
+ + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
+ + + + + + + + + + + + + + +
+
+ ); +}; + +const styles = StyleSheet.create({ + wrapper: { + flex: 1, + display: "flex", + flexDirection: "column", + flexWrap: "wrap", + justifyContent: "center", + alignItems: "center", + }, + boxLabel: { + margin: 10, + flex: 1, + }, +}); + +export default withTheme(ExpoImageExample); diff --git a/packages/core/package.json b/packages/core/package.json index 1ac178a0c..bc99a65ea 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -56,6 +56,7 @@ "date-fns": "^4.1.0", "dateformat": "^5.0.3", "expo-av": "~14.0.7", + "expo-image": "~1.13.0", "lodash.isequal": "^4.5.0", "lodash.isnumber": "^3.0.3", "lodash.omit": "^4.5.0", diff --git a/packages/core/src/components/ExpoImage.tsx b/packages/core/src/components/ExpoImage.tsx new file mode 100644 index 000000000..c65f6cd5f --- /dev/null +++ b/packages/core/src/components/ExpoImage.tsx @@ -0,0 +1,86 @@ +import React from "react"; +import { + Image, + ImageContentPosition, + ImageProps as ExpoImageProps, + ImageContentFit, +} from "expo-image"; +import Config from "./Config"; + +interface ExtendedImageProps extends ExpoImageProps { + transitionDuration?: number; + transitionEffect?: + | "cross-dissolve" + | "flip-from-top" + | "flip-from-right" + | "flip-from-bottom" + | "flip-from-left" + | "curl-up" + | "curl-down"; + transitionTiming?: "ease-in-out" | "ease-in" | "ease-out" | "linear"; + contentFit?: "cover" | "contain" | "fill" | "none" | "scale-down"; + contentPosition?: ImageContentPosition; + cachePolicy?: "none" | "disk" | "memory" | "memory-disk"; + allowDownscaling?: boolean; + blurRadius?: number; + blurhash?: string; +} + +const resizeModeToContentFit = ( + resizeMode: "cover" | "contain" | "stretch" | "repeat" | "center" +): ImageContentFit => { + const mapping: Record = { + cover: "cover", + contain: "contain", + stretch: "fill", + repeat: "none", + center: "scale-down", + } as const; + return mapping[resizeMode] ?? "cover"; +}; + +const ExpoImage: React.FC = ({ + source, + resizeMode = "cover", + style, + transitionDuration = 300, + transitionEffect = "cross-dissolve", + transitionTiming = "ease-in-out", + contentFit = "cover", + contentPosition = "center", + cachePolicy = "memory-disk", + allowDownscaling = true, + blurRadius, + blurhash, + ...props +}) => { + const imageSource = source ?? Config.placeholderImageURL; + const finalContentFit = resizeMode + ? resizeModeToContentFit(resizeMode) + : contentFit; + + const transition = { + timing: transitionTiming, + duration: transitionDuration, + effect: transitionEffect, + }; + + return ( + + ); +}; + +export default ExpoImage; diff --git a/packages/core/src/index.tsx b/packages/core/src/index.tsx index 11b4f3326..8cf12db08 100644 --- a/packages/core/src/index.tsx +++ b/packages/core/src/index.tsx @@ -82,6 +82,7 @@ export { default as SimpleStyleSwipeableList } from "./components/SimpleStyleScr export { default as LoadingIndicator } from "./components/LoadingIndicator"; export { default as LottieAnimation } from "./components/LottieAnimation"; export { default as Timer } from "./components/Timer"; +export { default as ExpoImage } from "./components/ExpoImage"; /* Deprecated: Fix or Delete! */ export { default as AccordionItem } from "./deprecated-components/AccordionItem"; diff --git a/packages/ui/src/index.tsx b/packages/ui/src/index.tsx index 0eabd3e51..6a8151951 100644 --- a/packages/ui/src/index.tsx +++ b/packages/ui/src/index.tsx @@ -78,6 +78,7 @@ export { LoadingIndicator, LottieAnimation, Timer, + ExpoImage, } from "@draftbit/core"; export { diff --git a/yarn.lock b/yarn.lock index 147a1bb03..b09e471e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6218,6 +6218,11 @@ expo-font@~12.0.10: dependencies: fontfaceobserver "^2.1.0" +expo-image@~1.13.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/expo-image/-/expo-image-1.13.0.tgz#f0ad585ecf57f6df2d8524f5e9275cb12b349836" + integrity sha512-0NLDcFmEn4Nh1sXeRvNzDHT+Fl6FXtTol6ki6kYYH0/iDeSFWyIy/Fek6kzDDYAmhipSMR7buPf7VVoHseTbAA== + expo-keep-awake@~13.0.2: version "13.0.2" resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-13.0.2.tgz#5ef31311a339671eec9921b934fdd90ab9652b0e"