Image gallery with Ionic React using Ionic-Swipe - reactjs

My client requested an image gallery feature. Such that I will have an array of images and on clicking each image, I will get like a modal that shows all the images available one by one. I want to achieve this with the Ionic Swiper Component. The example below is for Ionic-Angular, I need Ionic-React.
https://www.youtube.com/watch?v=BGoL0uWRTrY
Is there a way to open the image as a gallery and have zoom, prev and next swipe functionality?
<div className="mt-2">
<IonSlides ref={slideRef} options={slideOpts}>
{bridImages.map((image, idx) => (
<IonSlide key={idx} className="img-container">
<img
src={image.url}
alt={image.alt}
/>
</IonSlide>
))}
</IonSlides>
</div>
Or if there's any other library that is mobile friendly and can also work with Ionic-React, please let me know.

<IonSlides
options={slideOpts}
ref={mySlides}
onIonSlideDidChange={handleSlideChange}
>
list with the event handler and get the swiper object which holds the activeIndex
const handleSlideChange = async () => {
const swiper = await mySlides.current.getSwiper();
console.log("Slide Index", swiper.activeIndex);
// setDisablePrevBtn(swiper.isBeginning);
// setDisableNextBtn(swiper.isEnd);
};
See working project - https://codesandbox.io/s/ionic-react-slides-jq57g
See video describing code and more - https://youtu.be/mCkrZYIbH10

Related

React is not dynamically loading images

I am trying to dynamically load images in a map function but it won't return anything.
I can get it to load a single image if I import it at the top of the page and hardcode the src but I have tried every solution I can find to do it dynamically and none of them work.
Here is what the code looks like. I am passing props with the title of the PNGs but nothing will load.
const Project = (props) => {
const proj = props.proj
return (
<div >
{proj.map(({title, id}) =>{
return(
<div>
<div className="..." key={id}>
<img
src={require(`../Assets/${title}.png`).default}
alt={`Image of ${title} hompage`}
className='object-cover'
/>
</div>
</div>
)
})}
</div>
)
}
export default Project;
The app was set up with create react app. I tried setting up a library but it didn't load the images either.

Keep component scrolled to bottom

I have made a mini chat box on an application that sits about mid way down the site on the 3rd section. I'd like to have this chat box always scrolled to the bottom when people type. I am currently using the bellow:
ChatMessage.js
const messagesEndRef = useRef(null)
const scrollToBottom = () => {messagesEndRef.current.scrollIntoView({ behavior: "smooth", block: 'nearest', inline: 'start' })}
useEffect(scrollToBottom, [messageUser]);
return (
<>
<div className='text-left my-2 mx-2'>
<span className={`inline-block pr-4 pl-2 py-2 ${messageClass} rounded-lg`}>
<span className='text-xs'>{username}</span><br />
<span className='text-md font-bold'>{text}</span>
</span>
</div>
<div ref={messagesEndRef} />
</>
)
ChatBox.js
{messages && messages.map(msg => <ChatMessage key={msg.id} messages={msg} user={props.user} /> )}
This solution has an issue when the user is actually not on the chat box page. If the user is to scroll to the top or bottom of the website, each time a message occurs the user if forced up to the chat box. Is there a way that I can have just the chatbox itself scroll to bottom without affecting the users exploring the rest of the site?
I tried thinking of using an iFrame or something but that didn't seem like it would be the best solution.
Thanks in advance.
i think ChatBox component should have be set position: fixed and stay on bottom and user can minimize or expand ChatMessage component every they want chat or not.

How to change image using hover in jsx

