react-scripts 4 on React 17 no longer builds on a current toolchain. Move to Vite 8 with React 19 and TypeScript 7, and take the same shape as the other converted sites. - react-router-dom v5 -> react-router v8: Switch/Redirect become Routes/Navigate, and withRouter gives way to useLocation and useNavigate; the original /modules/... addresses are kept - swap the unmaintained dependencies: axios -> ky, react-html-parser -> @orrisroot/react-html-parser, react-ga -> react-ga4, react-helmet -> @dr.pogodin/react-helmet, moment -> date-fns, react-spinner-material -> a CSS spinner, and a local HashLink in place of react-router-hash-link - drop react-app-polyfill, the jest setup, xregexp and the unused async-lock, rc-tree, react-overlays and react-image-lightbox - replace ESLint with Biome, yarn with npm, and match the other sites' tsconfigs and sanitize.css base stylesheet - serve static-contents/ next to the repository with sirv in the dev and preview servers, keeping it out of dist/ - convert the page components to function components; each module loads its index once, sharing the request under StrictMode - resolve relative links in page bodies the way a browser does, since react-router 8 resolves them against the route hierarchy - fix the glossary search restricted to a category, whose query matched nothing - set the GA4 measurement ID replacing the shut-down UA property - correct the keywords meta tag copied from dynamicbrain - write down the data layout and the deployment procedure
83 lines
2.9 KiB
TypeScript
83 lines
2.9 KiB
TypeScript
import type { ReactNode } from 'react';
|
|
import XoopsCode from '../../common/lib/XoopsCode';
|
|
import type { MultiLang } from '../../config';
|
|
import Functions from '../../functions';
|
|
import type CosmoDbContext from './CosmoDbContext';
|
|
import type { CosmoDbBasicData, CosmoDbListData } from './CosmoDbContext';
|
|
import CosmoDbListSortBar from './CosmoDbListSortBar';
|
|
import CosmoDbUtils from './CosmoDbUtils';
|
|
|
|
interface Props {
|
|
lang: MultiLang;
|
|
context: CosmoDbContext;
|
|
list: CosmoDbListData;
|
|
params: URLSearchParams;
|
|
data: CosmoDbBasicData[];
|
|
}
|
|
|
|
const CosmoDbListThumbnailView = (props: Props) => {
|
|
const { lang, context, list, params, data } = props;
|
|
const size = CosmoDbUtils.getThumbnailSize(params.get('size'), list.thumb_size);
|
|
if (size === null) {
|
|
return null;
|
|
}
|
|
const rows: ReactNode[] = [];
|
|
let cols: ReactNode[] = [];
|
|
let col = 1;
|
|
const thumbRegex = new RegExp(`^${list.thumb_dir}/`);
|
|
const imgStyles: string[] = [];
|
|
if (size.height > 0) {
|
|
imgStyles.push(`height:${size.height}px`);
|
|
}
|
|
if (size.width > 0) {
|
|
imgStyles.push(`width:${size.width}px`);
|
|
}
|
|
const imgStyle = imgStyles.length !== 0 ? `style="${imgStyles.join(';')}" ` : '';
|
|
data.forEach((value) => {
|
|
const thumbs = value.thumbnails.filter((thumbnail) => {
|
|
return thumbRegex.test(thumbnail.url);
|
|
});
|
|
const url = context.getDetailUrl(value.id);
|
|
if (thumbs.length === 0) {
|
|
thumbs.push({ url: '', caption: '' });
|
|
}
|
|
thumbs.forEach((thumb) => {
|
|
const imgUrl = context.getThumbnailUrl(value.id, thumb.url);
|
|
const style = thumb.url === '' ? '' : imgStyle;
|
|
const image = `<img src="${Functions.htmlspecialchars(imgUrl)}" alt="${Functions.htmlspecialchars(thumb.url)}" ${style}/>`;
|
|
const template = list.template.replace(
|
|
'{Image}',
|
|
`<div ${imgStyle}><a href="${Functions.htmlspecialchars(url)}">${image}</a></div>`
|
|
);
|
|
cols.push(
|
|
<td key={`${value.id}:${thumb.url}`}>
|
|
<XoopsCode lang={lang} text={context.renderBasic(value, template, true)} dohtml={true} />
|
|
</td>
|
|
);
|
|
if (cols.length === size.maxCol) {
|
|
rows.push(<tr key={col}>{cols}</tr>);
|
|
cols = [];
|
|
}
|
|
col++;
|
|
});
|
|
});
|
|
while (cols.length !== 0) {
|
|
cols.push(<td key={`0.${col}`}></td>);
|
|
if (cols.length === size.maxCol) {
|
|
rows.push(<tr key={col}>{cols}</tr>);
|
|
cols = [];
|
|
}
|
|
col++;
|
|
}
|
|
return (
|
|
<div className="thumbnail-view">
|
|
<CosmoDbListSortBar lang={lang} context={context} list={list} params={params} />
|
|
<table className="thumbnail-table">
|
|
<tbody>{rows}</tbody>
|
|
</table>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default CosmoDbListThumbnailView;
|