A small web app for watching movies and shows easily
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

85 lines
2.7 KiB

import { useCallback, useEffect, useRef, useState } from "react";
import Sticky from "react-sticky-el";
import { useWindowSize } from "react-use";
import { SearchBarInput } from "@/components/form/SearchBar";
import { ThinContainer } from "@/components/layout/ThinContainer";
import { useSlashFocus } from "@/components/player/hooks/useSlashFocus";
import { HeroTitle } from "@/components/text/HeroTitle";
import { useRandomTranslation } from "@/hooks/useRandomTranslation";
import { useSearchQuery } from "@/hooks/useSearchQuery";
import { useBannerSize } from "@/stores/banner";
export interface HeroPartProps {
setIsSticky: (val: boolean) => void;
searchParams: ReturnType<typeof useSearchQuery>;
}
function getTimeOfDay(date: Date): "night" | "morning" | "day" {
const hour = date.getHours();
if (hour < 5) return "night";
if (hour < 12) return "morning";
if (hour < 19) return "day";
return "night";
}
export function HeroPart({ setIsSticky, searchParams }: HeroPartProps) {
const { t: randomT } = useRandomTranslation();
const [search, setSearch, setSearchUnFocus] = searchParams;
const [, setShowBg] = useState(false);
const bannerSize = useBannerSize();
const stickStateChanged = useCallback(
(isFixed: boolean) => {
setShowBg(isFixed);
setIsSticky(isFixed);
},
[setShowBg, setIsSticky],
);
const { width: windowWidth } = useWindowSize();
const topSpacing = 16;
const [stickyOffset, setStickyOffset] = useState(topSpacing);
useEffect(() => {
if (windowWidth > 1200) {
// On large screens the bar goes inline with the nav elements
setStickyOffset(topSpacing);
} else {
// On smaller screens the bar goes below the nav elements
setStickyOffset(topSpacing + 60);
}
}, [windowWidth]);
const time = getTimeOfDay(new Date());
const title = randomT(`home.titles.${time}`);
const placeholder = randomT(`home.search.placeholder`);
const inputRef = useRef<HTMLInputElement>(null);
useSlashFocus(inputRef);
return (
<ThinContainer>
<div className="mt-44 space-y-16 text-center">
<div className="relative z-10 mb-16">
<HeroTitle className="mx-auto max-w-md">{title}</HeroTitle>
</div>
<div className="relative h-20 z-30">
<Sticky
topOffset={stickyOffset * -1 + bannerSize}
stickyStyle={{
paddingTop: `${stickyOffset + bannerSize}px`,
}}
onFixedToggle={stickStateChanged}
>
<SearchBarInput
ref={inputRef}
onChange={setSearch}
value={search}
onUnFocus={setSearchUnFocus}
placeholder={placeholder ?? ""}
/>
</Sticky>
</div>
</div>
</ThinContainer>
);
}