Compare commits
	
		
			No commits in common. "8a1b52749bcfc723439d768cbe38427da8465cc0" and "098777bb020dba30ed245eae9bb06676a2b14775" have entirely different histories.
		
	
	
		
			8a1b52749b
			...
			098777bb02
		
	
		
| @ -8,7 +8,8 @@ body { | ||||
|   display: flex; | ||||
|   flex-direction: row; | ||||
| 
 | ||||
|   padding: 1em; | ||||
|   margin: 1em; | ||||
|   padding: 0; | ||||
| } | ||||
| 
 | ||||
| .Contents { | ||||
| @ -39,7 +40,6 @@ body { | ||||
| } | ||||
| 
 | ||||
| .GalleryItem > img, video { | ||||
|   object-fit: contain; | ||||
|   max-height: 80vh; | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										177
									
								
								src/App.tsx
									
									
									
									
									
								
							
							
						
						
									
										177
									
								
								src/App.tsx
									
									
									
									
									
								
							| @ -1,14 +1,185 @@ | ||||
| import React from 'react'; | ||||
| //import logo from './logo.svg';
 | ||||
| import './App.css'; | ||||
| 
 | ||||
| import Gallery from './Gallery/index'; | ||||
| import { useState, useEffect } from 'react'; | ||||
| 
 | ||||
| function App() { | ||||
|   const [data, setData] = useState(''); | ||||
|   const [category, setCategory] = useState(''); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     post(category, (json: string) => { | ||||
|       setData(json); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   return ( | ||||
|     <div className="App"> | ||||
|       <Gallery /> | ||||
|       <div className="Header"> | ||||
|         {getContents(data, true, category, setCategory)} | ||||
|       </div> | ||||
|       <div className="Contents"> | ||||
|         {getContents(data, false, category, setCategory)} | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| interface galleryItemInfo { | ||||
|   is_dir: boolean; | ||||
|   url: string; | ||||
|   thumbnail_url: string; | ||||
| } | ||||
| 
 | ||||
| function getContents( | ||||
|   data: string, | ||||
|   getDir: boolean, | ||||
|   category: string, | ||||
|   setCategory: (category: string) => void | ||||
| ) { | ||||
|   if (data === '') return; | ||||
| 
 | ||||
|   let obj = null; | ||||
|   try { | ||||
|     obj = JSON.parse(data); | ||||
|   } catch (error: unknown) { | ||||
|     if (!(error instanceof SyntaxError)) { | ||||
|       throw new Error(error as unknown as undefined); | ||||
|     } | ||||
|     return data; | ||||
|   } | ||||
| 
 | ||||
|   return obj | ||||
|     .sort((a: galleryItemInfo, b: galleryItemInfo) => { | ||||
|       if (a.is_dir && b.is_dir) return 0; | ||||
|       if (a.is_dir && !b.is_dir) return -1; | ||||
|       if (!a.is_dir && b.is_dir) return 1; | ||||
|       if (!a.is_dir && !b.is_dir) return 0; | ||||
|     }) | ||||
|     .filter((item: galleryItemInfo) => { | ||||
|       return getDir == item.is_dir; | ||||
|     }) | ||||
|     .map((item: galleryItemInfo, index: number) => { | ||||
|       const url = item.url; | ||||
|       const thumbnail_url = | ||||
|         item.thumbnail_url === null ? item.url : item.thumbnail_url; | ||||
|       let onClick = () => {}; | ||||
|       if (item.is_dir) { | ||||
|         onClick = () => { | ||||
|           const subCategory = getFileName(url); | ||||
| 
 | ||||
|           if (category !== '') category = `${category}/${subCategory}`; | ||||
|           else category = subCategory; | ||||
|           if (subCategory === '..') | ||||
|             category = category.split('/').slice(0, -2).join('/'); | ||||
| 
 | ||||
|           setCategory(category); | ||||
|         }; | ||||
|         return ( | ||||
|           <DirectoryItem | ||||
|             key={index} | ||||
|             thumbnail_url={thumbnail_url} | ||||
|             url={url} | ||||
|             onClick={onClick} | ||||
|           /> | ||||
|         ); | ||||
|       } | ||||
|       if (url.endsWith('.mp4')) { | ||||
|         return ( | ||||
|           <VideoItem | ||||
|             key={index} | ||||
|             thumbnail_url={thumbnail_url} | ||||
|             url={url} | ||||
|             onClick={onClick} | ||||
|           /> | ||||
|         ); | ||||
|       } | ||||
|       return ( | ||||
|         <ImageItem | ||||
|           key={index} | ||||
|           thumbnail_url={thumbnail_url} | ||||
|           url={url} | ||||
|           onClick={onClick} | ||||
|         /> | ||||
|       ); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| interface galleryItem { | ||||
|   url: string; | ||||
|   thumbnail_url: string; | ||||
|   onClick: () => void; | ||||
| } | ||||
| 
 | ||||
| function ImageItem({ thumbnail_url, url }: galleryItem) { | ||||
|   return ( | ||||
|     <div className="GalleryItem"> | ||||
|       <a href={url} target="_blank"> | ||||
|         {getFileName(url)} | ||||
|       </a> | ||||
|       <img src={thumbnail_url} loading="lazy" /> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| function VideoItem({ url }: galleryItem) { | ||||
|   return ( | ||||
|     <div className="GalleryItem"> | ||||
|       <a href={url} target="_blank"> | ||||
|         {getFileName(url)} | ||||
|       </a> | ||||
|       <video controls> | ||||
|         <source src={url} type="video/mp4" /> | ||||
|       </video> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| function DirectoryItem({ url, onClick }: galleryItem) { | ||||
|   let buttonText = getFileName(url); | ||||
|   const isBackButton = buttonText === '..'; | ||||
|   buttonText = isBackButton ? 'Back' : `Category: ${buttonText}`; | ||||
|   const backButtonClass = isBackButton ? 'ParentDirectoryItem' : ''; | ||||
|   return ( | ||||
|     <div className={`DirectoryItem ${backButtonClass}`}> | ||||
|       <button className="DirectoryItem" onClick={onClick}> | ||||
|         {buttonText} | ||||
|       </button> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| function getFileName(string: string): string { | ||||
|   return string.split('/').at(-1) as unknown as string; | ||||
| } | ||||
| 
 | ||||
| function post(category: string, callback: (text: string) => void) { | ||||
|   fetch( | ||||
|     //'http://localhost/photo-viewer-backend/php/get.php',
 | ||||
|     'https://dundun.ddns.net/photo-viewer/photo-viewer-backend/php/get.php', | ||||
|     { | ||||
|       method: 'POST', | ||||
|       headers: { | ||||
|         'Content-Type': 'application/json', | ||||
|       }, | ||||
|       body: JSON.stringify({ | ||||
|         category: category, | ||||
|       }), | ||||
|     } | ||||
|   ) | ||||
|     .then((response) => { | ||||
|       if (!response.ok) { | ||||
|         throw new Error('Network response was not ok'); | ||||
|       } | ||||
|       return response; | ||||
|     }) | ||||
|     .then((response) => response.text()) | ||||
|     .then((data) => { | ||||
|       callback(data as unknown as string); | ||||
|     }) | ||||
|     .catch((error) => { | ||||
|       console.error('There was a problem with the fetch operation:', error); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export default App; | ||||
|  | ||||
| @ -1,167 +0,0 @@ | ||||
| import React from 'react'; | ||||
| import '../App.css'; | ||||
| import { useState, useEffect } from 'react'; | ||||
| 
 | ||||
| function Gallery() { | ||||
|   const [data, setData] = useState(''); | ||||
|   const [category, setCategory] = useState(''); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     post(category, (json: string) => { | ||||
|       setData(json); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   return ( | ||||
|     <div className="Gallery"> | ||||
|       <div className="Header"> | ||||
|         {getContents(data, true, category, setCategory)} | ||||
|       </div> | ||||
|       <div className="Contents"> | ||||
|         {getContents(data, false, category, setCategory)} | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| interface galleryItemInfo { | ||||
|   is_dir: boolean; | ||||
|   url: string; | ||||
|   thumbnail_url: string; | ||||
| } | ||||
| 
 | ||||
| function getContents( | ||||
|   data: string, | ||||
|   getDir: boolean, | ||||
|   category: string, | ||||
|   setCategory: (category: string) => void | ||||
| ) { | ||||
|   if (data === '') return; | ||||
| 
 | ||||
|   let obj = null; | ||||
|   try { | ||||
|     obj = JSON.parse(data); | ||||
|   } catch (error: unknown) { | ||||
|     if (!(error instanceof SyntaxError)) { | ||||
|       throw new Error(error as unknown as undefined); | ||||
|     } | ||||
|     return data; | ||||
|   } | ||||
| 
 | ||||
|   return obj | ||||
|     .sort((a: galleryItemInfo, b: galleryItemInfo) => { | ||||
|       if (a.is_dir && b.is_dir) return 0; | ||||
|       if (a.is_dir && !b.is_dir) return -1; | ||||
|       if (!a.is_dir && b.is_dir) return 1; | ||||
|       if (!a.is_dir && !b.is_dir) return 0; | ||||
|     }) | ||||
|     .filter((item: galleryItemInfo) => { | ||||
|       return getDir == item.is_dir; | ||||
|     }) | ||||
|     .map((item: galleryItemInfo, index: number) => { | ||||
|       const itemProps = { | ||||
|         key: index, | ||||
|         url: item.url, | ||||
|         thumbnail_url: | ||||
|           item.thumbnail_url === null ? item.url : item.thumbnail_url, | ||||
|         onClick: () => {}, | ||||
|       }; | ||||
| 
 | ||||
|       if (item.is_dir) { | ||||
|         itemProps.onClick = () => { | ||||
|           const subCategory = getFileName(itemProps.url); | ||||
| 
 | ||||
|           if (category !== '') category = `${category}/${subCategory}`; | ||||
|           else category = subCategory; | ||||
|           if (subCategory === '..') | ||||
|             category = category.split('/').slice(0, -2).join('/'); | ||||
| 
 | ||||
|           setCategory(category); | ||||
|         }; | ||||
|         return <DirectoryItem {...itemProps} />; | ||||
|       } | ||||
|       if (itemProps.url.endsWith('.mp4')) { | ||||
|         return <VideoItem {...itemProps} />; | ||||
|       } | ||||
|       return <ImageItem {...itemProps} />; | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| interface galleryItem { | ||||
|   url: string; | ||||
|   thumbnail_url: string; | ||||
|   onClick: () => void; | ||||
| } | ||||
| 
 | ||||
| function ImageItem({ thumbnail_url, url }: galleryItem) { | ||||
|   return ( | ||||
|     <div className="GalleryItem"> | ||||
|       <a href={url} target="_blank"> | ||||
|         {getFileName(url)} | ||||
|       </a> | ||||
|       <img src={thumbnail_url} loading="lazy" /> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| function VideoItem({ url }: galleryItem) { | ||||
|   return ( | ||||
|     <div className="GalleryItem"> | ||||
|       <a href={url} target="_blank"> | ||||
|         {getFileName(url)} | ||||
|       </a> | ||||
|       <video controls> | ||||
|         <source src={url} type="video/mp4" /> | ||||
|       </video> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| function DirectoryItem({ url, onClick }: galleryItem) { | ||||
|   let buttonText = getFileName(url); | ||||
|   const isBackButton = buttonText === '..'; | ||||
|   buttonText = isBackButton ? 'Back' : `Category: ${buttonText}`; | ||||
|   const backButtonClass = isBackButton ? 'ParentDirectoryItem' : ''; | ||||
|   return ( | ||||
|     <div className={`DirectoryItem ${backButtonClass}`}> | ||||
|       <button className="DirectoryItem" onClick={onClick}> | ||||
|         {buttonText} | ||||
|       </button> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| function getFileName(string: string): string { | ||||
|   return string.split('/').at(-1) as unknown as string; | ||||
| } | ||||
| 
 | ||||
| function post(category: string, callback: (text: string) => void) { | ||||
|   fetch( | ||||
|     'http://localhost/photo-viewer-backend/php/get.php', | ||||
|     //'https://dundun.ddns.net/photo-viewer/photo-viewer-backend/php/get.php',
 | ||||
|     { | ||||
|       method: 'POST', | ||||
|       headers: { | ||||
|         'Content-Type': 'application/json', | ||||
|       }, | ||||
|       body: JSON.stringify({ | ||||
|         category: category, | ||||
|       }), | ||||
|     } | ||||
|   ) | ||||
|     .then((response) => { | ||||
|       if (!response.ok) { | ||||
|         throw new Error('Network response was not ok'); | ||||
|       } | ||||
|       return response; | ||||
|     }) | ||||
|     .then((response) => response.text()) | ||||
|     .then((data) => { | ||||
|       callback(data as unknown as string); | ||||
|     }) | ||||
|     .catch((error) => { | ||||
|       console.error('There was a problem with the fetch operation:', error); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export default Gallery; | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user