Skip to content

Commit

Permalink
Feat: Move collection data to static_data
Browse files Browse the repository at this point in the history
  • Loading branch information
whats2000 committed Jul 25, 2024
1 parent fd28a21 commit 964e75b
Show file tree
Hide file tree
Showing 25 changed files with 88 additions and 103 deletions.
Binary file removed src/assets/architectureCollection/ctec_spawn.png
Binary file not shown.
Binary file removed src/assets/architectureCollection/ctec_spawn_1.png
Binary file not shown.
Binary file removed src/assets/architectureCollection/ctec_spawn_2.png
Binary file not shown.
Binary file removed src/assets/architectureCollection/ice_boat.png
Binary file not shown.
Binary file removed src/assets/architectureCollection/ice_boat.webp
Binary file not shown.
Binary file removed src/assets/architectureCollection/ice_boat_1.png
Binary file not shown.
Binary file removed src/assets/architectureCollection/ice_boat_2.png
Binary file not shown.
Binary file removed src/assets/architectureCollection/spawn.png
Binary file not shown.
Binary file removed src/assets/architectureCollection/spawn.webp
Binary file not shown.
Binary file removed src/assets/architectureCollection/spawn_1.png
Binary file not shown.
Binary file removed src/assets/architectureCollection/spawn_2.png
Binary file not shown.
Binary file removed src/assets/redstoneCollection/360ftl_star_bow.png
Binary file not shown.
Binary file not shown.
Binary file removed src/assets/redstoneCollection/432K_sand_duper.png
Binary file not shown.
Binary file removed src/assets/redstoneCollection/432K_sand_duper.webp
Binary file not shown.
Binary file not shown.
Binary file removed src/assets/redstoneCollection/redstoneCollection.rar
Binary file not shown.
11 changes: 7 additions & 4 deletions src/components/collection/CollectionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import type { CarouselRef } from 'antd/lib/carousel';
import { DownloadOutlined, PlayCircleOutlined } from '@ant-design/icons';

import { ICollection } from '@/types/ICollection.ts';
import getImageUrl from '@/utils/getImageUrl.ts';
import ShareModal from '#/common/ShareModal.tsx';
import stopVideo from '@/utils/stopVideo.ts';
import { STATIC_DATA_API } from '@/constants';

const StyledTitle = styled.h2`
font-size: 24px;
Expand Down Expand Up @@ -209,7 +209,10 @@ const CollectionModal: React.FC<CollectionModalProps> = ({
...(item.galleryImagesUrl ?? []).map((url, index) => (
<div key={`image-${index}`}>
<ImageWrapper>
<PreviewImage src={getImageUrl(url)} alt={`Gallery image ${index}`} />
<PreviewImage
src={`${STATIC_DATA_API}/images/${url}`}
alt={`Gallery image ${index}`}
/>
</ImageWrapper>
</div>
)),
Expand All @@ -219,7 +222,7 @@ const CollectionModal: React.FC<CollectionModalProps> = ({
...(item.videosUrl ?? []).map((video, index) => (
<ThumbnailWithOverlay key={`video-thumb-${index}`}>
<Thumbnail
src={getImageUrl(video.thumbnailUrl)}
src={`${STATIC_DATA_API}/images/${video.thumbnailUrl}`}
alt={`Video thumbnail ${index}`}
onClick={() => handleThumbnailClick(index)}
$isSelected={selectedImageIndex === index}
Expand All @@ -232,7 +235,7 @@ const CollectionModal: React.FC<CollectionModalProps> = ({
...(item.galleryImagesUrl ?? []).map((url, index) => (
<Thumbnail
key={`image-thumb-${index}`}
src={getImageUrl(url)}
src={`${STATIC_DATA_API}/images/${url}`}
alt={`Image thumbnail ${index + (item.videosUrl?.length ?? 0)}`}
onClick={() =>
handleThumbnailClick(index + (item.videosUrl?.length ?? 0))
Expand Down
79 changes: 61 additions & 18 deletions src/components/collection/CollectionPageBase.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useTranslation } from 'react-i18next';
import { useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Select, SelectProps } from 'antd';
import { Select, SelectProps, Spin } from 'antd';
import styled from 'styled-components';

import PageHeader from '#/common/PageHeader.tsx';
Expand All @@ -10,7 +10,10 @@ import CardsSection from '#/common/CardsSection.tsx';
import CollectionModal from '#/collection/CollectionModal.tsx';

import { ICollection } from '@/types/ICollection.ts';
import { STATIC_DATA_API } from '@/constants';
import getImageUrl from '@/utils/getImageUrl.ts';
import useApi from '@/hooks/useApi.ts';
import { WarningOutlined } from '@ant-design/icons';

const Container = styled.div`
padding: 50px 40px;
Expand All @@ -31,16 +34,31 @@ const StyledSelect = styled(Select)<SelectProps>`
width: 100%;
`;

