Implement basic placeholder skeleton when loading

This commit is contained in:
Sheldon Lee 2023-11-24 19:24:40 +08:00
parent 07dd094d6b
commit f3d7c7abf2
4 changed files with 59 additions and 12 deletions

View File

@ -63,7 +63,16 @@ body {
background-color: #0056b3; background-color: #0056b3;
} }
.PlaceholderItem > button,
.ParentDirectoryItem > button { .ParentDirectoryItem > button {
background-color: #4D4F5D; background-color: #4D4F5D;
} }
.PlaceholderItem > a {
height: 1em;
}
.PlaceholderItem > button {
height: calc(16px + 10px * 2);
width: 6em;
}

View File

@ -1,4 +1,3 @@
import React from 'react';
import './App.css'; import './App.css';
import Gallery from './Gallery/index'; import Gallery from './Gallery/index';

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import '../App.css'; import '../App.css';
import placeholderPng from './placeholder.png';
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
function Gallery() { function Gallery() {
@ -13,7 +14,7 @@ function Gallery() {
}, [category]); }, [category]);
const updateCategory = (category: string) => { const updateCategory = (category: string) => {
setData([]); setData(getPlaceholderData);
setCategory(category); setCategory(category);
}; };
@ -33,6 +34,8 @@ interface galleryItemInfo {
is_dir: boolean; is_dir: boolean;
url: string; url: string;
thumbnail_url: string; thumbnail_url: string;
isPlaceholder: boolean;
} }
function Contents( function Contents(
@ -61,6 +64,7 @@ function Contents(
thumbnail_url: thumbnail_url:
item.thumbnail_url === null ? item.url : item.thumbnail_url, item.thumbnail_url === null ? item.url : item.thumbnail_url,
onClick: () => {}, onClick: () => {},
isPlaceholder: item.isPlaceholder,
}; };
if (item.is_dir) { if (item.is_dir) {
@ -87,11 +91,13 @@ interface galleryItem {
url: string; url: string;
thumbnail_url: string; thumbnail_url: string;
onClick: () => void; onClick: () => void;
isPlaceholder: boolean;
} }
function ImageItem({ thumbnail_url, url }: galleryItem) { function ImageItem({ thumbnail_url, url, isPlaceholder }: galleryItem) {
const placeholderClass = isPlaceholder ? 'PlaceholderItem' : '';
return ( return (
<div className="GalleryItem"> <div className={`GalleryItem ${placeholderClass}`}>
<a href={url} target="_blank"> <a href={url} target="_blank">
{getFileName(url)} {getFileName(url)}
</a> </a>
@ -113,16 +119,15 @@ function VideoItem({ url }: galleryItem) {
); );
} }
function DirectoryItem({ url, onClick }: galleryItem) { function DirectoryItem({ url, onClick, isPlaceholder }: galleryItem) {
let buttonText = getFileName(url); let buttonText = getFileName(url);
const isBackButton = buttonText === '..'; const isBackButton = buttonText === '..';
buttonText = isBackButton ? 'Back' : `Category: ${buttonText}`; const placeholderClass = isPlaceholder ? 'PlaceholderItem' : '';
buttonText = isBackButton ? 'Back' : `${buttonText}`;
const backButtonClass = isBackButton ? 'ParentDirectoryItem' : ''; const backButtonClass = isBackButton ? 'ParentDirectoryItem' : '';
return ( return (
<div className={`DirectoryItem ${backButtonClass}`}> <div className={`DirectoryItem ${backButtonClass} ${placeholderClass}`}>
<button className="DirectoryItem" onClick={onClick}> <button onClick={onClick}>{buttonText}</button>
{buttonText}
</button>
</div> </div>
); );
} }
@ -131,14 +136,40 @@ function getFileName(string: string): string {
return string.split('/').at(-1) as unknown as string; return string.split('/').at(-1) as unknown as string;
} }
function getPlaceholderData(): galleryItemInfo[] {
const placeholderDir = (): galleryItemInfo => {
return {
is_dir: true,
url: '',
thumbnail_url: '',
isPlaceholder: true,
};
};
const placeholderImg = (): galleryItemInfo => {
return {
is_dir: false,
url: '',
thumbnail_url: `${placeholderPng}`,
isPlaceholder: true,
};
};
return [
placeholderDir(),
placeholderDir(),
placeholderImg(),
placeholderImg(),
placeholderImg(),
];
}
async function post( async function post(
category: string, category: string,
setDataCallback: (data: galleryItemInfo[]) => void setDataCallback: (data: galleryItemInfo[]) => void
) { ) {
try { try {
const response = await fetch( const response = await fetch(
'http://localhost/photo-viewer-backend/php/get.php', //'http://localhost/photo-viewer-backend/php/get.php',
//'https://dundun.ddns.net/photo-viewer/photo-viewer-backend/php/get.php', 'https://dundun.ddns.net/photo-viewer/photo-viewer-backend/php/get.php',
{ {
method: 'POST', method: 'POST',
headers: { headers: {
@ -152,6 +183,14 @@ async function post(
setDataCallback(await response.json()); setDataCallback(await response.json());
} catch (error) { } catch (error) {
console.error('Error fetching data: ', error); console.error('Error fetching data: ', error);
setDataCallback([
{
is_dir: false,
url: 'error_fetching',
thumbnail_url: '',
isPlaceholder: false,
},
]);
} }
} }

BIN
src/Gallery/placeholder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB