diff --git a/next.config.ts b/next.config.ts index 2fd5158..ef6aa7d 100644 --- a/next.config.ts +++ b/next.config.ts @@ -5,9 +5,7 @@ import NextBundleAnalyzer from "@next/bundle-analyzer"; import { ANALYZE, BASE_PATH, STAGING, validateConfig } from "@/utils/config"; import { error, info } from "@/utils/log"; -const withBundleAnalyzer = NextBundleAnalyzer({ - enabled: ANALYZE, -}); +const withBundleAnalyzer = NextBundleAnalyzer(); if (!validateConfig()) { error("Shutting down because of invalid configuration..."); @@ -26,6 +24,7 @@ const nextConfig: NextConfig = { }, staticPageGenerationTimeout: 3600, experimental: { + turbo: {}, // We don't want to multi-thread page building // to make use of caching between page builds. workerThreads: false, @@ -81,4 +80,4 @@ const nextConfig: NextConfig = { }, }; -export default withBundleAnalyzer(nextConfig); +export default ANALYZE ? withBundleAnalyzer(nextConfig) : nextConfig; diff --git a/src/components/switcher/Switcher.tsx b/src/components/switcher/Switcher.tsx index 8de4218..23b7ab6 100644 --- a/src/components/switcher/Switcher.tsx +++ b/src/components/switcher/Switcher.tsx @@ -35,6 +35,7 @@ const StyledSwitcher = styled.div` background-color: ${theme.colors["solid"]}; box-shadow: ${theme.shadows.low}; + isolation: isolate; ${Solid} & { background-color: ${theme.colors["solid-on-card"]}; diff --git a/src/components/video-player/VideoPlayer.style.ts b/src/components/video-player/VideoPlayer.style.ts index 2b46089..6dde26d 100644 --- a/src/components/video-player/VideoPlayer.style.ts +++ b/src/components/video-player/VideoPlayer.style.ts @@ -6,12 +6,14 @@ import { Switcher } from "@/components/switcher/Switcher"; import theme from "@/theme"; export const StyledPlayer = styled.div` - position: sticky; - bottom: 0; - display: flex; flex-direction: column; + &[data-background] { + position: sticky; + bottom: 0; + } + &:not([data-background]) { flex: 1; } @@ -161,8 +163,10 @@ export const StyledSwitcher = styled(Switcher)` `; export const StyledScrollArea = styled.div` - flex: 1 0 0; - padding-bottom: 16px; overflow: auto; + + @media (min-width: ${theme.breakpoints.desktopMin}) or (max-aspect-ratio: 1/1) { + flex: 1 0 0; + } `; diff --git a/src/components/video-player/VideoPlayerBar.tsx b/src/components/video-player/VideoPlayerBar.tsx index 96225b2..20e60d1 100644 --- a/src/components/video-player/VideoPlayerBar.tsx +++ b/src/components/video-player/VideoPlayerBar.tsx @@ -33,6 +33,10 @@ const StyledPlayerBar = styled(Solid)` transition: opacity 100ms; @media (max-width: ${theme.breakpoints.tabletMax}) { + position: sticky; + bottom: 0; + isolation: isolate; + grid-template-columns: 1fr auto; padding: 8px 16px; diff --git a/src/lib/common/animethemes/api.ts b/src/lib/common/animethemes/api.ts index 8c3de5c..90a1375 100644 --- a/src/lib/common/animethemes/api.ts +++ b/src/lib/common/animethemes/api.ts @@ -123,6 +123,7 @@ const ALLOWED_INCLUDES: Record> = { "animethemes.animethemeentries.videos.audio", "animethemes.animethemeentries.videos.videoscript", "animethemes.animethemeentries.videos.tracks.playlist", + "animethemes.animethemeentries.videos.tracks.playlist.user", "animethemes.animethemeentries.videos.animethemeentries.animetheme.anime", "animethemes.animethemeentries.videos.animethemeentries.animetheme.anime.images", "animethemes.animethemeentries.videos.animethemeentries.animetheme.animethemeentries.videos", diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 5056052..1d3e782 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -51,6 +51,7 @@ const queryClient = new QueryClient(); const StyledWrapper = styled(Column)` isolation: isolate; min-height: 100vh; + min-height: 100dvh; `; const StyledContainer = styled(Container)` diff --git a/src/pages/anime/[animeSlug]/[videoSlug]/index.tsx b/src/pages/anime/[animeSlug]/[videoSlug]/index.tsx index 089cf54..b5f757f 100644 --- a/src/pages/anime/[animeSlug]/[videoSlug]/index.tsx +++ b/src/pages/anime/[animeSlug]/[videoSlug]/index.tsx @@ -24,6 +24,7 @@ import VideoScript from "@/components/video-script/VideoScript"; import PlayerContext from "@/context/playerContext"; import type { VideoPageAllQuery, VideoPageQuery, VideoPageQueryVariables } from "@/generated/graphql"; import { fetchData } from "@/lib/server"; +import styleTheme from "@/theme"; import { VIDEO_URL } from "@/utils/config"; import createVideoSlug from "@/utils/createVideoSlug"; import extractImages from "@/utils/extractImages"; @@ -129,7 +130,13 @@ export default function VideoPage({ let isCancelled = false; setTimeout(() => { - if (isCancelled) { + // We don't want to scroll the watch list item into view + // if the video is not fixed to the viewport. + // This affects mobile devices in landscape mode. + const isMobileInLandscape = matchMedia( + `(max-width: ${styleTheme.breakpoints.tabletMax}) and (min-aspect-ratio: 1/1)`, + ).matches; + if (isCancelled || isMobileInLandscape) { return; } const currentVideoCard = getVideoCardMap().get(currentWatchListItem.watchListId);