Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
GGO-web committed Dec 9, 2023
2 parents c9daba3 + 96660a7 commit 9be42af
Show file tree
Hide file tree
Showing 18 changed files with 271 additions and 60 deletions.
11 changes: 8 additions & 3 deletions src/components/CustomPlayer/CustomPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useEffect, useRef, useState } from 'react';
import { toFormattedTime } from '@helpers/getDateFromSeconds';
import { fetchVideoPlayer } from '@helpers/fetchVideoPlayer';
import { SavedPlayerInfo } from '../../interfaces/SavedPlayerInfo.interface';
import { SavedPlayerInfo } from '@/interfaces/SavedPlayerInfo.interface';

import { Select } from '@components/Select/Select';
import { Item } from 'react-aria-components';

export const CustomPlayer = () => {
export const CustomPlayer = ({ url }: { url?: string }) => {
const [info, setInfo] = useState<SavedPlayerInfo>();
const [seasons, setSeasons] = useState<{ season: number }[]>();
const [season, setSeason] = useState<React.Key>(1);
Expand All @@ -22,6 +22,7 @@ export const CustomPlayer = () => {
setIsPlayerLoading(true);

const { info } = await fetchVideoPlayer({
url,
season,
episode,
startTime
Expand Down Expand Up @@ -56,8 +57,12 @@ export const CustomPlayer = () => {
};

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

fetchVideoPlayerData();
}, [season, episode, startTime]);
}, [url, season, episode, startTime]);

return (
<div className="player-container relative aspect-video">
Expand Down
2 changes: 1 addition & 1 deletion src/components/FlexGroup/FlexGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { HTMLAttributes } from 'react';
import cn from 'classnames';

interface FlexGroupProps extends HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
children: React.ReactNode | React.ReactNode[];
centerY?: boolean;
center?: boolean;
column?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions src/components/Searchbar/ExtraFilters.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';

import { Select } from '@components/Select/Select';
import { ANIME_YEARS, FILTERS_MAX } from '../../constants';
import { ANIME_YEARS, FILTERS_MAX } from '@/constants';
import { Item } from 'react-aria-components';
import { Paragraph } from '@components/Paragraph/Paragraph';

Expand All @@ -14,7 +14,7 @@ interface ExtraFiltersProps {

export const ExtraFilters: React.FC<ExtraFiltersProps> = ({ togglePopup }) => {
const [year, setYear] = React.useState<React.Key>(1);
const [isYearLoading, setIsYearLoading] = React.useState(false);
const [isYearLoading] = React.useState(false);
const [grade, setGrade] = React.useState<[number, number]>([0, 10]);
const [isSeries, setIsSeries] = React.useState(true);

Expand Down
6 changes: 2 additions & 4 deletions src/components/Searchbar/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import axios from 'axios';

import { Item } from 'react-aria-components';
import { Select } from '@components/Select/Select';
import { IJsonAlbum } from '../../types/album';
import { IJsonAlbum } from '@/types/album';
import { useQuery } from '@tanstack/react-query';
import { GenreService } from '@services/Genre/Genre.service';

Expand All @@ -17,15 +17,13 @@ export const Search = () => {
staleTime: 1000 * 60 * 60 // 60 minutes caching
});

console.log(newGenres);

const [posts, setPosts] = React.useState<IJsonAlbum[]>([]);

const [search, setSearch] = useState('');
const [isSearchLoading, setIsSearchLoading] = useState(false);

const [genre, setGenre] = useState<React.Key>(1);
const [isGenreLoading, setIsGenreLoading] = useState(false);
const [isGenreLoading] = useState(false);

const filterSearch = search.toLowerCase() || '';

Expand Down
96 changes: 96 additions & 0 deletions src/components/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {
Tab,
TabList,
TabPanel,
Tabs as AriaTabs,
TabsProps
} from 'react-aria-components';
import type { TabPanelProps, TabProps } from 'react-aria-components';
import React, { Key, useMemo, useState } from 'react';

export interface ITab {
id: string;
label: string;
element: JSX.Element;
}

export interface ITabs extends TabsProps {
tabs: ITab[];
}

export const Tabs = ({ tabs, ...props }: ITabs) => {
const [selectedKey, setSelectedKey] = useState<Key>(tabs[0].id);

const selectedItem = useMemo(() => {
return document.querySelector(`.tabpanel-${selectedKey as string}`);
}, [selectedKey]);

return (
<div className="flex justify-center">
<AriaTabs
selectedKey={selectedKey}
onSelectionChange={setSelectedKey}
className="w-full tabs"
{...props}
>
<TabList className="flex space-x-1 tabs__list">
{tabs.map(({ id, label }, index) => {
return (
<MyTab
key={id}
id={id}
style={{ marginLeft: index ? '-6px' : 0 }}
>
{label}
</MyTab>
);
})}
</TabList>

<div
className={`tabs__tabpanels flex aspect-video min-h-[${
selectedItem?.clientHeight || 0
}px] relative`}
>
{tabs.map(({ id, element }) => {
return (
<MyTabPanel
key={`tabpanel-${id}`}
id={id}
className={`tabpanel-${id}`}
>
{element}
</MyTabPanel>
);
})}
</div>
</AriaTabs>
</div>
);
};

function MyTab(props: TabProps) {
return (
<Tab
{...props}
className={({ isSelected }) => `
tabs__item w-full max-w-[300px] py-2.5 text-center outline-none transition-colors font-bold cursor-pointer
${
isSelected
? 'rounded-tl-[6px] rounded-tr-[6px] text-white bg-[var(--color-red)] border-[1px] border-transparent'
: 'rounded-tl-[6px] rounded-tr-[6px] text-white border-[1px] border-[var(--color-red)]'
}
`}
/>
);
}

function MyTabPanel({ className, ...props }: TabPanelProps) {
return (
<TabPanel
shouldForceMount={true}
{...props}
className={`mt-2 text-gray-700 rounded-2x tabpanel ${className}`}
/>
);
}
15 changes: 15 additions & 0 deletions src/components/TrailerPlayer/TrailerPlayer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import { FlexGroup } from '@components/FlexGroup/FlexGroup';

export const TrailerPlayer = () => {
return (
<FlexGroup className="trailer-container">
<iframe
className={'w-full aspect-video'}
src="https://www.youtube.com/embed/i66VJnh-hYc"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
/>
</FlexGroup>
);
};
6 changes: 2 additions & 4 deletions src/helpers/fetchVideoPlayer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Key } from 'react';
import { SavedPlayerInfo } from '../interfaces/SavedPlayerInfo.interface';
import { SavedPlayerInfo } from '@/interfaces/SavedPlayerInfo.interface';

interface FetchPlayerProps {
url?: string;
Expand All @@ -26,9 +26,7 @@ export const fetchVideoPlayer = async ({
const randomPoster = getRandomArbitrary(1, 5);
return fetch(
`${
url
? url
: 'https://voidboost.net/serial/8171b59d92582ed8eb7d17c9d6768660/iframe'
url ? url : 'https://voidboost.net/embed/tt15765670'
}?s=${season}&e=${episode}&start=${startTime}&autoplay=${
startTime !== 0 ? 1 : 0
}&poster=1&poster_id=${randomPoster}&h=voidboost.net&plang=ua`
Expand Down
54 changes: 42 additions & 12 deletions src/pages/Title/Title.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import React from 'react';
import React, { useMemo } from 'react';
import { Breadcrumbs } from '@components/Breadcrumbs/Breadcrumbs';
import { Header } from '@components/Header/Header';
import { Sidenav } from '@components/Navigation/Sidenav';

import {
CURRENT_ANIME,
DESCRIPTION_ANIME,
NEXT_ANIME,
RECOMMENDATIONS_ANIME,
TITLE_BREADCRUMBS,
LIST_RELEASE_SCHEDULE
} from '../../constants';
} from '@/constants';
import { TitleInfo } from './components/TitleInfo/TitleInfo';
import { NextSeasons } from './components/NextSeasons/NextSeasons';
import { Recommendations } from './components/Recommendations/Recommendations';
Expand All @@ -20,14 +18,45 @@ import { SeriesReleaseSchedule } from './components/SeriesReleaseSchedule/Series
import { TitleImages } from './components/TitleImages/TitleImages';
import { SimilarAnime } from './components/SimilarAnime/SimilarAnime';

import { FormComment } from './components/Comments/FormComment/FormComment';
import { ItemCommment } from './components/Comments/ItemComment/ItemComment';
import { Comments } from './components/Comments/Comments';

import { CustomPlayer } from '@components/CustomPlayer/CustomPlayer';

import { TrailerPlayer } from '@components/TrailerPlayer/TrailerPlayer';
import { ITab, Tabs } from '@components/Tabs/Tabs';
import { useParams } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import { TitleService } from '@services/Title/Title.service';

export const Title = () => {
const { id } = useParams();

const { data: title } = useQuery({
queryKey: ['titles', id],
queryFn: async () => {
return TitleService.getTitleById(id);
},
staleTime: 1000 * 60 * 60
});

const playerLink = useMemo(() => {
return title?.players?.at(0)?.embedLink;
}, [title]);

const videoTabs: ITab[] = useMemo(() => {
return [
{
id: 'anime',
label: 'Дивитися онлайн',
element: <CustomPlayer url={playerLink} />
},
{
id: 'trailer',
label: 'Трейлер',
element: <TrailerPlayer />
}
];
}, [playerLink]);

return (
<section className="home page-section">
<div className="home__container page-section__container">
Expand All @@ -39,27 +68,28 @@ export const Title = () => {
<Breadcrumbs
items={[
...TITLE_BREADCRUMBS,
{ name: 'Константин: Місто Демонів', link: '#' }
{ name: title?.name || 'Невідомий шедевр', link: '#' }
]}
/>

<section className="title__main">
<TitleInfo anime={CURRENT_ANIME} />
<TitleInfo anime={title} />

<div className="title__main-col-2">
<NextSeasons anime={NEXT_ANIME} />
<Recommendations anime={RECOMMENDATIONS_ANIME} />
</div>
</section>

<TitleDescription
heading={DESCRIPTION_ANIME.heading}
paragraph={DESCRIPTION_ANIME.paragraph}
heading={title?.name}
paragraph={title?.description}
/>

<section className="player-outer">
<TitleImages />

<CustomPlayer />
<Tabs tabs={videoTabs} />

<SeriesReleaseSchedule listSeries={LIST_RELEASE_SCHEDULE} />
</section>
Expand Down
27 changes: 23 additions & 4 deletions src/pages/Title/components/TitleDescrption/TitleDescription.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,41 @@ import { Paragraph } from '@components/Paragraph/Paragraph';
import React from 'react';

interface TitleDescriptionProps {
heading: string;
paragraph: string;
heading?: string;
paragraph?: string;
}

export const TitleDescription: React.FC<TitleDescriptionProps> = ({
heading,
paragraph
}) => {
const formatText = (text = '') => {
if (!text) {
return 'Тут мав бути крутий опис, але його вміст загубили';
}

// Split the text into sentences
const sentences = text.split('. ');

// Capitalize the first letter of each sentence
const capitalizedSentences = sentences.map((sentence) => {
return sentence.charAt(0).toUpperCase() + sentence.slice(1);
});

// Join the sentences back into a single string
const result = capitalizedSentences.join('. ');

return result;
};

return (
<>
<strong>
<Heading className="text-xl mb-5">
Про що мультсеріал &quot;{heading}&quot;:
Про що мультсеріал &quot;{heading || 'Невідомий'}&quot;:
</Heading>
</strong>
<Paragraph className="mb-[63px]">{paragraph}</Paragraph>
<Paragraph className="mb-[63px]">{formatText(paragraph)}</Paragraph>
</>
);
};
Loading

0 comments on commit 9be42af

Please sign in to comment.