fix homepage layout and carousels

This commit is contained in:
Pas 2025-06-01 19:04:14 -06:00
parent 3cc435332c
commit b8ca66b4cb
7 changed files with 60 additions and 177 deletions

View file

@ -70,7 +70,6 @@ export function HomePage() {
const enableCarouselView = usePreferencesStore(
(state) => state.enableCarouselView,
);
const isMobile = window.innerWidth < 768;
const handleClick = (path: To) => {
window.scrollTo(0, 0);
@ -85,23 +84,8 @@ export function HomePage() {
detailsModal.show();
};
// const { loggedIn } = useAuth(); // Adjust padding for popup show button based on logged in state
return (
<HomeLayout showBg={showBg}>
{/* <a
onClick={() => modal.show()}
className={` text-white tabbable rounded-full z-50 fixed top-5 ${
loggedIn
? "right-[7.5rem] lg:right-[12.5rem] lg:text-2xl"
: "right-[7.5rem] text-xl lg:text-lg"
}`}
style={{ animation: "pulse 1s infinite" }}
>
<IconPill icon={Icons.WARNING}>
<span className="font-bold select-none">READ</span>
</IconPill>
</a> */}
<div className="mb-2">
<Helmet>
<style type="text/css">{`
@ -112,97 +96,7 @@ export function HomePage() {
<title>{t("global.name")}</title>
</Helmet>
{/* Popup
<FancyModal
id="notice"
title="We're changing our backend server!"
oneTime
>
<div>
<p>
On <strong>January 8th</strong>, the backend server will change
from:
</p>
<p>
<strong>server.vidbinge.com</strong> {" "}
<strong>server.fifthwit.tech</strong>
</p>
<br />
<p>
You will need to <strong>migrate your account </strong> to the new
server or choose to continue using the old server by updating your
settings.
</p>
<br />
<p>
<strong>What You Need to Know:</strong>
</p>
<ul>
<li>
1. <strong>Migrating Your Account:</strong> Your data (e.g.,
bookmarks) will not be automatically transferred. You&apos;ll
need to migrate your account from the settings page. Or from
below.
</li>
<li>
2. <strong>Staying on the Old Server:</strong> If you don&apos;t
want to change to the new server, your data will remain safe on{" "}
<strong>server.vidbinge.com</strong>. You can change the Backend
URL in your settings to &quot;https://server.vidbinge.com&quot;.
</li>
</ul>
<br />
<p>
<strong>Steps to Move Your Data:</strong>
</p>
<ol>
<li>
1. Log into your account on <strong>server.vidbinge.com</strong>
.
</li>
<li>
(If you already are logged in, press here:{" "}
<a href="/migration" className="text-type-link">
Migrate my data.
</a>
)
</li>
<li>
2. Go to the <strong>Settings</strong> page.
</li>
<li>
3. Scroll down to{" "}
<strong>Connections &gt; Custom Server</strong>.
</li>
<li>
3. Press the &quot;Migrate my data to a new server.&quot;
button.
</li>
<li>
4. Enter the new server url:{" "}
<strong>https://server.fifthwit.tech</strong> and press
&quot;Migrate&quot;.
</li>
<li>5. Login to your account with the same passphrase!</li>
</ol>
<br />
<p>
Thank you for your understanding and support during this
transition! If you have questions or need help, feel free to reach
out on the{" "}
<a
href="https://discord.com/invite/7z6znYgrTG"
target="_blank"
rel="noopener noreferrer"
className="text-type-link"
>
P-Stream Discord
</a>
!
</p>
</div>
</FancyModal>
*/}
{/* Page Header */}
{enableFeatured ? (
<FeaturedCarousel
forcedCategory="editorpicks"
@ -223,59 +117,64 @@ export function HomePage() {
showTitle
/>
)}
{conf().SHOW_AD ? <AdsPart /> : null}
</div>
<WideContainer ultraWide={enableCarouselView}>
{s.loading ? (
<SearchLoadingPart />
) : s.searching ? (
enableCarouselView ? (
<WideContainer>
{/* Search */}
{search && (
<WideContainer>
{s.loading ? (
<SearchLoadingPart />
) : (
s.searching && (
<SearchListPart
searchQuery={search}
onShowDetails={handleShowDetails}
/>
</WideContainer>
) : (
<SearchListPart
searchQuery={search}
)
)}
</WideContainer>
)}
{/* User Content */}
{!search &&
(enableCarouselView ? (
<WideContainer ultraWide>
<WatchingCarousel
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
/>
)
<BookmarksCarousel
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
/>
</WideContainer>
) : (
<div className="flex flex-col gap-8">
{enableCarouselView ? (
<>
<WatchingCarousel
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
/>
<BookmarksCarousel
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
/>
</>
) : (
<>
<WatchingPart
onItemsChange={setShowWatching}
onShowDetails={handleShowDetails}
/>
<BookmarksPart
onItemsChange={setShowBookmarks}
onShowDetails={handleShowDetails}
/>
</>
)}
</div>
)}
<WideContainer>
<div className="flex flex-col gap-8">
<WatchingPart
onItemsChange={setShowWatching}
onShowDetails={handleShowDetails}
/>
<BookmarksPart
onItemsChange={setShowBookmarks}
onShowDetails={handleShowDetails}
/>
</div>
</WideContainer>
))}
{/* Under user content */}
<WideContainer ultraWide>
{/* Empty text */}
{!(showBookmarks || showWatching) && !enableDiscover ? (
<div className="flex flex-col translate-y-[-30px] items-center justify-center pt-20">
<p className="text-[18.5px] pb-3">{emptyText}</p>
</div>
) : null}
{/* Discover Spacing */}
{enableDiscover &&
(enableFeatured ? (
<div className="pb-4" />
@ -285,6 +184,8 @@ export function HomePage() {
<div className="pb-20" />
))}
{/* there... perfect. */}
{/* Discover section or discover button */}
{enableDiscover && !search ? (
<DiscoverContent />
) : (

View file

@ -20,7 +20,6 @@ interface LazyMediaCarouselProps {
category?: Category;
genre?: Genre;
mediaType: "movie" | "tv";
isMobile: boolean;
carouselRefs: React.MutableRefObject<{
[key: string]: HTMLDivElement | null;
}>;
@ -37,7 +36,6 @@ export function LazyMediaCarousel({
category,
genre,
mediaType,
isMobile,
carouselRefs,
onShowDetails,
preloadedMedia,
@ -121,7 +119,6 @@ export function LazyMediaCarousel({
medias={medias}
category={categoryName}
isTVShow={mediaType === "tv"}
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={onShowDetails}
genreId={genreId}

View file

@ -8,6 +8,7 @@ import { Dropdown, OptionItem } from "@/components/form/Dropdown";
import { Icon, Icons } from "@/components/Icon";
import { MediaCard } from "@/components/media/MediaCard";
import { Flare } from "@/components/utils/Flare";
import { useIsMobile } from "@/hooks/useIsMobile";
import { Media } from "@/pages/discover/common";
import { useDiscoverStore } from "@/stores/discover";
import { MediaItem } from "@/utils/mediaTypes";
@ -19,7 +20,6 @@ interface MediaCarouselProps {
medias: Media[];
category: string;
isTVShow: boolean;
isMobile: boolean;
carouselRefs: React.MutableRefObject<{
[key: string]: HTMLDivElement | null;
}>;
@ -79,7 +79,6 @@ export function MediaCarousel({
medias,
category,
isTVShow,
isMobile,
carouselRefs,
onShowDetails,
genreId,
@ -99,6 +98,8 @@ export function MediaCarousel({
);
const categorySlug = `${category.toLowerCase().replace(/[^a-z0-9]+/g, "-")}-${isTVShow ? "tv" : "movie"}`;
const browser = !!window.chrome;
const { isMobile } = useIsMobile();
let isScrolling = false;
const handleWheel = (e: React.WheelEvent) => {

View file

@ -5,7 +5,6 @@ import { get } from "@/backend/metadata/tmdb";
import { WideContainer } from "@/components/layout/WideContainer";
import { DetailsModal } from "@/components/overlays/DetailsModal";
import { useModal } from "@/components/overlays/Modal";
import { useIsMobile } from "@/hooks/useIsMobile";
import {
Genre,
Movie,
@ -168,8 +167,6 @@ export function DiscoverContent() {
const carouselRefs = useRef<{ [key: string]: HTMLDivElement | null }>({});
const { isMobile } = useIsMobile();
const userLanguage = useLanguageStore.getState().language;
const formattedLanguage = getTmdbLanguageCode(userLanguage);
@ -505,7 +502,6 @@ export function DiscoverContent() {
preloadedMedia={filteredGenreMovies}
title="Editor Picks"
mediaType="movie"
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreContent
@ -514,7 +510,6 @@ export function DiscoverContent() {
preloadedMedia={filteredGenreTVShows}
title="Editor Picks"
mediaType="tv"
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreContent
@ -533,7 +528,6 @@ export function DiscoverContent() {
medias={movieRecommendations}
category={movieRecommendationTitle}
isTVShow={false}
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreLink={`/discover/more/recommendations/${movieRecommendationSourceId}/movie`}
@ -548,7 +542,6 @@ export function DiscoverContent() {
<LazyMediaCarousel
category={categories[0]}
mediaType="movie"
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreContent
@ -558,7 +551,6 @@ export function DiscoverContent() {
<LazyMediaCarousel
category={categories[1]}
mediaType="movie"
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreContent
@ -568,7 +560,6 @@ export function DiscoverContent() {
<LazyMediaCarousel
category={categories[2]}
mediaType="movie"
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreContent
@ -579,7 +570,6 @@ export function DiscoverContent() {
medias={providerMovies}
category={`Movies on ${selectedProvider.name || ""}`}
isTVShow={false}
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
relatedButtons={MOVIE_PROVIDERS.map((p) => ({
@ -596,7 +586,6 @@ export function DiscoverContent() {
medias={filteredGenreMovies}
category={`${selectedGenre.name || ""}`}
isTVShow={false}
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
relatedButtons={genres.map((g) => ({
@ -621,7 +610,6 @@ export function DiscoverContent() {
medias={tvRecommendations}
category={tvRecommendationTitle}
isTVShow
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreLink={`/discover/more/recommendations/${tvRecommendationSourceId}/tv`}
@ -636,7 +624,6 @@ export function DiscoverContent() {
<LazyMediaCarousel
category={tvCategories[0]}
mediaType="tv"
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreContent
@ -646,7 +633,6 @@ export function DiscoverContent() {
<LazyMediaCarousel
category={tvCategories[1]}
mediaType="tv"
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreContent
@ -656,7 +642,6 @@ export function DiscoverContent() {
<LazyMediaCarousel
category={tvCategories[2]}
mediaType="tv"
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
moreContent
@ -667,7 +652,6 @@ export function DiscoverContent() {
medias={providerTVShows}
category={`Shows on ${selectedProvider.name || ""}`}
isTVShow
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
relatedButtons={TV_PROVIDERS.map((p) => ({
@ -684,7 +668,6 @@ export function DiscoverContent() {
medias={filteredGenreTVShows}
category={`${selectedGenre.name || ""}`}
isTVShow
isMobile={isMobile}
carouselRefs={carouselRefs}
onShowDetails={handleShowDetails}
relatedButtons={tvGenres.map((g) => ({

View file

@ -4,15 +4,14 @@ import { useTranslation } from "react-i18next";
import { EditButton } from "@/components/buttons/EditButton";
import { Icons } from "@/components/Icon";
import { SectionHeading } from "@/components/layout/SectionHeading";
import { MediaCard } from "@/components/media/MediaCard";
import { WatchedMediaCard } from "@/components/media/WatchedMediaCard";
import { useIsMobile } from "@/hooks/useIsMobile";
import { CarouselNavButtons } from "@/pages/discover/components/CarouselNavButtons";
import { useBookmarkStore } from "@/stores/bookmarks";
import { useProgressStore } from "@/stores/progress";
import { MediaItem } from "@/utils/mediaTypes";
interface BookmarksCarouselProps {
isMobile: boolean;
carouselRefs: React.MutableRefObject<{
[key: string]: HTMLDivElement | null;
}>;
@ -33,7 +32,6 @@ function MediaCardSkeleton() {
}
export function BookmarksCarousel({
isMobile,
carouselRefs,
onShowDetails,
}: BookmarksCarouselProps) {
@ -44,6 +42,8 @@ export function BookmarksCarousel({
const removeBookmark = useBookmarkStore((s) => s.removeBookmark);
const pressTimerRef = useRef<NodeJS.Timeout | null>(null);
const { isMobile } = useIsMobile();
const bookmarksLength = useBookmarkStore(
(state) => Object.keys(state.bookmarks).length,
);
@ -133,7 +133,7 @@ export function BookmarksCarousel({
<SectionHeading
title={t("home.bookmarks.sectionTitle") || "Bookmarks"}
icon={Icons.BOOKMARK}
className="ml-2 md:ml-8 mt-2 -mb-10"
className="ml-2 md:ml-8 mt-2 -mb-5"
>
<div className="mr-6">
<EditButton

View file

@ -5,13 +5,13 @@ import { EditButton } from "@/components/buttons/EditButton";
import { Icons } from "@/components/Icon";
import { SectionHeading } from "@/components/layout/SectionHeading";
import { WatchedMediaCard } from "@/components/media/WatchedMediaCard";
import { useIsMobile } from "@/hooks/useIsMobile";
import { CarouselNavButtons } from "@/pages/discover/components/CarouselNavButtons";
import { useProgressStore } from "@/stores/progress";
import { shouldShowProgress } from "@/stores/progress/utils";
import { MediaItem } from "@/utils/mediaTypes";
interface WatchingCarouselProps {
isMobile: boolean;
carouselRefs: React.MutableRefObject<{
[key: string]: HTMLDivElement | null;
}>;
@ -32,7 +32,6 @@ function MediaCardSkeleton() {
}
export function WatchingCarousel({
isMobile,
carouselRefs,
onShowDetails,
}: WatchingCarouselProps) {
@ -43,6 +42,8 @@ export function WatchingCarousel({
const removeItem = useProgressStore((s) => s.removeItem);
const pressTimerRef = useRef<NodeJS.Timeout | null>(null);
const { isMobile } = useIsMobile();
const itemsLength = useProgressStore((state) => {
return Object.entries(state.items).filter(
(entry) => shouldShowProgress(entry[1]).show,
@ -125,7 +126,7 @@ export function WatchingCarousel({
<SectionHeading
title={t("home.continueWatching.sectionTitle")}
icon={Icons.CLOCK}
className="ml-2 md:ml-8 mt-2 -mb-10"
className="ml-2 md:ml-8 mt-2 -mb-5"
>
<div className="mr-6">
<EditButton

View file

@ -20,7 +20,7 @@ function SearchSuffix(props: { failed?: boolean; results?: number }) {
const icon: Icons = props.failed ? Icons.WARNING : Icons.EYE_SLASH;
return (
<div className="mb-24 mt-40 flex flex-col items-center justify-center space-y-3 text-center">
<div className="mt-40 flex flex-col items-center justify-center space-y-3 text-center">
<IconPatch
icon={icon}
className={`text-xl ${
@ -35,7 +35,7 @@ function SearchSuffix(props: { failed?: boolean; results?: number }) {
<>
<p>{t("home.search.allResults")}</p>
<Button
className="px-py p-[0.3em] mt-3 rounded-xl text-type-dimmed box-content text-[17px] bg-largeCard-background text-buttons-secondaryText justify-center items-center"
className="px-py p-[0.3em] mt-3 rounded-xl text-type-dimmed box-content text-[17px] bg-largeCard-background justify-center items-center"
onClick={() => navigate("/discover")}
>
{t("home.search.discoverMore")}