Compare commits
2 Commits
098777bb02
...
8a1b52749b
Author | SHA1 | Date | |
---|---|---|---|
8a1b52749b | |||
d959c004dd |
@ -8,8 +8,7 @@ body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
margin: 1em;
|
||||
padding: 0;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.Contents {
|
||||
@ -40,6 +39,7 @@ body {
|
||||
}
|
||||
|
||||
.GalleryItem > img, video {
|
||||
object-fit: contain;
|
||||
max-height: 80vh;
|
||||
}
|
||||
|
||||
|
177
src/App.tsx
177
src/App.tsx
@ -1,185 +1,14 @@
|
||||
import React from 'react';
|
||||
//import logo from './logo.svg';
|
||||
import './App.css';
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
import Gallery from './Gallery/index';
|
||||
|
||||
function App() {
|
||||
const [data, setData] = useState('');
|
||||
const [category, setCategory] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
post(category, (json: string) => {
|
||||
setData(json);
|
||||
});
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<div className="Header">
|
||||
{getContents(data, true, category, setCategory)}
|
||||
</div>
|
||||
<div className="Contents">
|
||||
{getContents(data, false, category, setCategory)}
|
||||
</div>
|
||||
<Gallery />
|
||||
</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;
|
||||
|
167
src/Gallery/index.tsx
Normal file
167
src/Gallery/index.tsx
Normal file
@ -0,0 +1,167 @@
|
||||
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