Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion example/src/App.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import React, { useState } from 'react';
import './App.css';
import Stories, { WithSeeMore } from 'react-insta-stories'

function App() {
const [pause, setPause] = useState(false)

return (
<div className="App">
<div className="left">
Expand Down Expand Up @@ -64,12 +66,16 @@ function App() {
keyboardNavigation
defaultInterval={8000}
stories={stories2}
isPaused={pause}
onStoryEnd={(s, st) => console.log('story ended', s, st)}
onAllStoriesEnd={(s, st) => console.log('all stories ended', s, st)}
onStoryStart={(s, st) => console.log('story started', s, st)}
storyContainerStyles={{ borderRadius: 8, overflow: 'hidden' }}
/>
</div>
<div>
<button onClick={() => setPause(prev => !prev)}>{pause ? 'Resume' : 'Pause'} Story</button>
</div>
</div>
);
}
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-insta-stories",
"version": "2.4.2",
"name": "@reiiyuki/react-insta-stories",
"version": "2.4.5",
"description": "A React component for Instagram like stories",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -55,4 +55,4 @@
"react": "^16.8.2 || 17.x || 18.x"
},
"dependencies": {}
}
}
43 changes: 27 additions & 16 deletions src/components/Container.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useContext, useState, useRef, useEffect } from 'react'
import React, { useContext, useState, useRef, useEffect, MouseEvent, TouchEvent } from 'react'
import GlobalContext from './../context/Global'
import StoriesContext from './../context/Stories'
import ProgressContext from './../context/Progress'
Expand All @@ -15,13 +15,13 @@ export default function () {
let mousedownId = useRef<any>();
let isMounted = useRef<boolean>(true);

const { width, height, loop, currentIndex, isPaused, keyboardNavigation, preventDefault, storyContainerStyles = {} } = useContext<GlobalCtx>(GlobalContext);
const { width, height, loop, currentIndex, isPaused, keyboardNavigation, preventDefault, storyContainerStyles = {}, onAllStoriesEnd } = useContext<GlobalCtx>(GlobalContext);
const { stories } = useContext<StoriesContextInterface>(StoriesContext);

useEffect(() => {
if (typeof currentIndex === 'number') {
if (currentIndex >= 0 && currentIndex < stories.length) {
setCurrentIdWrapper(() => currentIndex)
setCurrentId(() => currentIndex)
} else {
console.error('Index out of bounds. Current index was set to value more than the length of stories array.', currentIndex)
}
Expand Down Expand Up @@ -51,6 +51,11 @@ export default function () {
}
}, []);

function isTouchDevice() {
return 'ontouchstart' in window // works on most browsers
|| navigator.maxTouchPoints; // works on IE10/11 and Surface
}

const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'ArrowLeft') {
previous()
Expand All @@ -65,13 +70,10 @@ export default function () {
setBufferAction(!!bufferAction)
}

const setCurrentIdWrapper = (callback) => {
setCurrentId(callback);
toggleState('pause', true);
}

const previous = () => {
setCurrentIdWrapper(prev => prev > 0 ? prev - 1 : prev)
if(currentId !== 0){
setCurrentId(prev => prev - 1)
}
}

const next = () => {
Expand All @@ -85,24 +87,33 @@ export default function () {
};

const updateNextStoryIdForLoop = () => {
setCurrentIdWrapper(prev => (prev + 1) % stories.length)
setCurrentId(prev => (prev + 1) % stories.length)
}

const updateNextStoryId = () => {
setCurrentIdWrapper(prev => {
if (prev < stories.length - 1) return prev + 1
return prev
})
if(currentId < stories.length - 1){
setCurrentId(prev => prev + 1)
} else{
onAllStoriesEnd()
}
}

const debouncePause = (e: React.MouseEvent | React.TouchEvent) => {
const debouncePause = (e: MouseEvent | TouchEvent) => {
if (isTouchDevice() && e.nativeEvent instanceof MouseEvent) {
return
}

e.preventDefault()
mousedownId.current = setTimeout(() => {
toggleState('pause')
}, 200)
}

const mouseUp = (type: string) => (e: React.MouseEvent | React.TouchEvent) => {
const mouseUp = (type: string) => (e: MouseEvent | TouchEvent) => {
if (isTouchDevice() && e.nativeEvent instanceof MouseEvent) {
return
}

e.preventDefault()
mousedownId.current && clearTimeout(mousedownId.current)
if (pause) {
Expand Down
12 changes: 7 additions & 5 deletions src/components/ProgressArray.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import GlobalContext from './../context/Global'
import StoriesContext from './../context/Stories'

export default () => {
let animationFrameId = useRef<number>()
const pauseRef = useRef(false);

const [count, setCount] = useState<number>(0)
const { currentId, next, videoDuration, pause } = useContext<ProgressContext>(ProgressCtx)
const { defaultInterval, onStoryEnd, onStoryStart, onAllStoriesEnd } = useContext<GlobalCtx>(GlobalContext);
Expand All @@ -16,6 +19,7 @@ export default () => {
}, [currentId, stories])

useEffect(() => {
pauseRef.current = pause
if (!pause) {
animationFrameId.current = requestAnimationFrame(incrementCount)
}
Expand All @@ -24,11 +28,10 @@ export default () => {
}
}, [currentId, pause])

let animationFrameId = useRef<number>()

let countCopy = count;
const incrementCount = () => {
if (countCopy === 0) storyStartCallback()
if (pauseRef.current) return
setCount((count: number) => {
const interval = getCurrentInterval()
countCopy = count + (100 / ((interval / 1000) * 60))
Expand Down Expand Up @@ -65,14 +68,14 @@ export default () => {
}

return (
<div style={styles.progressArr}>
<div style={{...styles.progressArr}}>
{stories.map((_, i) =>
<Progress
key={i}
count={count}
width={1 / stories.length}
active={i === currentId ? 1 : (i < currentId ? 2 : 0)}
/>)}
/>)}
</div>
)
}
Expand All @@ -89,6 +92,5 @@ const styles = {
paddingTop: 7,
alignSelf: 'center',
zIndex: 1001,
filter: 'drop-shadow(0 1px 8px #222)'
}
}
6 changes: 4 additions & 2 deletions src/renderers/AutoPlayContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { Renderer, Tester } from './../interfaces';

export const renderer: Renderer = (props) => {
React.useEffect(() => {
props.action('play');
}, [props.story])
if (!props.isPaused) {
props.action('play');
}
}, [props.story, props.isPaused])
const Content = props.story.originalContent;
return <Content {...props} />
}
Expand Down
8 changes: 5 additions & 3 deletions src/renderers/Default.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import * as React from 'react';
import { Renderer, Tester } from './../interfaces';

export const renderer: Renderer = ({ story, action }) => {
export const renderer: Renderer = ({ story, action, isPaused }) => {
React.useEffect(() => {
action('play');
}, [story])
if (!isPaused) {
action('play');
}
}, [story, isPaused])

return <div style={styles.storyContent}>
<p style={styles.text}>This story could not be loaded.</p>
Expand Down
7 changes: 6 additions & 1 deletion src/renderers/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ export const renderer: Renderer = ({ story, action, isPaused, config }) => {

const imageLoaded = () => {
setLoaded(true);
action('play');
}

React.useEffect(() => {
if (loaded && !isPaused) {
action('play')
}
}, [loaded, isPaused])

return <WithHeader story={story} globalHeader={config.header}>
<WithSeeMore story={story} action={action}>
<div>
Expand Down