import { useState, useEffect, useRef, useReducer } from 'react' import { debounce } from 'lodash' import axios from 'axios' import ReactModal from 'react-modal' import Image from "./Image" export default function GetImages() { const [render, setRender] = useState(false); const [images, setImages] = useState([]) const [searchTerm, setSearchTerm] = useState('') const [loading, setLoading] = useState(true) const [error, setError] = useState(false) const [sort, setSort] = useState('modified') const [type, setType] = useState('lora') const [renderMore, setRenderMore] = useState(false); const [modalIsOpen, setIsOpen] = useState(false) const [moreImages, setMoreImages] = useState([]) const [moreLoading, setMoreLoading] = useState(true) const [moreError, setMoreError] = useState(false) const [moreIndex, setMoreIndex] = useState(null) const [moreDocument, setMoreDocument] = useState(null) const inputReference = useRef(null) ReactModal.setAppElement('#root') const customModalStyle = { overlay: { backgroundColor: 'rgba(0,0,0,0.97)', }, content: { maxHeight: '90%', maxWidth: '95%', top: '50%', left: '50%', right: 'auto', bottom: 'auto', marginRight: '-50%', transform: 'translate(-50%, -50%)', backgroundColor: 'rgba(0,0,0,0.25)', border: 'none', scrollbarWidth: 'thin', scrollbarColor: '#141414 #000' }, } const sortImages = (dataArray) => { if (sort == "random") { for (let i = dataArray.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [dataArray[i], dataArray[j]] = [dataArray[j], dataArray[i]]; } } else { dataArray.sort(function(a, b){ if (sort == "modified") { return b.mtimeMs - a.mtimeMs } else { return a.filename - b.filename } }) } return dataArray } const fetchImages = () => { setLoading(true) setMoreLoading(true) setImages([]) setMoreImages([]) axios.get(`http://localhost:3000/images?type=${type}&search=${searchTerm}`) .then(response => { if (sort != "name") { setImages(sortImages(response.data)) } else { setImages(response.data) } setLoading(false) setError(false) }) .catch(err => { console.log(err) setLoading(false) setError(true) }) } const fetchMoreImages = () => { setMoreLoading(true) setMoreImages([]) const image = images[moreIndex] const query = encodeURIComponent(image.path + image.filename) axios.get(`http://localhost:3000/moreImages?type=${type}&search=${query}`) .then(response => { setMoreLoading(false) setMoreError(false) if (sort != "name") { setMoreImages(sortImages(response.data)) } else { setMoreImages(response.data) } openModal() }) .catch(err => { console.log(err) setMoreLoading(false) setMoreError(true) }) } const handleSearchInputChange = debounce((e) => { setSearchTerm(e.target.value) }, 500) const handleSortChange = (sortOption) => { setSort(sortOption) // Triggering refresh manually to allow for sorting option reclicks setRender(!render) } const handleTypeChange = (typeOption) => { setType(typeOption) // Prevent issue with clicking the same image (eg. 3rd) on each tab not loading. setMoreIndex(null) } const openModal = () => { setIsOpen(true) } const closeModal = () => { setIsOpen(false) } const handleFolderClick = (index) => { if (moreIndex != null && moreIndex == index && !moreDocument) { openModal() } else { setMoreDocument(null) setMoreLoading(true) setMoreIndex(index) setRenderMore(!renderMore) openModal() } } const handleDocumentClick = (index) => { setMoreLoading(true) setMoreImages([]) setMoreDocument(null) const image = images[index] const file = (type == "poses") ? 'readme.txt' : encodeURIComponent(image.filename.substring(0, image.filename.lastIndexOf('.')) + '.txt') axios.get(`http://localhost:3000/${image.path.replaceAll('#','%23')}${file}`) .then(response => { setMoreLoading(false) setMoreError(false) setMoreDocument(response.data) setMoreIndex(index) openModal() }) .catch(err => { if (err.response.status == "404") { setMoreLoading(false) setMoreError(false) setMoreDocument('No additional information found.') setMoreIndex(index) openModal() } else { console.log(err) setMoreLoading(false) setMoreError(true) openModal() } }) } const handleModalKeys = (event) => { event.stopPropagation() if (event.key == "ArrowLeft") { if (moreIndex > 0) { setMoreLoading(true) setMoreDocument(null) setMoreIndex(moreIndex - 1) setRenderMore(!renderMore) } } else if (event.key == "ArrowRight") { if (moreIndex+1 < images.length) { setMoreLoading(true) setMoreDocument(null) setMoreIndex(moreIndex + 1) setRenderMore(!renderMore) } } else if (event.key == "ArrowDown") { handleDocumentClick(moreIndex) } else if (event.key == "ArrowUp") { handleFolderClick(moreIndex) } else if (event.key == "Escape") { closeModal() } } useEffect(() => { fetchImages() }, [searchTerm, type, render]) useEffect(() => { if (moreIndex != null) { fetchMoreImages() } }, [renderMore]) return ( <>
{loading &&
} {error &&

There was an error loading the images.

} {!loading && !error && images.map((image, index) => ( ))}
{ inputReference.current.focus() }} onRequestClose={closeModal} preventScroll={true} style={customModalStyle} >
{moreLoading &&
} {moreError &&

There was an error during loading.

} {!moreLoading && !moreError && images[moreIndex] && moreImages[0] && !moreDocument &&
{images[moreIndex].path + images[moreIndex].filename}
}
{!moreLoading && !moreError && images[moreIndex] && moreImages[0] && !moreDocument && moreImages.map((image, index) => (
{navigator.clipboard.writeText(images[moreIndex].prompt)}}>
))} {!moreLoading && !moreError && moreDocument && images[moreIndex] &&
										File: {images[moreIndex].filename}{
} {type != "styles" && `Keywords: ${images[moreIndex].keywords}\n`} {type != "styles" && `Weight: ${images[moreIndex].weight}`} {type == "styles" && `Prompt: ${images[moreIndex].prompt}`}
{moreDocument}
}
) }