Merge branch 'fix/landscape-design'

This commit is contained in:
Fredrik Burmester
2024-08-29 08:45:20 +02:00
7 changed files with 77 additions and 16 deletions

View File

@@ -13,6 +13,7 @@ import { FFmpegKit } from "ffmpeg-kit-react-native";
import { useAtom } from "jotai";
import { useMemo } from "react";
import { ScrollView, TouchableOpacity, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
const downloads: React.FC = () => {
const [process, setProcess] = useAtom(runningProcesses);
@@ -53,6 +54,8 @@ const downloads: React.FC = () => {
return formatNumber(timeLeft / 10000);
}, [process]);
const insets = useSafeAreaInsets();
if (isLoading) {
return (
<View className="h-full flex flex-col items-center justify-center -mt-6">
@@ -63,7 +66,14 @@ const downloads: React.FC = () => {
return (
<ScrollView>
<View className="px-4 py-4">
<View
className="px-4 py-4"
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
paddingBottom: 100,
}}
>
<View className="mb-4 flex flex-col space-y-4">
<View>
<Text className="text-2xl font-bold mb-2">Queue</Text>

View File

@@ -18,7 +18,8 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useRouter } from "expo-router";
import { useAtom } from "jotai";
import { useCallback, useEffect, useMemo, useState } from "react";
import { RefreshControl, ScrollView, View } from "react-native";
import { RefreshControl, SafeAreaView, ScrollView, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
type BaseSection = {
title: string;
@@ -270,6 +271,8 @@ export default function index() {
// );
// }
const insets = useSafeAreaInsets();
if (e1 || e2)
return (
<View className="flex flex-col items-center justify-center h-full -mt-6">
@@ -286,6 +289,7 @@ export default function index() {
<Loader />
</View>
);
return (
<ScrollView
nestedScrollEnabled
@@ -294,7 +298,13 @@ export default function index() {
<RefreshControl refreshing={loading} onRefresh={refetch} />
}
>
<View className="flex flex-col pt-4 pb-24 gap-y-4">
<View
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
}}
className="flex flex-col pt-4 pb-24 gap-y-4"
>
<LargeMovieCarousel />
{sections.map((section, index) => {

View File

@@ -9,6 +9,7 @@ import { useQuery } from "@tanstack/react-query";
import * as Haptics from "expo-haptics";
import { useAtom } from "jotai";
import { ScrollView, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
export default function settings() {
const { logout } = useJellyfin();
@@ -23,9 +24,18 @@ export default function settings() {
refetchInterval: 1000,
});
const insets = useSafeAreaInsets();
return (
<ScrollView>
<View className="p-4 flex flex-col gap-y-4 pb-12">
<View
className="p-4 flex flex-col gap-y-4 pb-12"
style={{
paddingLeft: insets.left,
paddingRight: insets.right,
paddingBottom: 100,
}}
>
<Text className="font-bold text-2xl">Information</Text>
<View className="flex flex-col rounded-xl mb-4 overflow-hidden border-neutral-800 divide-y-2 divide-solid divide-neutral-800 ">

View File

@@ -9,7 +9,12 @@ import React, {
useMemo,
useState,
} from "react";
import { FlatList, RefreshControl, View } from "react-native";
import {
FlatList,
RefreshControl,
useWindowDimensions,
View,
} from "react-native";
import { Text } from "@/components/common/Text";
import { TouchableItemRouter } from "@/components/common/TouchableItemRouter";
@@ -39,6 +44,7 @@ import {
} from "@jellyfin/sdk/lib/utils/api";
import { FlashList } from "@shopify/flash-list";
import { Loader } from "@/components/Loader";
import { useSafeAreaInsets } from "react-native-safe-area-context";
const MemoizedTouchableItemRouter = React.memo(TouchableItemRouter);
@@ -49,6 +55,7 @@ const Page = () => {
const [api] = useAtom(apiAtom);
const [user] = useAtom(userAtom);
const navigation = useNavigation();
const { width: screenWidth } = useWindowDimensions();
const [selectedGenres, setSelectedGenres] = useAtom(genreFilterAtom);
const [selectedYears, setSelectedYears] = useAtom(yearFilterAtom);
@@ -60,6 +67,14 @@ const Page = () => {
ScreenOrientation.Orientation.PORTRAIT_UP
);
const getNumberOfColumns = useCallback(() => {
if (orientation === ScreenOrientation.Orientation.PORTRAIT_UP) return 3;
if (screenWidth < 600) return 5;
if (screenWidth < 960) return 6;
if (screenWidth < 1280) return 7;
return 6;
}, [screenWidth]);
useLayoutEffect(() => {
setSortBy([
{
@@ -193,18 +208,19 @@ const Page = () => {
key={item.Id}
style={{
width: "100%",
marginBottom:
orientation === ScreenOrientation.Orientation.PORTRAIT_UP ? 4 : 16,
marginBottom: 4,
}}
item={item}
>
<View
style={{
alignSelf:
index % 3 === 0
? "flex-end"
: (index + 1) % 3 === 0
? "flex-start"
orientation === ScreenOrientation.Orientation.PORTRAIT_UP
? index % 3 === 0
? "flex-end"
: (index + 1) % 3 === 0
? "flex-start"
: "center"
: "center",
width: "89%",
}}
@@ -375,6 +391,8 @@ const Page = () => {
]
);
const insets = useSafeAreaInsets();
if (isLoading || isLibraryLoading)
return (
<View className="w-full h-full flex items-center justify-center">
@@ -401,9 +419,7 @@ const Page = () => {
renderItem={renderItem}
keyExtractor={keyExtractor}
estimatedItemSize={244}
numColumns={
orientation === ScreenOrientation.Orientation.PORTRAIT_UP ? 3 : 5
}
numColumns={getNumberOfColumns()}
onEndReached={() => {
if (hasNextPage) {
fetchNextPage();
@@ -411,7 +427,11 @@ const Page = () => {
}}
onEndReachedThreshold={1}
ListHeaderComponent={ListHeaderComponent}
contentContainerStyle={{ paddingBottom: 24 }}
contentContainerStyle={{
paddingBottom: 24,
paddingLeft: insets.left,
paddingRight: insets.right,
}}
ItemSeparatorComponent={() => (
<View
style={{

View File

@@ -13,6 +13,7 @@ import { useNavigation } from "expo-router";
import { useAtom } from "jotai";
import { useEffect } from "react";
import { StyleSheet, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
export default function index() {
const [api] = useAtom(apiAtom);
@@ -54,6 +55,8 @@ export default function index() {
}
}, [data]);
const insets = useSafeAreaInsets();
if (isLoading)
return (
<View className="justify-center items-center h-full">
@@ -76,6 +79,8 @@ export default function index() {
paddingTop: 17,
paddingHorizontal: settings?.libraryOptions?.display === "row" ? 0 : 17,
paddingBottom: 150,
paddingLeft: insets.left,
paddingRight: insets.right,
}}
data={data}
renderItem={({ item }) => <LibraryItemCard library={item} />}

View File

@@ -28,6 +28,7 @@ import React, {
useState,
} from "react";
import { Platform, ScrollView, TouchableOpacity, View } from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useDebounce } from "use-debounce";
const exampleSearches = [
@@ -41,6 +42,7 @@ const exampleSearches = [
export default function search() {
const params = useLocalSearchParams();
const insets = useSafeAreaInsets();
const { q, prev } = params as { q: string; prev: Href<string> };
@@ -220,6 +222,10 @@ export default function search() {
<ScrollView
keyboardDismissMode="on-drag"
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={{
paddingLeft: insets.left,
paddingRight: insets.right,
}}
>
<View className="flex flex-col pt-4 pb-32">
{Platform.OS === "android" && (

View File

@@ -31,7 +31,7 @@ export const getStreamUrl = async ({
subtitleStreamIndex?: number;
forceDirectPlay?: boolean;
height?: number;
mediaSourceId?: string | null;
mediaSourceId: string | null;
}) => {
if (!api || !userId || !item?.Id || !mediaSourceId) {
return null;