diff --git a/README.md b/README.md index 8d42a46..fb3497e 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ export default YourComponent; `progressContainerStyle` | ViewStyle | | Additional styles for the story progress container `hideAvatarList` | boolean | false | A boolean indicating whether to hide avatar scroll list `hideElementsOnLongPress` | boolean | false | A boolean indicating whether to hide all elements when story is paused by long press + `loopingStories` | `'none'` | `'onlyLast'` | `'all'` | `'none'` | A string indicating whether to continue stories after last story was shown. If set to `'none'` modal will be closed after all stories were played, if set to `'onlyLast'` stories will loop on last user only after all stories were played. If set to `'all'` stories will play from beginning after all stories were played. `footerComponent` | ReactNode | | A custom component, such as a floating element, that can be added to the modal. `imageOverlayView` | ReactNode | | Image overlay compontent `onShow` | ( id: string ) => void | | Callback when a story is shown. diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 16c06f7..873c3b9 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -18,7 +18,7 @@ import ModalStyles from './Modal.styles'; const StoryModal = forwardRef( ( { stories, seenStories, duration, videoDuration, storyAvatarSize, textStyle, containerStyle, backgroundColor, videoProps, closeIconColor, modalAnimationDuration = STORY_ANIMATION_DURATION, - storyAnimationDuration = STORY_ANIMATION_DURATION, hideElementsOnLongPress, + storyAnimationDuration = STORY_ANIMATION_DURATION, hideElementsOnLongPress, loopingStories = 'none', onLoad, onShow, onHide, onSeenStoriesChange, onSwipeUp, onStoryStart, onStoryEnd, footerComponent, ...props }, ref ) => { @@ -122,6 +122,7 @@ const StoryModal = forwardRef( ( { animated = true, sameUser = false, previousUser?: string, + index?: number, ) => { 'worklet'; @@ -151,7 +152,7 @@ const StoryModal = forwardRef( ( { ( story ) => story.id === seenStories.value[id], ) ?? 0 ) + 1 ); const userStories = stories[newUserIndex]?.stories; - const newStory = userStories?.[newStoryIndex]?.id ?? userStories?.[0]?.id; + const newStory = userStories?.[index ?? newStoryIndex]?.id ?? userStories?.[0]?.id; currentStory.value = newStory; if ( onStoryStart ) { @@ -178,6 +179,14 @@ const StoryModal = forwardRef( ( { scrollTo( nextUserId.value ); + } else if ( stories[0]?.id && loopingStories === 'all' ) { + + scrollTo( stories[0].id, false ); + + } else if ( userId.value && loopingStories === 'onlyLast' ) { + + scrollTo( userId.value, false, undefined, undefined, 0 ); + } else { onClose(); diff --git a/src/core/dto/componentsDTO.ts b/src/core/dto/componentsDTO.ts index 89b53e6..f19479e 100644 --- a/src/core/dto/componentsDTO.ts +++ b/src/core/dto/componentsDTO.ts @@ -44,6 +44,7 @@ export interface StoryModalProps { imageProps?: ImageProps; footerComponent?: ReactNode; hideElementsOnLongPress?: boolean; + loopingStories?: 'none' | 'all' | 'onlyLast'; onLoad: () => void; onShow?: ( id: string ) => void; onHide?: ( id: string ) => void; diff --git a/src/core/dto/instagramStoriesDTO.ts b/src/core/dto/instagramStoriesDTO.ts index 1ce157c..7020e4f 100644 --- a/src/core/dto/instagramStoriesDTO.ts +++ b/src/core/dto/instagramStoriesDTO.ts @@ -73,6 +73,7 @@ export interface InstagramStoriesProps { hideAvatarList?: boolean; imageOverlayView?: ReactNode; hideElementsOnLongPress?: boolean; + loopingStories?: 'none' | 'all' | 'onlyLast'; onShow?: ( id: string ) => void; onHide?: ( id: string ) => void; onSwipeUp?: ( userId?: string, storyId?: string ) => void;