I am having a hard time figuring how to switch images inside react. I need the image to switch when I hover over a certain area. The area detection was created by someone else but I am been able to place my first image as the default. But I need to figure out how to change the image when I hover over the area.
This is what the images are imported as
import suitcase_open from '../images/suitcase_openEMPTY.png';
import box_open from '../images/discardbox_open.png';
import suitcase_closed from '../images/suitcase_closed.png';
import box_closed from '../images/discardbox_closed.png';
These are the two divs where I need to change the image
<div className='bound bound0'>
<img
id = 'box'
src = {box_closed}
/>
</div>
<span id='discard'>discard</span>
<div className='bound bound1' >
<img id = 'suitcase' src = {suitcase_closed} />
</div>
<span id='keep'>keep</span>
I was thinking about using onMouseOver but I do not know how to implement the change for the image source. I need to change from the closed to open versions.
You will likely need some state to track whether the suitcase is open or closed. You can then use a ternary operator to display the right image. The following code assumes you might also want to set it back to closed when mousing out.
function App() {
const [open, setOpen] = useState(false);
return (
<img
id='suitcase'
src={open ? suitcase_open : suitcase_closed}
onMouseOver={() => setOpen(true)}
onMouseOut={() => setOpen(false)}
/>
)
}

React animate leaving div content

I'm using React and React-Spring to animate a questionnaire app.
I want the questionnaire to animate the leaving/enter of a question when the user answer one.
I'm using React for the app and try to use React-Spring to animate the transitions. The issue is that when the user is answering a question, the question component is updated with the new content before it leaving.
To simplify it, the Question component look like this:
export default function Question({question, onAnswer}) {
const [answer, setAnswer] = useState(null);
return (
<animated.div ...>
{question.title}
<select>...{quesiton.options}...</select>
<button onClick={() => onAnswer(question.id, answer)}>Next</button>
</animated.div>
);
}
I create a Code Sandbox that illustrates my issue:
https://codesandbox.io/s/nostalgic-swartz-lhkj0?file=/src/AnimatedComponent.js
How should I handle this? couldn't find any example on the web
Thanks!
You should use the item property in the transition map instead of using the text directly in the animated.div.
{transitions.map(
({ item, key, props }) =>
item && (
<animated.div key={key} style={props}>
{item}
</animated.div>
)
)}

How to play video in react image gallery when clicked for e-commerce project? Need to play video in the carousel itself

I have an image slider built using react image gallery and populated with images from backend for an e-commerce project. When there is a product with video, show video image and when clicked on the image play video inside the carousel.
I had tried to implement react image gallery demo code given but unable to get a successful result.
<div className="leftSlider">
<ImageGallery ref={el => this.imagegallery = el}
thumbnailPosition={window.matchMedia('(min-width: 600px)').matches ? 'left' : 'bottom'}
showFullscreenButton={false}
showPlayButton={false}
showNav={false}
renderItem={this.imageHover}
showThumbnails={this.showThumbnails(Object.keys(this.state.images) ? this.state.images[selectedVariant] : [])}
items={Object.keys(this.state.images) ? this.state.images[selectedVariant] : []}
onSlide={(slide) => this.onslide(slide)}/></div>
Expected result is exactly the same like shown in the demo of react-image-gallery
https://www.npmjs.com/package/react-image-gallery
There is an example created by package author where he uses custom itemRender for video media.
He is rendering video on description click, but you can of course change it to immediately render video in the slider.
Whole application can be seen:
https://github.com/xiaolin/react-image-gallery/blob/master/example/app.js
// items
{
thumbnail: `${PREFIX_URL}4v.jpg`,
original: `${PREFIX_URL}4v.jpg`,
embedUrl: 'https://www.youtube.com/embed/4pSzhZ76GdM?autoplay=1&showinfo=0',
description: 'Render custom slides within the gallery',
renderItem: this._renderVideo.bind(this)
},
_renderVideo(item) {
return (
<div>
{
this.state.showVideo[item.embedUrl] ?
<div className='video-wrapper'>
<a
className='close-video'
onClick={this._toggleShowVideo.bind(this, item.embedUrl)}
>
</a>
<iframe
width='560'
height='315'
src={item.embedUrl}
frameBorder='0'
allowFullScreen
>
</iframe>
</div>
:
<a onClick={this._toggleShowVideo.bind(this, item.embedUrl)}>
<div className='play-button'></div>
<img className='image-gallery-image' src={item.original} />
{
item.description &&
<span
className='image-gallery-description'
style={{right: '0', left: 'initial'}}
>
{item.description}
</span>
}
</a>
}
</div>
);
}

Resources