-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add better and fast player * fetch all trending data in action * load content
- Loading branch information
Showing
23 changed files
with
1,361 additions
and
206 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Trending } from '@/components/Content/Trending' | ||
import { Movies } from '@/components/Content/Movies' | ||
import { TVShows } from '@/components/Content/TVShows' | ||
import { Watching } from '@/components/Content/Watching' | ||
|
||
export function Content() { | ||
return ( | ||
<div className='-my-[--discover-space] sm:pb-8'> | ||
<Trending /> | ||
<Watching /> | ||
<Movies /> | ||
<TVShows /> | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { $playerState } from '@/store/player' | ||
import { getSource } from '@/utils/sources' | ||
import { getEpisodeUrl } from '@/utils/url' | ||
import { useStore } from '@nanostores/react' | ||
import { navigate } from 'astro:transitions/client' | ||
import { SkipBackIcon, SkipForwardIcon } from 'lucide-react' | ||
|
||
interface NextPrevButtonsProps { | ||
season: number | ||
mediaId: number | ||
mediaTitle: string | ||
firstEpisode: number | ||
lastEpisode: number | ||
totalSeasons: number | ||
initialEpisode: number | ||
} | ||
|
||
export function NextPrevButtons({ | ||
season, | ||
mediaId, | ||
mediaTitle, | ||
firstEpisode, | ||
lastEpisode, | ||
totalSeasons, | ||
initialEpisode, | ||
}: NextPrevButtonsProps) { | ||
const playerState = useStore($playerState) | ||
const episode = playerState.episode ?? initialEpisode | ||
|
||
const isFirstEpisode = episode <= firstEpisode | ||
const isLastEpisode = episode >= lastEpisode | ||
const isLastSeason = season >= totalSeasons | ||
|
||
const handleEpisodeClick = (episode: number) => { | ||
$playerState.set({ ...$playerState.get(), episode }) | ||
const searchParams = new URL(window.location.href).searchParams | ||
const source = getSource(searchParams.get('source')) | ||
window.history.replaceState( | ||
{}, | ||
'', | ||
new URL( | ||
getEpisodeUrl(mediaId, mediaTitle, season, episode, source.id), | ||
window.location.href | ||
).toString() | ||
) | ||
} | ||
|
||
const handleNextSeason = () => { | ||
const searchParams = new URL(window.location.href).searchParams | ||
const source = getSource(searchParams.get('source')) | ||
const newSeason = season + 1 | ||
void navigate(getEpisodeUrl(mediaId, mediaTitle, newSeason, 1, source.id)) | ||
} | ||
|
||
return ( | ||
<div className='flex w-full items-center justify-end gap-2 rounded-2xl bg-white/10 p-2'> | ||
{!isFirstEpisode && ( | ||
<button | ||
onClick={() => handleEpisodeClick(episode - 1)} | ||
className='flex items-center justify-center gap-1 rounded-2xl bg-black/50 px-4 py-2 text-lg text-white' | ||
> | ||
<SkipBackIcon className='size-5 text-white' /> | ||
Prev | ||
</button> | ||
)} | ||
{!isLastEpisode && ( | ||
<button | ||
onClick={() => handleEpisodeClick(episode + 1)} | ||
className='flex items-center justify-center gap-1 rounded-2xl bg-black/50 px-4 py-2 text-lg text-white' | ||
> | ||
Next | ||
<SkipForwardIcon className='size-5 text-white' /> | ||
</button> | ||
)} | ||
{isLastEpisode && !isLastSeason && ( | ||
<button | ||
onClick={handleNextSeason} | ||
className='flex items-center justify-center gap-1 rounded-2xl bg-black/50 px-4 py-2 text-lg text-white' | ||
> | ||
Next Season | ||
<SkipForwardIcon className='size-5 text-white' /> | ||
</button> | ||
)} | ||
</div> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { useEffect } from 'react' | ||
import { PlayIcon } from 'lucide-react' | ||
import { useStore } from '@nanostores/react' | ||
import { $playerState } from '@/store/player' | ||
import { getSeasonOrEpisode } from '@/utils' | ||
import { getEpisodeUrl } from '@/utils/url' | ||
import { getSource, getTvUrl } from '@/utils/sources' | ||
import type { Episode } from 'tmdb-ts' | ||
|
||
interface SelectEpisodeProps { | ||
season: number | ||
mediaId: number | ||
mediaTitle: string | ||
episodes: Episode[] | ||
initialEpisode: number | ||
} | ||
|
||
export function SelectEpisode({ | ||
season, | ||
mediaId, | ||
episodes, | ||
mediaTitle, | ||
initialEpisode, | ||
}: SelectEpisodeProps) { | ||
const playerState = useStore($playerState) | ||
const episode = playerState.episode ?? initialEpisode | ||
|
||
const handleEpisodeClick = (episode: number) => { | ||
$playerState.set({ ...$playerState.get(), episode }) | ||
const searchParams = new URL(window.location.href).searchParams | ||
const source = getSource(searchParams.get('source')) | ||
window.history.replaceState( | ||
{}, | ||
'', | ||
new URL( | ||
getEpisodeUrl(mediaId, mediaTitle, season, episode, source.id), | ||
window.location.href | ||
).toString() | ||
) | ||
} | ||
|
||
useEffect(() => { | ||
const playerVideo = document.querySelector('#player-video') | ||
const currentEpisodeNumber = $playerState.get().episode | ||
const episodeIndex = episodes.findIndex( | ||
episodeDetails => episodeDetails.episode_number === currentEpisodeNumber | ||
) | ||
|
||
const episodeDetails = episodes[episodeIndex] | ||
|
||
if (!playerVideo || !episodeDetails) return | ||
|
||
const container = playerVideo.parentElement | ||
const olsSrc = playerVideo.getAttribute('src') | ||
const searchParams = new URL(window.location.href).searchParams | ||
|
||
const source = getSource(searchParams.get('source')) | ||
const season = getSeasonOrEpisode(searchParams.get('season')) | ||
const episode = episodeDetails.episode_number | ||
|
||
const newSrc = getTvUrl(source.id, mediaId, season, episode) | ||
|
||
if (olsSrc === newSrc || !container) return | ||
|
||
playerVideo.remove() | ||
playerVideo.setAttribute('src', newSrc) | ||
container?.append(playerVideo) | ||
}, [episodes, mediaId, episode]) | ||
|
||
return ( | ||
<div className='custom-scrollbars overflow-y-auto'> | ||
{episodes.map(episodeDetails => ( | ||
<button | ||
key={episodeDetails.id} | ||
aria-current={episodeDetails.episode_number === episode} | ||
onClick={() => handleEpisodeClick(episodeDetails.episode_number)} | ||
className='group relative line-clamp-1 flex h-12 w-full flex-shrink-0 items-center justify-between gap-1 p-4 text-sm even:bg-white/5 hover:bg-white/10 hover:text-white aria-[current=true]:!bg-white/20 aria-[current=true]:!text-primary-400' | ||
> | ||
<p className='flex gap-2 tracking-wide'> | ||
<span className='font-medium'> | ||
{episodeDetails.episode_number}. | ||
</span> | ||
<span className='line-clamp-1 text-start font-normal'> | ||
{episodeDetails.name} | ||
</span> | ||
</p> | ||
<span className='hidden shrink-0 items-center justify-center rounded-full bg-primary-400 p-1 group-aria-[current=true]:flex'> | ||
<PlayIcon width='10' height='10' fill='black' stroke='black' /> | ||
</span> | ||
</button> | ||
))} | ||
</div> | ||
) | ||
} |
Oops, something went wrong.