const StatusContainer = styled.div`
display: flex;
justify-content: center;
align-items: center;
svg {
color: #6f9b9c !important;
}
span {
margin-left: 10px;
color: #6f9b9c;
}
`;

const CollectionPageBase = ({
pageType,
}: {
pageType: 'architecture' | 'redstone';
}) => {
const { t } = useTranslation();
const imageContents: ICollection[] = useMemo(
() => t(`${pageType}Collection.collections`, { returnObjects: true }),
[t, pageType],
const { t, i18n } = useTranslation();
const { data, loading, error } = useApi<ICollection[]>(
`${STATIC_DATA_API}/${i18n.language}/${pageType}Collection.json`,
);

const navigate = useNavigate();

const [isModalOpen, setIsModalOpen] = useState(false);
Expand All @@ -49,17 +67,22 @@ const CollectionPageBase = ({
index: number;
} | null>(null);
const [selectedTags, setSelectedTags] = useState<string[]>([]);
const [filteredContents, setFilteredContents] =
useState<ICollection[]>(imageContents);
const [filteredContents, setFilteredContents] = useState<ICollection[]>(
data ?? [],
);

useEffect(() => {
if (!data) {
return;
}

const params = new URLSearchParams(window.location.search);
const shareIndex = params.get('share') ?? params.get('index');
const tags = params.get('tag');

if (shareIndex !== null) {
const index = parseInt(shareIndex, 10);
const item = imageContents[index];
const item = data[index];
if (item) {
setSelectedItem({ item, index });
setIsModalOpen(true);
Expand All @@ -70,24 +93,29 @@ const CollectionPageBase = ({
setSelectedTags(tags.split(','));
}
}
}, [imageContents, navigate, pageType]);
}, [data, navigate, pageType]);

useEffect(() => {
if (!data) {
return;
}

if (selectedTags.length === 0) {
setFilteredContents(imageContents);
setFilteredContents(data);
} else {
const filtered = imageContents.filter((item) =>
const filtered = data.filter((item) =>
selectedTags.every(
(tag) => item.tags?.includes(tag) || item.title.includes(tag),
),
);
setFilteredContents(filtered);
}
}, [selectedTags, imageContents]);
}, [selectedTags, data]);

const imageUrl =
t(`${pageType}Collection.imageUrl`) === `${pageType}Collection.imageUrl`
? imageContents[Math.floor(Math.random() * imageContents.length)].imageUrl
t(`${pageType}Collection.imageUrl`) === `${pageType}Collection.imageUrl` &&
data
? data[Math.floor(Math.random() * data.length)].imageUrl
: t(`${pageType}Collection.imageUrl`);

const handleCardClick = (item: ICollection, index: number) => {
Expand All @@ -108,10 +136,12 @@ const CollectionPageBase = ({
};

const allTags = useMemo(() => {
return Array.from(
new Set(imageContents.flatMap((item) => item.tags || [])),
);
}, [imageContents]);
if (!data) {
return [];
}

return Array.from(new Set(data.flatMap((item) => item.tags || [])));
}, [data]);

const tagOptions = allTags.map((tag) => ({ value: tag, label: tag }));

Expand Down Expand Up @@ -144,7 +174,20 @@ const CollectionPageBase = ({
title={t(`${pageType}Collection.title`)}
darkMode={true}
imageContentSections={bindEventImageContents}
useStaticDataApi={true}
/>
{error && (
<StatusContainer>
<WarningOutlined style={{ fontSize: '24px', color: '#feffe6' }} />
<span>{t('error')}</span>
</StatusContainer>
)}
{loading && (
<StatusContainer>
<Spin size='large' spinning={true} />
<span>{t('loading')}</span>
</StatusContainer>
)}
{selectedItem && (
<CollectionModal
isOpen={isModalOpen}
Expand Down
10 changes: 9 additions & 1 deletion src/components/common/CardsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { IImageContent } from '@/types/IImageContent.ts';
import useAnimateOnScroll from '@/hooks/useAnimateOnScroll.ts';
import getImageUrl from '@/utils/getImageUrl.ts';
import { fadeIn } from '@/styles/animation.ts';
import { STATIC_DATA_API } from '@/constants';

const Section = styled.section<{ $darkMode: boolean }>`
background-color: #ecf0f1;
Expand Down Expand Up @@ -133,19 +134,22 @@ interface CardsSectionProps {
title: string;
darkMode?: boolean;
imageContentSections: IImageContent[];
useStaticDataApi?: boolean;
}

/**
* Cards section component, for rendering multiple cards with image, title, subtitle, paragraph, features, and buttons
* @param title - Section title
* @param darkMode - Dark mode flag
* @param imageContentSections - Array of image content sections
* @param useStaticDataApi - Flag to use static data API, otherwise use the image in assets
* @constructor
*/
const CardsSection: React.FC<CardsSectionProps> = ({
title,
darkMode = false,
imageContentSections,
useStaticDataApi = false,
}: CardsSectionProps) => {
const { animate, ref } = useAnimateOnScroll();

Expand All @@ -161,7 +165,11 @@ const CardsSection: React.FC<CardsSectionProps> = ({
cover={
<ImageWrapper>
<LazyLoadImage
src={getImageUrl(section.imageUrl)}
src={
useStaticDataApi
? `${STATIC_DATA_API}/images/${section.imageUrl}`
: getImageUrl(section.imageUrl)
}
alt={section.title}
effect='blur'
/>
Expand Down
2 changes: 1 addition & 1 deletion src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ export const serverLink = {
// export const MEMBER_API =
// 'https://raw.githubusercontent.com/mc-cloud-town/static-data/main/data/member.json';

export const MEMBER_API = 'https://mc-ctec.org/static-data/member.json';
export const STATIC_DATA_API = 'https://mc-ctec.org/static-data';

export const GITHUB_API = 'https://api.github.com/orgs/mc-cloud-town/repos';
79 changes: 2 additions & 77 deletions src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -654,86 +654,11 @@
"architectureCollection": {
"title": "Building Collection",
"imageUrl": "homePage/CTEC_Building.webp",
"searchPlaceholder": "Search Tags/Name...",
"collections": [
{
"title": "雲鎮工藝出生點-恐懼",
"imageUrl": "architectureCollection/spawn.webp",
"date": "2024-03-17",
"galleryImagesUrl": [
"architectureCollection/spawn.png",
"architectureCollection/spawn_1.png",
"architectureCollection/spawn_2.png"
],
"creator": ["_R6,XiaoYu2021"],
"credits": [
{
"name": "Etymology_Ghost",
"url": "https://twitter.com/EtymologyGhost"
}
],
"tags": ["建築", "雕塑", "海怪", "Karken", "建模"]
},
{
"title": "雲鎮工藝出生點-冰船賽道",
"imageUrl": "architectureCollection/ice_boat.webp",
"date": "2024-03-03",
"downloadUrl": "",
"creator": ["XiaoYu2021,bow_lsaa"],
"galleryImagesUrl": [
"architectureCollection/ice_boat.png",
"architectureCollection/ice_boat_1.png",
"architectureCollection/ice_boat_2.png"
],
"credits": [
{
"name": "XiaoYu2021 - 渲染圖片"
}
],
"tags": ["建築", "冰船賽道", "聖誕節"]
}
]
"searchPlaceholder": "Search Tags/Name..."
},
"redstoneCollection": {
"title": "Redstone Collection",
"imageUrl": "survivalProgress/p30.webp",
"searchPlaceholder": "Search Tags or Name",
"collections": [
{
"title": "360FTL-StarBow-Mini",
"imageUrl": "redstoneCollection/360ftl_star_bow.png",
"date": "2024-03-17",
"downloadUrl": "https://discord.com/channels/933290709589577728/1001472836625518612/1220232415314968586",
"videosUrl": [
{
"url": "https://www.youtube.com/embed/gFAjlbvHx0o?si=364H5gltOtsedO3x",
"thumbnailUrl": "redstoneCollection/360ftl_star_bow_video_page.webp"
}
],
"galleryImagesUrl": ["redstoneCollection/360ftl_star_bow.png"],
"creator": ["FlandreLed"],
"credits": [
{
"name": "672FTL - PearlCannon - _Emir",
"url": "https://www.youtube.com/@emiraleph"
}
],
"tags": ["紅石", "設施", "TNT", "珍珠炮", "FTL"]
},
{
"title": "432K高压主世界TNT刷沙机",
"imageUrl": "redstoneCollection/432K_sand_duper.webp",
"date": "2024-03-03",
"downloadUrl": "https://discord.com/channels/933290709589577728/1001472836625518612/1213776551548559421",
"creator": ["Petris 5256"],
"galleryImagesUrl": ["redstoneCollection/432K_sand_duper.png"],
"credits": [
{
"name": "432K/h sand duper axialeaa"
}
],
"tags": ["紅石", "設施", "粉末複製"]
}
]
"searchPlaceholder": "Search Tags or Name"
}
}
2 changes: 2 additions & 0 deletions src/i18n/locales/zh_CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,12 @@
},
"architectureCollection": {
"title": "建筑作品集",
"imageUrl": "homePage/CTEC_Building.webp",
"searchPlaceholder": "搜索标签或名称"
},
"redstoneCollection": {
"title": "紅石作品集",
"imageUrl": "survivalProgress/p30.webp",
"searchPlaceholder": "搜索标签或名称"
}
}
2 changes: 2 additions & 0 deletions src/i18n/locales/zh_TW/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -448,10 +448,12 @@
},
"architectureCollection": {
"title": "建築作品集",
"imageUrl": "homePage/CTEC_Building.webp",
"searchPlaceholder": "搜尋標籤或名稱"
},
"redstoneCollection": {
"title": "紅石作品集",
"imageUrl": "survivalProgress/p30.webp",
"searchPlaceholder": "搜尋標籤或名稱"
}
}
6 changes: 4 additions & 2 deletions src/pages/Members.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import MemberCase from '#/members/MemberCase.tsx';

import useApi from '@/hooks/useApi.ts';
import getImageUrl from '@/utils/getImageUrl.ts';
import { MEMBER_API } from '@/constants';
import { STATIC_DATA_API } from '@/constants';
import { IMembers } from '@/types/IMember.ts';

const Container = styled.div`
Expand Down Expand Up @@ -48,7 +48,9 @@ const StyledInput = styled(Input)`
`;

const MembersPage = () => {
const { data, loading, error } = useApi<IMembers>(MEMBER_API);
const { data, loading, error } = useApi<IMembers>(
`${STATIC_DATA_API}/member.json`,
);
const { t } = useTranslation();
const [searchTerm, setSearchTerm] = useState('');

Expand Down

0 comments on commit 964e75b

Please sign in to comment.