diff --git a/example/storybook-nativewind/.storybook/preview.js b/example/storybook-nativewind/.storybook/preview.js
index c89f7f123..49e5b04b0 100644
--- a/example/storybook-nativewind/.storybook/preview.js
+++ b/example/storybook-nativewind/.storybook/preview.js
@@ -108,6 +108,8 @@ export const parameters = {
[
'Recipes',
['Linear Gradient'],
+ 'Tutorials',
+ ['Building Ecommerce App'],
'More',
[
'Upgrade to v2',
diff --git a/example/storybook-nativewind/src/components/ImageViewer/ImageViewer.tsx b/example/storybook-nativewind/src/components/ImageViewer/ImageViewer.tsx
index 7c40983ef..22ac44607 100644
--- a/example/storybook-nativewind/src/components/ImageViewer/ImageViewer.tsx
+++ b/example/storybook-nativewind/src/components/ImageViewer/ImageViewer.tsx
@@ -1,5 +1,6 @@
import React, { useState } from 'react';
import { Image, Pressable } from 'react-native';
+import { StatusBar } from 'expo-status-bar';
import {
ImageViewer,
ImageViewerBackdrop,
@@ -20,6 +21,7 @@ const ImageViewerBasic = ({ ...props }: any) => {
const [visible, setVisible] = useState(false);
return (
<>
+
setVisible(true)}>
+
setVisible(true)}>
@@ -381,6 +385,7 @@ import { Center } from '@/components/ui/center';
const Images = [{ id: 1, url: 'https://img.freepik.com/free-photo/young-boy-learning-how-ride-horse_23-2150460636.jpg' }];
return (
+
setVisible(true)}>
void;
+ YT: any;
+ }
+}
+
+const VadimStream = () => {
+ useEffect(() => {
+ // Only load the API if it hasn't been loaded yet
+ if (!document.getElementById('youtube-api')) {
+ const tag = document.createElement('script');
+ tag.id = 'youtube-api';
+ tag.src = 'https://www.youtube.com/iframe_api';
+ const firstScriptTag = document.getElementsByTagName('script')[0];
+ firstScriptTag.parentNode?.insertBefore(tag, firstScriptTag);
+ }
+
+ // Initialize players when API is ready
+ const initializePlayers = () => {
+ new window.YT.Player('player1', {
+ events: {
+ onStateChange: (event: any) => {
+ if (event.data === window.YT.PlayerState.PLAYING) {
+ const player2Frame = document.getElementById(
+ 'player2'
+ ) as HTMLIFrameElement;
+ player2Frame?.contentWindow?.postMessage(
+ '{"event":"command","func":"pauseVideo","args":""}',
+ '*'
+ );
+ }
+ },
+ },
+ });
+
+ new window.YT.Player('player2', {
+ events: {
+ onStateChange: (event: any) => {
+ if (event.data === window.YT.PlayerState.PLAYING) {
+ const player1Frame = document.getElementById(
+ 'player1'
+ ) as HTMLIFrameElement;
+ player1Frame?.contentWindow?.postMessage(
+ '{"event":"command","func":"pauseVideo","args":""}',
+ '*'
+ );
+ }
+ },
+ },
+ });
+ };
+
+ // If API is already loaded, initialize players directly
+ if (window.YT && window.YT.Player) {
+ initializePlayers();
+ } else {
+ // Otherwise wait for API to load
+ window.onYouTubeIframeAPIReady = initializePlayers;
+ }
+
+ return () => {
+ // Only reset the ready handler, don't remove the script
+ window.onYouTubeIframeAPIReady = () => {};
+ };
+ }, []);
+
+ return (
+
+
+
+
+
+
+
+
+ );
+};
+
+export default VadimStream;
diff --git a/example/storybook-nativewind/src/guides/tutorials/building-ecommerce-app/index.nw.stories.mdx b/example/storybook-nativewind/src/guides/tutorials/building-ecommerce-app/index.nw.stories.mdx
new file mode 100644
index 000000000..b8a593793
--- /dev/null
+++ b/example/storybook-nativewind/src/guides/tutorials/building-ecommerce-app/index.nw.stories.mdx
@@ -0,0 +1,16 @@
+---
+title: Learn to build Ecommerce App using gluestack
+
+description: Tutorial to build Ecommerce App using gluestack-ui from Youtube guru notJust.dev (Vadim)
+---
+
+import { Meta } from '@storybook/addon-docs';
+import VadimStream from '../../../extra-components/nativewind/VadimStream';
+
+
+
+# Learn about gluestack from Youtube guru [notJust.dev](https://www.youtube.com/@notjustdev)
+
+Vadim, popularly known as "not-just-dev" on YouTube, offers insightful and practical videos that explore a wide range of developer tools and frameworks, including Gluestack-UI.
+
+
diff --git a/packages/unstyled/image-viewer/CHANGELOG.md b/packages/unstyled/image-viewer/CHANGELOG.md
index 9376145a1..bc222987e 100644
--- a/packages/unstyled/image-viewer/CHANGELOG.md
+++ b/packages/unstyled/image-viewer/CHANGELOG.md
@@ -1,5 +1,11 @@
# @gluestack-ui/image-viewer
+## 0.0.11
+
+### Patch Changes
+
+- fix: fixed lagging while swipping down image to close ImageViewer
+
## 0.0.10
### Patch Changes
diff --git a/packages/unstyled/image-viewer/package.json b/packages/unstyled/image-viewer/package.json
index e4380880b..036af3fca 100644
--- a/packages/unstyled/image-viewer/package.json
+++ b/packages/unstyled/image-viewer/package.json
@@ -1,6 +1,6 @@
{
"name": "@gluestack-ui/image-viewer",
- "version": "0.0.10",
+ "version": "0.0.11",
"main": "lib/index",
"module": "lib/index",
"types": "lib/index.d.ts",
diff --git a/packages/unstyled/image-viewer/src/ImageViewerContent.tsx b/packages/unstyled/image-viewer/src/ImageViewerContent.tsx
index c4e2237d6..92d127ab1 100644
--- a/packages/unstyled/image-viewer/src/ImageViewerContent.tsx
+++ b/packages/unstyled/image-viewer/src/ImageViewerContent.tsx
@@ -7,7 +7,7 @@ import {
withSpring,
withTiming,
} from 'react-native-reanimated';
-import { Dimensions, StatusBar } from 'react-native';
+import { Dimensions } from 'react-native';
import type { InterfaceImageViewerContentProps } from './types';
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');
@@ -100,13 +100,10 @@ const ImageViewerContent = (
translateY.value = lastTranslateY.value + event.translationY;
} else {
// Normal swipe behavior when not zoomed
- if (Math.abs(event.translationY) > Math.abs(event.translationX)) {
- translateY.value = event.translationY;
- scale.value = Math.max(
- 0.5,
- 1 - Math.abs(event.translationY) / SCREEN_HEIGHT
- );
- }
+ translateY.value = event.translationY;
+ scale.value = withSpring(
+ Math.max(0.5, 1 - Math.abs(event.translationY) / SCREEN_HEIGHT)
+ );
}
})
.onEnd((event: any) => {
@@ -120,7 +117,7 @@ const ImageViewerContent = (
if (scale.value <= 1) {
translateX.value = 0;
translateY.value = withSpring(0);
- scale.value = withSpring(1);
+ scale.value = withTiming(1);
savedScale.value = 1;
} else {
// When zoomed, bound the pan values
@@ -152,8 +149,6 @@ const ImageViewerContent = (
// @ts-ignore
const animatedStyle = useAnimatedStyle(() => {
runOnJS(setScale)(scale.value);
- if (scale.value <= 1) {
- }
return {
transform: [
{ translateX: translateX.value },
@@ -165,7 +160,6 @@ const ImageViewerContent = (
return (
-
{children}