expo-image 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,12 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 1.2.2 — 2023-04-27
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - Fix for the "limited" media library permission. ([#22261](https://github.com/expo/expo/pull/22261) by [@tsapeta](https://github.com/tsapeta))
18
+
13
19
  ## 1.2.1 — 2023-04-17
14
20
 
15
21
  ### 🐛 Bug fixes
@@ -30,6 +36,7 @@
30
36
 
31
37
  ### 🐛 Bug fixes
32
38
 
39
+ - [Web] Improve transition behavior when switching back and forth two sources. ([#22099](https://github.com/expo/expo/pull/22099) by [@aleqsio](https://github.com/aleqsio))
33
40
  - [Web] Prevent breaking in static rendering environments. ([#21883](https://github.com/expo/expo/pull/21883) by [@EvanBacon](https://github.com/EvanBacon))
34
41
  - [Android] Fixed image disappearing before navigation animation is complete. ([#22066](https://github.com/expo/expo/pull/22066) by [@sallen450](https://github.com/sallen450))
35
42
  - [Web] Fixed monorepo asset resolution in production for Metro web. ([#22094](https://github.com/expo/expo/pull/22094) by [@EvanBacon](https://github.com/EvanBacon))
package/README.md CHANGED
@@ -21,17 +21,17 @@ A cross-platform, performant image component for React Native and Expo.
21
21
 
22
22
  ## Supported image formats
23
23
 
24
- | Format | Android | iOS | Web |
25
- |:---:|:---:|:---:|:---:|
26
- | WebP | | ✅ | ✅ [~96% adoption](https://caniuse.com/webp) |
27
- | PNG / APNG | | ✅ | ✅ / ✅ [~96% adoption](https://caniuse.com/apng) |
28
- | AVIF | | ✅ | ⏳ [~79% adoption](https://caniuse.com/avif) |
29
- | HEIC | | ✅ | ❌ [not adopted yet](https://caniuse.com/heif) |
30
- | JPEG | | ✅ | |
31
- | GIF | | ✅ | |
32
- | SVG | | ✅ | |
33
- | ICO | | ✅ | |
34
- | ICNS | | ✅ | |
24
+ | Format | Android | iOS | Web |
25
+ | :--------: | :-----: | :-: | :-----------------------------------------------: |
26
+ | WebP | | ✅ | ✅ [~96% adoption](https://caniuse.com/webp) |
27
+ | PNG / APNG | | ✅ | ✅ / ✅ [~96% adoption](https://caniuse.com/apng) |
28
+ | AVIF | | ✅ | ⏳ [~79% adoption](https://caniuse.com/avif) |
29
+ | HEIC | | ✅ | ❌ [not adopted yet](https://caniuse.com/heif) |
30
+ | JPEG | | ✅ | |
31
+ | GIF | | ✅ | |
32
+ | SVG | | ✅ | |
33
+ | ICO | | ✅ | |
34
+ | ICNS | | ✅ | |
35
35
 
36
36
  # API documentation
37
37
 
@@ -49,7 +49,7 @@ android {
49
49
  minSdkVersion safeExtGet("minSdkVersion", 21)
50
50
  targetSdkVersion safeExtGet("targetSdkVersion", 33)
51
51
  versionCode 1
52
- versionName "1.2.1"
52
+ versionName "1.2.2"
53
53
  }
54
54
  lintOptions {
55
55
  abortOnError false
@@ -1 +1 @@
1
- {"version":3,"file":"AnimationManager.d.ts","sourceRoot":"","sources":["../../src/web/AnimationManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,KAAK,SAAS,GAAG;IACf,OAAO,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9B,mBAAmB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM;IACX,cAAc,EAAE,CACd,WAAW,EAAE,WAAW,CAAC,SAAS,CAAC,KAChC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,YAAY;CAC3E,CAAC;AAgDF,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;;;;;;;SA+BvF;AAUD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,QAAQ,EAAE,cAAc,EACxB,OAAO,EACP,UAAU,EACV,YAAY,GACb,EAAE;IACD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC1C,eAsGA"}
1
+ {"version":3,"file":"AnimationManager.d.ts","sourceRoot":"","sources":["../../src/web/AnimationManager.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,KAAK,SAAS,GAAG;IACf,OAAO,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9B,mBAAmB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM;IACX,cAAc,EAAE,CACd,WAAW,EAAE,WAAW,CAAC,SAAS,CAAC,KAChC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,YAAY;CAC3E,CAAC;AAgDF,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS;;;;;;;;;;;;;;;;SA+BvF;AAUD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,QAAQ,EAAE,cAAc,EACxB,OAAO,EACP,UAAU,EACV,YAAY,GACb,EAAE;IACD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/C,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC1C,eA4GA"}
@@ -86,9 +86,14 @@ export default function AnimationManager({ children: renderFunction, initial, tr
86
86
  }
87
87
  const existingNodeIndex = n.findIndex((node) => node.animationKey === newNode.animationKey);
88
88
  if (existingNodeIndex >= 0) {
89
- const copy = [...n];
90
- copy.splice(existingNodeIndex, 1, newNode);
91
- return copy;
89
+ if (animation) {
90
+ return n.map((n2) => n2.animationKey === newNode.animationKey
91
+ ? { ...newNode, status: 'in' }
92
+ : { ...n2, status: 'out' });
93
+ }
94
+ else {
95
+ return [{ ...newNode, status: 'in' }];
96
+ }
92
97
  }
93
98
  return [...n, newNode];
94
99
  });
@@ -1 +1 @@
1
- {"version":3,"file":"AnimationManager.js","sourceRoot":"","sources":["../../src/web/AnimationManager.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport { ImageTransition } from '../Image.types';\n\ntype Callbacks = {\n onReady?: (() => void) | null;\n onAnimationFinished?: (() => void) | null;\n onMount?: (() => void) | null;\n onError?: (() => void) | null;\n};\n\nexport type AnimationManagerNode = [\n key: string,\n renderFunction: (\n renderProps: NonNullable<Callbacks>\n ) => (className: string, style: React.CSSProperties) => React.ReactElement\n];\n\nconst SUPPORTED_ANIMATIONS: ImageTransition['effect'][] = [\n 'cross-dissolve',\n 'flip-from-left',\n 'flip-from-right',\n 'flip-from-top',\n 'flip-from-bottom',\n];\n\ntype NodeStatus = 'mounted' | 'in' | 'active' | 'out' | 'errored';\n\nfunction useAnimationManagerNode(node: AnimationManagerNode | null, initialStatus?: NodeStatus) {\n const newNode = React.useMemo(() => {\n if (!node) {\n return null;\n }\n const [animationKey, renderFunction] = node;\n // key, ReactElement, ref, callbacks\n return {\n animationKey,\n persistedElement: renderFunction,\n status: (initialStatus || 'mounted') as NodeStatus,\n };\n }, [node?.[0]]);\n return newNode;\n}\n\nfunction validateTimingFunctionForAnimation(\n animationClass: ImageTransition['effect'],\n timingFunction: ImageTransition['timing']\n) {\n if (animationClass?.includes('flip')) {\n if (timingFunction?.includes('ease')) {\n return 'ease-in-out';\n }\n return 'linear';\n }\n return timingFunction || null;\n}\n\nfunction validateAnimationClass(effect: ImageTransition['effect']) {\n if (SUPPORTED_ANIMATIONS.includes(effect)) {\n return effect;\n }\n return 'cross-dissolve';\n}\n\nexport function getAnimatorFromTransition(transition: ImageTransition | null | undefined) {\n if (!transition?.duration) {\n return null;\n }\n const animationClass = validateAnimationClass(transition.effect);\n if (!animationClass) {\n return {\n startingClass: '',\n animateInClass: '',\n animateOutClass: '',\n containerClass: '',\n timingFunction: 'linear',\n animationClass: '',\n duration: 0,\n };\n }\n\n const timingFunction = validateTimingFunctionForAnimation(animationClass, transition.timing);\n const timingClass = `image-timing-${timingFunction}`;\n\n return {\n startingClass: `${animationClass}-start`,\n animateInClass: [animationClass, 'transitioning', `${animationClass}-active`, timingClass].join(\n ' '\n ),\n animateOutClass: [animationClass, `${animationClass}-end`, timingClass].join(' '),\n containerClass: `${animationClass}-container`,\n timingFunction,\n animationClass,\n duration: transition?.duration || 0,\n };\n}\n\ntype MountedAnimationNode = {\n animationKey: string;\n persistedElement: (\n renderProps: Callbacks\n ) => (className: string, style: React.CSSProperties) => React.ReactElement;\n status: NodeStatus;\n};\n\nexport default function AnimationManager({\n children: renderFunction,\n initial,\n transition,\n recyclingKey,\n}: {\n children: AnimationManagerNode;\n initial: AnimationManagerNode | null;\n transition: ImageTransition | null | undefined;\n recyclingKey?: string | null | undefined;\n}) {\n const animation = getAnimatorFromTransition(transition);\n\n const initialNode = useAnimationManagerNode(initial, 'active');\n\n const [nodes, setNodes] = React.useState<MountedAnimationNode[]>(\n initialNode ? [initialNode] : []\n );\n\n const [prevRecyclingKey, setPrevRecyclingKey] = React.useState<string>(recyclingKey ?? '');\n if (prevRecyclingKey !== (recyclingKey ?? '')) {\n setPrevRecyclingKey(recyclingKey ?? '');\n setNodes(initialNode ? [initialNode] : []);\n }\n\n const removeAllNodesOfKeyExceptShowing = (key?: string) => {\n setNodes((n) =>\n n.filter(\n (node) =>\n (key ? node.animationKey !== key : false) ||\n node.status === 'in' ||\n node.status === 'active'\n )\n );\n };\n\n const newNode = useAnimationManagerNode(renderFunction);\n\n React.useEffect(() => {\n setNodes((n) => {\n if (!newNode) {\n return n;\n }\n const existingNodeIndex = n.findIndex((node) => node.animationKey === newNode.animationKey);\n if (existingNodeIndex >= 0) {\n const copy = [...n];\n copy.splice(existingNodeIndex, 1, newNode);\n return copy;\n }\n return [...n, newNode];\n });\n }, [newNode]);\n\n function wrapNodeWithCallbacks(node: MountedAnimationNode) {\n if (renderFunction[0] === node.animationKey) {\n return renderFunction[1]({\n onReady: () => {\n if (animation) {\n setNodes((nodes) =>\n nodes.map((n) => (n === newNode ? { ...n, status: 'in' } : { ...n, status: 'out' }))\n );\n } else {\n setNodes([{ ...node, status: 'in' }]);\n }\n },\n onAnimationFinished: () => {\n setNodes([{ ...node, status: 'in' }]);\n },\n onError: () => {\n setNodes((nodes) => nodes.map((n) => (n === node ? { ...n, status: 'errored' } : n)));\n },\n });\n }\n if (initial?.[0] === node.animationKey) {\n return initial[1]({\n onAnimationFinished: () => {\n if (node.status === 'out') {\n removeAllNodesOfKeyExceptShowing(node.animationKey);\n }\n },\n onError: () => {\n setNodes((nodes) => nodes.map((n) => (n === node ? { ...n, status: 'errored' } : n)));\n },\n });\n }\n return node.persistedElement({\n onAnimationFinished: () => {\n removeAllNodesOfKeyExceptShowing(node.animationKey);\n },\n });\n }\n const styles = {\n transitionDuration: `${animation?.duration || 0}ms`,\n transitionTimingFunction: animation?.timingFunction || 'linear',\n };\n const classes = {\n in: animation?.animateInClass,\n out: animation?.animateOutClass,\n mounted: animation?.startingClass,\n };\n\n return (\n <>\n {[...nodes]\n .filter((n) => n.status !== 'errored')\n .map((n) => (\n <div className={animation?.containerClass} key={n.animationKey}>\n {wrapNodeWithCallbacks(n)(classes[n.status], styles)}\n </div>\n ))}\n </>\n );\n}\n"]}
1
+ {"version":3,"file":"AnimationManager.js","sourceRoot":"","sources":["../../src/web/AnimationManager.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport { ImageTransition } from '../Image.types';\n\ntype Callbacks = {\n onReady?: (() => void) | null;\n onAnimationFinished?: (() => void) | null;\n onMount?: (() => void) | null;\n onError?: (() => void) | null;\n};\n\nexport type AnimationManagerNode = [\n key: string,\n renderFunction: (\n renderProps: NonNullable<Callbacks>\n ) => (className: string, style: React.CSSProperties) => React.ReactElement\n];\n\nconst SUPPORTED_ANIMATIONS: ImageTransition['effect'][] = [\n 'cross-dissolve',\n 'flip-from-left',\n 'flip-from-right',\n 'flip-from-top',\n 'flip-from-bottom',\n];\n\ntype NodeStatus = 'mounted' | 'in' | 'active' | 'out' | 'errored';\n\nfunction useAnimationManagerNode(node: AnimationManagerNode | null, initialStatus?: NodeStatus) {\n const newNode = React.useMemo(() => {\n if (!node) {\n return null;\n }\n const [animationKey, renderFunction] = node;\n // key, ReactElement, ref, callbacks\n return {\n animationKey,\n persistedElement: renderFunction,\n status: (initialStatus || 'mounted') as NodeStatus,\n };\n }, [node?.[0]]);\n return newNode;\n}\n\nfunction validateTimingFunctionForAnimation(\n animationClass: ImageTransition['effect'],\n timingFunction: ImageTransition['timing']\n) {\n if (animationClass?.includes('flip')) {\n if (timingFunction?.includes('ease')) {\n return 'ease-in-out';\n }\n return 'linear';\n }\n return timingFunction || null;\n}\n\nfunction validateAnimationClass(effect: ImageTransition['effect']) {\n if (SUPPORTED_ANIMATIONS.includes(effect)) {\n return effect;\n }\n return 'cross-dissolve';\n}\n\nexport function getAnimatorFromTransition(transition: ImageTransition | null | undefined) {\n if (!transition?.duration) {\n return null;\n }\n const animationClass = validateAnimationClass(transition.effect);\n if (!animationClass) {\n return {\n startingClass: '',\n animateInClass: '',\n animateOutClass: '',\n containerClass: '',\n timingFunction: 'linear',\n animationClass: '',\n duration: 0,\n };\n }\n\n const timingFunction = validateTimingFunctionForAnimation(animationClass, transition.timing);\n const timingClass = `image-timing-${timingFunction}`;\n\n return {\n startingClass: `${animationClass}-start`,\n animateInClass: [animationClass, 'transitioning', `${animationClass}-active`, timingClass].join(\n ' '\n ),\n animateOutClass: [animationClass, `${animationClass}-end`, timingClass].join(' '),\n containerClass: `${animationClass}-container`,\n timingFunction,\n animationClass,\n duration: transition?.duration || 0,\n };\n}\n\ntype MountedAnimationNode = {\n animationKey: string;\n persistedElement: (\n renderProps: Callbacks\n ) => (className: string, style: React.CSSProperties) => React.ReactElement;\n status: NodeStatus;\n};\n\nexport default function AnimationManager({\n children: renderFunction,\n initial,\n transition,\n recyclingKey,\n}: {\n children: AnimationManagerNode;\n initial: AnimationManagerNode | null;\n transition: ImageTransition | null | undefined;\n recyclingKey?: string | null | undefined;\n}) {\n const animation = getAnimatorFromTransition(transition);\n\n const initialNode = useAnimationManagerNode(initial, 'active');\n\n const [nodes, setNodes] = React.useState<MountedAnimationNode[]>(\n initialNode ? [initialNode] : []\n );\n\n const [prevRecyclingKey, setPrevRecyclingKey] = React.useState<string>(recyclingKey ?? '');\n if (prevRecyclingKey !== (recyclingKey ?? '')) {\n setPrevRecyclingKey(recyclingKey ?? '');\n setNodes(initialNode ? [initialNode] : []);\n }\n\n const removeAllNodesOfKeyExceptShowing = (key?: string) => {\n setNodes((n) =>\n n.filter(\n (node) =>\n (key ? node.animationKey !== key : false) ||\n node.status === 'in' ||\n node.status === 'active'\n )\n );\n };\n\n const newNode = useAnimationManagerNode(renderFunction);\n\n React.useEffect(() => {\n setNodes((n) => {\n if (!newNode) {\n return n;\n }\n const existingNodeIndex = n.findIndex((node) => node.animationKey === newNode.animationKey);\n if (existingNodeIndex >= 0) {\n if (animation) {\n return n.map((n2) =>\n n2.animationKey === newNode.animationKey\n ? { ...newNode, status: 'in' }\n : { ...n2, status: 'out' }\n );\n } else {\n return [{ ...newNode, status: 'in' }];\n }\n }\n return [...n, newNode];\n });\n }, [newNode]);\n\n function wrapNodeWithCallbacks(node: MountedAnimationNode) {\n if (renderFunction[0] === node.animationKey) {\n return renderFunction[1]({\n onReady: () => {\n if (animation) {\n setNodes((nodes) =>\n nodes.map((n) => (n === newNode ? { ...n, status: 'in' } : { ...n, status: 'out' }))\n );\n } else {\n setNodes([{ ...node, status: 'in' }]);\n }\n },\n onAnimationFinished: () => {\n setNodes([{ ...node, status: 'in' }]);\n },\n onError: () => {\n setNodes((nodes) => nodes.map((n) => (n === node ? { ...n, status: 'errored' } : n)));\n },\n });\n }\n if (initial?.[0] === node.animationKey) {\n return initial[1]({\n onAnimationFinished: () => {\n if (node.status === 'out') {\n removeAllNodesOfKeyExceptShowing(node.animationKey);\n }\n },\n onError: () => {\n setNodes((nodes) => nodes.map((n) => (n === node ? { ...n, status: 'errored' } : n)));\n },\n });\n }\n return node.persistedElement({\n onAnimationFinished: () => {\n removeAllNodesOfKeyExceptShowing(node.animationKey);\n },\n });\n }\n const styles = {\n transitionDuration: `${animation?.duration || 0}ms`,\n transitionTimingFunction: animation?.timingFunction || 'linear',\n };\n const classes = {\n in: animation?.animateInClass,\n out: animation?.animateOutClass,\n mounted: animation?.startingClass,\n };\n\n return (\n <>\n {[...nodes]\n .filter((n) => n.status !== 'errored')\n .map((n) => (\n <div className={animation?.containerClass} key={n.animationKey}>\n {wrapNodeWithCallbacks(n)(classes[n.status], styles)}\n </div>\n ))}\n </>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ImageWrapper.d.ts","sourceRoot":"","sources":["../../src/web/ImageWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,cAAc,EAA2B,MAAM,OAAO,CAAC;AAEtF,OAAO,EACL,0BAA0B,EAG1B,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAgDxB,QAAA,MAAM,YAAY;;;2BAeS,eAAe,gBAAgB,EAAE,KAAK,CAAC,KAAK,IAAI;;oBAChC,WAAW,GAAG,IAAI;cAAO,IAAI;kCACtC,IAAI;0BACZ,IAAI;;;;;WAKjB,aAAa;;;;0CAwDzB,CAAC;AACF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"ImageWrapper.d.ts","sourceRoot":"","sources":["../../src/web/ImageWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,cAAc,EAA2B,MAAM,OAAO,CAAC;AAEtF,OAAO,EACL,0BAA0B,EAG1B,WAAW,EACZ,MAAM,gBAAgB,CAAC;AAgDxB,QAAA,MAAM,YAAY;;;2BAeS,eAAe,gBAAgB,EAAE,KAAK,CAAC,KAAK,IAAI;;oBAChC,WAAW,GAAG,IAAI;cAAO,IAAI;kCACtC,IAAI;0BACZ,IAAI;;;;;WAKjB,aAAa;;;;0CA+DzB,CAAC;AACF,eAAe,YAAY,CAAC"}
@@ -60,7 +60,15 @@ const ImageWrapper = React.forwardRef(({ source, events, contentPosition, hashPl
60
60
  // @ts-ignore
61
61
  // eslint-disable-next-line react/no-unknown-property
62
62
  fetchpriority: getFetchPriorityFromImagePriority(priority || 'normal'), onLoad: (event) => {
63
- events?.onLoad?.forEach((e) => e?.(event));
63
+ if (typeof window !== 'undefined') {
64
+ // this ensures the animation will run, since the starting class is applied at least 1 frame before the target class set in the onLoad event callback
65
+ window.requestAnimationFrame(() => {
66
+ events?.onLoad?.forEach((e) => e?.(event));
67
+ });
68
+ }
69
+ else {
70
+ events?.onLoad?.forEach((e) => e?.(event));
71
+ }
64
72
  }, onTransitionEnd: () => events?.onTransitionEnd?.forEach((e) => e?.()), onError: () => events?.onError?.forEach((e) => e?.({ source: source || null })) }));
65
73
  });
66
74
  export default ImageWrapper;
@@ -1 +1 @@
1
- {"version":3,"file":"ImageWrapper.js","sourceRoot":"","sources":["../../src/web/ImageWrapper.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { CSSProperties, SyntheticEvent, useEffect, Ref, useMemo } from 'react';\n\nimport {\n ImageContentPositionObject,\n ImageContentPositionValue,\n ImageNativeProps,\n ImageSource,\n} from '../Image.types';\nimport { useBlurhash } from '../utils/blurhash/useBlurhash';\nimport { isBlurhashString, isThumbhashString } from '../utils/resolveSources';\nimport { thumbHashStringToDataURL } from '../utils/thumbhash/thumbhash';\n\nfunction ensureUnit(value: string | number) {\n const trimmedValue = String(value).trim();\n if (trimmedValue.endsWith('%')) {\n return trimmedValue;\n }\n return `${trimmedValue}px`;\n}\n\ntype KeysOfUnion<T> = T extends T ? keyof T : never;\n\nfunction getObjectPositionFromContentPositionObject(\n contentPosition?: ImageContentPositionObject\n): string {\n const resolvedPosition = { ...contentPosition } as Record<\n KeysOfUnion<ImageContentPositionObject>,\n ImageContentPositionValue\n >;\n if (!resolvedPosition) {\n return '50% 50%';\n }\n if (resolvedPosition.top == null && resolvedPosition.bottom == null) {\n resolvedPosition.top = '50%';\n }\n if (resolvedPosition.left == null && resolvedPosition.right == null) {\n resolvedPosition.left = '50%';\n }\n\n return (\n ['top', 'bottom', 'left', 'right']\n .map((key) => {\n if (key in resolvedPosition) {\n return `${key} ${ensureUnit(resolvedPosition[key])}`;\n }\n return '';\n })\n .join(' ') || '50% 50%'\n );\n}\n\nfunction getFetchPriorityFromImagePriority(priority: ImageNativeProps['priority'] = 'normal') {\n return priority && ['low', 'high'].includes(priority) ? priority : 'auto';\n}\n\nconst ImageWrapper = React.forwardRef(\n (\n {\n source,\n events,\n contentPosition,\n hashPlaceholderContentPosition,\n priority,\n style,\n hashPlaceholderStyle,\n className,\n accessibilityLabel,\n }: {\n source?: ImageSource | null;\n events?: {\n onLoad?: (((event: SyntheticEvent<HTMLImageElement, Event>) => void) | undefined | null)[];\n onError?: ((({ source }: { source: ImageSource | null }) => void) | undefined | null)[];\n onTransitionEnd?: ((() => void) | undefined | null)[];\n onMount?: ((() => void) | undefined | null)[];\n };\n contentPosition?: ImageContentPositionObject;\n hashPlaceholderContentPosition?: ImageContentPositionObject;\n priority?: string | null;\n style: CSSProperties;\n hashPlaceholderStyle?: CSSProperties;\n className?: string;\n accessibilityLabel?: string;\n },\n ref: Ref<HTMLImageElement>\n ) => {\n useEffect(() => {\n events?.onMount?.forEach((e) => e?.());\n }, []);\n const isBlurhash = isBlurhashString(source?.uri || '');\n const isThumbhash = isThumbhashString(source?.uri || '');\n const isHash = isBlurhash || isThumbhash;\n\n // Thumbhash uri always has to start with 'thumbhash:/'\n const thumbhash = source?.uri?.replace(/thumbhash:\\//, '');\n const thumbhashUri = useMemo(\n () => (isThumbhash ? thumbHashStringToDataURL(thumbhash ?? '') : null),\n [thumbhash]\n );\n\n const blurhashUri = useBlurhash(isBlurhash ? source?.uri : null, source?.width, source?.height);\n const objectPosition = getObjectPositionFromContentPositionObject(\n isHash ? hashPlaceholderContentPosition : contentPosition\n );\n\n const uri = isHash ? blurhashUri ?? thumbhashUri : source?.uri;\n if (!uri) return null;\n return (\n <img\n ref={ref}\n alt={accessibilityLabel}\n className={className}\n src={uri || undefined}\n key={source?.uri}\n style={{\n width: '100%',\n height: '100%',\n position: 'absolute',\n left: 0,\n right: 0,\n objectPosition,\n ...style,\n ...(isHash ? hashPlaceholderStyle : {}),\n }}\n // @ts-ignore\n // eslint-disable-next-line react/no-unknown-property\n fetchpriority={getFetchPriorityFromImagePriority(priority || 'normal')}\n onLoad={(event) => {\n events?.onLoad?.forEach((e) => e?.(event));\n }}\n onTransitionEnd={() => events?.onTransitionEnd?.forEach((e) => e?.())}\n onError={() => events?.onError?.forEach((e) => e?.({ source: source || null }))}\n />\n );\n }\n);\nexport default ImageWrapper;\n"]}
1
+ {"version":3,"file":"ImageWrapper.js","sourceRoot":"","sources":["../../src/web/ImageWrapper.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { CSSProperties, SyntheticEvent, useEffect, Ref, useMemo } from 'react';\n\nimport {\n ImageContentPositionObject,\n ImageContentPositionValue,\n ImageNativeProps,\n ImageSource,\n} from '../Image.types';\nimport { useBlurhash } from '../utils/blurhash/useBlurhash';\nimport { isBlurhashString, isThumbhashString } from '../utils/resolveSources';\nimport { thumbHashStringToDataURL } from '../utils/thumbhash/thumbhash';\n\nfunction ensureUnit(value: string | number) {\n const trimmedValue = String(value).trim();\n if (trimmedValue.endsWith('%')) {\n return trimmedValue;\n }\n return `${trimmedValue}px`;\n}\n\ntype KeysOfUnion<T> = T extends T ? keyof T : never;\n\nfunction getObjectPositionFromContentPositionObject(\n contentPosition?: ImageContentPositionObject\n): string {\n const resolvedPosition = { ...contentPosition } as Record<\n KeysOfUnion<ImageContentPositionObject>,\n ImageContentPositionValue\n >;\n if (!resolvedPosition) {\n return '50% 50%';\n }\n if (resolvedPosition.top == null && resolvedPosition.bottom == null) {\n resolvedPosition.top = '50%';\n }\n if (resolvedPosition.left == null && resolvedPosition.right == null) {\n resolvedPosition.left = '50%';\n }\n\n return (\n ['top', 'bottom', 'left', 'right']\n .map((key) => {\n if (key in resolvedPosition) {\n return `${key} ${ensureUnit(resolvedPosition[key])}`;\n }\n return '';\n })\n .join(' ') || '50% 50%'\n );\n}\n\nfunction getFetchPriorityFromImagePriority(priority: ImageNativeProps['priority'] = 'normal') {\n return priority && ['low', 'high'].includes(priority) ? priority : 'auto';\n}\n\nconst ImageWrapper = React.forwardRef(\n (\n {\n source,\n events,\n contentPosition,\n hashPlaceholderContentPosition,\n priority,\n style,\n hashPlaceholderStyle,\n className,\n accessibilityLabel,\n }: {\n source?: ImageSource | null;\n events?: {\n onLoad?: (((event: SyntheticEvent<HTMLImageElement, Event>) => void) | undefined | null)[];\n onError?: ((({ source }: { source: ImageSource | null }) => void) | undefined | null)[];\n onTransitionEnd?: ((() => void) | undefined | null)[];\n onMount?: ((() => void) | undefined | null)[];\n };\n contentPosition?: ImageContentPositionObject;\n hashPlaceholderContentPosition?: ImageContentPositionObject;\n priority?: string | null;\n style: CSSProperties;\n hashPlaceholderStyle?: CSSProperties;\n className?: string;\n accessibilityLabel?: string;\n },\n ref: Ref<HTMLImageElement>\n ) => {\n useEffect(() => {\n events?.onMount?.forEach((e) => e?.());\n }, []);\n const isBlurhash = isBlurhashString(source?.uri || '');\n const isThumbhash = isThumbhashString(source?.uri || '');\n const isHash = isBlurhash || isThumbhash;\n\n // Thumbhash uri always has to start with 'thumbhash:/'\n const thumbhash = source?.uri?.replace(/thumbhash:\\//, '');\n const thumbhashUri = useMemo(\n () => (isThumbhash ? thumbHashStringToDataURL(thumbhash ?? '') : null),\n [thumbhash]\n );\n\n const blurhashUri = useBlurhash(isBlurhash ? source?.uri : null, source?.width, source?.height);\n const objectPosition = getObjectPositionFromContentPositionObject(\n isHash ? hashPlaceholderContentPosition : contentPosition\n );\n\n const uri = isHash ? blurhashUri ?? thumbhashUri : source?.uri;\n if (!uri) return null;\n return (\n <img\n ref={ref}\n alt={accessibilityLabel}\n className={className}\n src={uri || undefined}\n key={source?.uri}\n style={{\n width: '100%',\n height: '100%',\n position: 'absolute',\n left: 0,\n right: 0,\n objectPosition,\n ...style,\n ...(isHash ? hashPlaceholderStyle : {}),\n }}\n // @ts-ignore\n // eslint-disable-next-line react/no-unknown-property\n fetchpriority={getFetchPriorityFromImagePriority(priority || 'normal')}\n onLoad={(event) => {\n if (typeof window !== 'undefined') {\n // this ensures the animation will run, since the starting class is applied at least 1 frame before the target class set in the onLoad event callback\n window.requestAnimationFrame(() => {\n events?.onLoad?.forEach((e) => e?.(event));\n });\n } else {\n events?.onLoad?.forEach((e) => e?.(event));\n }\n }}\n onTransitionEnd={() => events?.onTransitionEnd?.forEach((e) => e?.())}\n onError={() => events?.onError?.forEach((e) => e?.({ source: source || null }))}\n />\n );\n }\n);\nexport default ImageWrapper;\n"]}
@@ -78,7 +78,8 @@ private func assetLocalIdentifier(fromUrl url: URL) -> String? {
78
78
  */
79
79
  private func isPhotoLibraryStatusAuthorized() -> Bool {
80
80
  if #available(iOS 14, *) {
81
- return PHPhotoLibrary.authorizationStatus(for: .readWrite) == .authorized
81
+ let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
82
+ return status == .authorized || status == .limited
82
83
  } else {
83
84
  return PHPhotoLibrary.authorizationStatus() == .authorized
84
85
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "expo-image",
3
3
  "title": "Expo Image",
4
- "version": "1.2.1",
4
+ "version": "1.2.2",
5
5
  "description": "A cross-platform, performant image component for React Native and Expo with Web support",
6
6
  "main": "build/index.js",
7
7
  "types": "build/index.d.ts",
@@ -33,5 +33,5 @@
33
33
  "peerDependencies": {
34
34
  "expo": "*"
35
35
  },
36
- "gitHead": "836bea54c7c2ba747df428d8217d85703a9701fb"
36
+ "gitHead": "e7ef246d8e7c274cc6ce67eee4d0d764bd3f042f"
37
37
  }
@@ -148,9 +148,15 @@ export default function AnimationManager({
148
148
  }
149
149
  const existingNodeIndex = n.findIndex((node) => node.animationKey === newNode.animationKey);
150
150
  if (existingNodeIndex >= 0) {
151
- const copy = [...n];
152
- copy.splice(existingNodeIndex, 1, newNode);
153
- return copy;
151
+ if (animation) {
152
+ return n.map((n2) =>
153
+ n2.animationKey === newNode.animationKey
154
+ ? { ...newNode, status: 'in' }
155
+ : { ...n2, status: 'out' }
156
+ );
157
+ } else {
158
+ return [{ ...newNode, status: 'in' }];
159
+ }
154
160
  }
155
161
  return [...n, newNode];
156
162
  });
@@ -125,7 +125,14 @@ const ImageWrapper = React.forwardRef(
125
125
  // eslint-disable-next-line react/no-unknown-property
126
126
  fetchpriority={getFetchPriorityFromImagePriority(priority || 'normal')}
127
127
  onLoad={(event) => {
128
- events?.onLoad?.forEach((e) => e?.(event));
128
+ if (typeof window !== 'undefined') {
129
+ // this ensures the animation will run, since the starting class is applied at least 1 frame before the target class set in the onLoad event callback
130
+ window.requestAnimationFrame(() => {
131
+ events?.onLoad?.forEach((e) => e?.(event));
132
+ });
133
+ } else {
134
+ events?.onLoad?.forEach((e) => e?.(event));
135
+ }
129
136
  }}
130
137
  onTransitionEnd={() => events?.onTransitionEnd?.forEach((e) => e?.())}
131
138
  onError={() => events?.onError?.forEach((e) => e?.({ source: source || null }))}