mirror of
https://github.com/p-stream/p-stream.git
synced 2026-03-11 17:55:33 +00:00
refactor and simplify search bar positioning
This commit is contained in:
parent
544fe97c5e
commit
b6a8028eff
2 changed files with 22 additions and 57 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import classNames from "classnames";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useAsyncFn, useWindowSize } from "react-use";
|
||||
import { useAsyncFn } from "react-use";
|
||||
|
||||
import {
|
||||
base64ToBuffer,
|
||||
|
|
@ -33,6 +33,7 @@ import { RegisterCalloutPart } from "@/pages/parts/settings/RegisterCalloutPart"
|
|||
import { SidebarPart } from "@/pages/parts/settings/SidebarPart";
|
||||
import { PageTitle } from "@/pages/parts/util/PageTitle";
|
||||
import { AccountWithToken, useAuthStore } from "@/stores/auth";
|
||||
import { useBannerSize } from "@/stores/banner";
|
||||
import { useLanguageStore } from "@/stores/language";
|
||||
import { usePreferencesStore } from "@/stores/preferences";
|
||||
import { useSubtitleStore } from "@/stores/subtitles";
|
||||
|
|
@ -56,30 +57,13 @@ function SettingsLayout(props: {
|
|||
const { t } = useTranslation();
|
||||
const { isMobile } = useIsMobile();
|
||||
const searchRef = useRef<HTMLInputElement>(null);
|
||||
const { width: windowWidth, height: windowHeight } = useWindowSize();
|
||||
const bannerSize = useBannerSize();
|
||||
|
||||
// Dynamic offset calculation like HeroPart
|
||||
const topSpacing = 16; // Base spacing
|
||||
const [stickyOffset, setStickyOffset] = useState(topSpacing);
|
||||
|
||||
// Detect if running as a PWA on iOS
|
||||
const isIOSPWA =
|
||||
/iPad|iPhone|iPod/i.test(navigator.userAgent) &&
|
||||
window.matchMedia("(display-mode: standalone)").matches;
|
||||
|
||||
const adjustedTopSpacing = isIOSPWA ? 60 : topSpacing;
|
||||
const isLandscape = windowHeight < windowWidth && isIOSPWA;
|
||||
const adjustedOffset = isLandscape ? -40 : 0;
|
||||
|
||||
useEffect(() => {
|
||||
if (windowWidth > 1280) {
|
||||
// On large screens the bar goes inline with the nav elements
|
||||
setStickyOffset(adjustedTopSpacing);
|
||||
} else {
|
||||
// On smaller screens the bar goes below the nav elements
|
||||
setStickyOffset(adjustedTopSpacing + 60 + adjustedOffset);
|
||||
}
|
||||
}, [adjustedOffset, adjustedTopSpacing, windowWidth]);
|
||||
// Navbar height is 80px (h-20)
|
||||
const navbarHeight = 80;
|
||||
// On desktop: inline with navbar (same top position + 14px adjustment)
|
||||
// On mobile: below navbar (navbar height + banner)
|
||||
const topOffset = isMobile ? navbarHeight + bannerSize : bannerSize + 14;
|
||||
|
||||
return (
|
||||
<WideContainer ultraWide classNames="overflow-visible">
|
||||
|
|
@ -87,7 +71,7 @@ function SettingsLayout(props: {
|
|||
<div
|
||||
className="fixed left-0 right-0 z-50"
|
||||
style={{
|
||||
top: `${stickyOffset}px`,
|
||||
top: `${topOffset}px`,
|
||||
}}
|
||||
>
|
||||
<ThinContainer>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import classNames from "classnames";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useCallback, 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 { useIsMobile } from "@/hooks/useIsMobile";
|
||||
import { useIsTV } from "@/hooks/useIsTv";
|
||||
import { useRandomTranslation } from "@/hooks/useRandomTranslation";
|
||||
import { useSearchQuery } from "@/hooks/useSearchQuery";
|
||||
|
|
@ -44,41 +44,22 @@ export function HeroPart({
|
|||
const [search, setSearch, setSearchUnFocus] = searchParams;
|
||||
const [showBg, setShowBg] = useState(false);
|
||||
const bannerSize = useBannerSize();
|
||||
const { isMobile } = useIsMobile();
|
||||
const { isTV } = useIsTV();
|
||||
|
||||
const stickStateChanged = useCallback(
|
||||
(isFixed: boolean) => {
|
||||
setShowBg(isFixed);
|
||||
setIsSticky(isFixed);
|
||||
},
|
||||
[setShowBg, setIsSticky],
|
||||
[setIsSticky],
|
||||
);
|
||||
|
||||
const { width: windowWidth, height: windowHeight } = useWindowSize();
|
||||
|
||||
const { isTV } = useIsTV();
|
||||
|
||||
// Detect if running as a PWA on iOS
|
||||
const isIOSPWA =
|
||||
/iPad|iPhone|iPod/i.test(navigator.userAgent) &&
|
||||
window.matchMedia("(display-mode: standalone)").matches;
|
||||
|
||||
const topSpacing = isIOSPWA ? 60 : 16;
|
||||
const [stickyOffset, setStickyOffset] = useState(topSpacing);
|
||||
|
||||
const isLandscape = windowHeight < windowWidth && isIOSPWA;
|
||||
const adjustedOffset = isLandscape
|
||||
? -40 // landscape
|
||||
: 0; // portrait
|
||||
|
||||
useEffect(() => {
|
||||
if (windowWidth > 1280) {
|
||||
// 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 + adjustedOffset);
|
||||
}
|
||||
}, [adjustedOffset, topSpacing, windowWidth]);
|
||||
// Navbar height is 80px (h-20)
|
||||
const navbarHeight = 80;
|
||||
// On desktop: inline with navbar (same top position)
|
||||
// On mobile: below navbar (navbar height + banner)
|
||||
const topOffset = isMobile ? navbarHeight + bannerSize : bannerSize + 14;
|
||||
|
||||
const time = getTimeOfDay(new Date());
|
||||
const title = randomT(`home.titles.${time}`);
|
||||
|
|
@ -91,7 +72,7 @@ export function HeroPart({
|
|||
<div
|
||||
className={classNames(
|
||||
"space-y-16 text-center",
|
||||
showTitle ? "mt-44" : `mt-4`,
|
||||
showTitle ? "mt-44" : "mt-4",
|
||||
)}
|
||||
>
|
||||
{showTitle && (!isTV || search.length === 0) ? (
|
||||
|
|
@ -102,9 +83,9 @@ export function HeroPart({
|
|||
|
||||
<div className="relative h-20 z-30">
|
||||
<Sticky
|
||||
topOffset={stickyOffset * -1 + bannerSize}
|
||||
topOffset={-topOffset}
|
||||
stickyStyle={{
|
||||
paddingTop: `${stickyOffset + bannerSize}px`,
|
||||
paddingTop: `${topOffset}px`,
|
||||
}}
|
||||
onFixedToggle={stickStateChanged}
|
||||
>
|
||||
|
|
|
|||
Loading…
Reference in a new issue