mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-02 03:58:36 +01:00
chore(bottom-sheet): Migrate to expo-ui bottom sheet
This commit is contained in:
@@ -1,10 +1,3 @@
|
||||
import {
|
||||
BottomSheetBackdrop,
|
||||
type BottomSheetBackdropProps,
|
||||
BottomSheetModal,
|
||||
BottomSheetTextInput,
|
||||
BottomSheetView,
|
||||
} from "@gorhom/bottom-sheet";
|
||||
import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
@@ -13,11 +6,17 @@ import React, {
|
||||
useState,
|
||||
} from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ActivityIndicator, Keyboard } from "react-native";
|
||||
import { ActivityIndicator, Keyboard, Platform } from "react-native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { Button } from "@/components/Button";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { useCreatePlaylist } from "@/hooks/usePlaylistMutations";
|
||||
import {
|
||||
type BottomSheetMethods,
|
||||
BottomSheetModal,
|
||||
BottomSheetTextInput,
|
||||
BottomSheetView,
|
||||
} from "@/utils/expoUiBottomSheet";
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
@@ -32,7 +31,7 @@ export const CreatePlaylistModal: React.FC<Props> = ({
|
||||
onPlaylistCreated,
|
||||
initialTrackId,
|
||||
}) => {
|
||||
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
||||
const bottomSheetModalRef = useRef<BottomSheetMethods>(null);
|
||||
const insets = useSafeAreaInsets();
|
||||
const { t } = useTranslation();
|
||||
const createPlaylist = useCreatePlaylist();
|
||||
@@ -59,17 +58,6 @@ export const CreatePlaylistModal: React.FC<Props> = ({
|
||||
[setOpen],
|
||||
);
|
||||
|
||||
const renderBackdrop = useCallback(
|
||||
(props: BottomSheetBackdropProps) => (
|
||||
<BottomSheetBackdrop
|
||||
{...props}
|
||||
disappearsOnIndex={-1}
|
||||
appearsOnIndex={0}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
const handleCreate = useCallback(async () => {
|
||||
if (!name.trim()) return;
|
||||
|
||||
@@ -86,13 +74,15 @@ export const CreatePlaylistModal: React.FC<Props> = ({
|
||||
|
||||
const isValid = name.trim().length > 0;
|
||||
|
||||
if (Platform.isTV) return null;
|
||||
|
||||
return (
|
||||
<BottomSheetModal
|
||||
ref={bottomSheetModalRef}
|
||||
enablePanDownToClose
|
||||
index={0}
|
||||
snapPoints={snapPoints}
|
||||
onChange={handleSheetChanges}
|
||||
backdropComponent={renderBackdrop}
|
||||
handleIndicatorStyle={{
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import {
|
||||
BottomSheetBackdrop,
|
||||
type BottomSheetBackdropProps,
|
||||
BottomSheetModal,
|
||||
BottomSheetView,
|
||||
} from "@gorhom/bottom-sheet";
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Alert, StyleSheet, TouchableOpacity, View } from "react-native";
|
||||
import {
|
||||
Alert,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import useRouter from "@/hooks/useAppRouter";
|
||||
import { useDeletePlaylist } from "@/hooks/usePlaylistMutations";
|
||||
import {
|
||||
type BottomSheetMethods,
|
||||
BottomSheetModal,
|
||||
BottomSheetView,
|
||||
} from "@/utils/expoUiBottomSheet";
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
@@ -25,7 +30,7 @@ export const PlaylistOptionsSheet: React.FC<Props> = ({
|
||||
setOpen,
|
||||
playlist,
|
||||
}) => {
|
||||
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
||||
const bottomSheetModalRef = useRef<BottomSheetMethods>(null);
|
||||
const router = useRouter();
|
||||
const insets = useSafeAreaInsets();
|
||||
const { t } = useTranslation();
|
||||
@@ -47,17 +52,6 @@ export const PlaylistOptionsSheet: React.FC<Props> = ({
|
||||
[setOpen],
|
||||
);
|
||||
|
||||
const renderBackdrop = useCallback(
|
||||
(props: BottomSheetBackdropProps) => (
|
||||
<BottomSheetBackdrop
|
||||
{...props}
|
||||
disappearsOnIndex={-1}
|
||||
appearsOnIndex={0}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
const handleDeletePlaylist = useCallback(() => {
|
||||
if (!playlist?.Id) return;
|
||||
|
||||
@@ -89,14 +83,15 @@ export const PlaylistOptionsSheet: React.FC<Props> = ({
|
||||
}, [playlist, deletePlaylist, setOpen, router, t]);
|
||||
|
||||
if (!playlist) return null;
|
||||
if (Platform.isTV) return null;
|
||||
|
||||
return (
|
||||
<BottomSheetModal
|
||||
ref={bottomSheetModalRef}
|
||||
enablePanDownToClose
|
||||
index={0}
|
||||
snapPoints={snapPoints}
|
||||
onChange={handleSheetChanges}
|
||||
backdropComponent={renderBackdrop}
|
||||
handleIndicatorStyle={{
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import {
|
||||
BottomSheetBackdrop,
|
||||
type BottomSheetBackdropProps,
|
||||
BottomSheetModal,
|
||||
BottomSheetScrollView,
|
||||
} from "@gorhom/bottom-sheet";
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
@@ -20,6 +14,7 @@ import React, {
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
@@ -29,6 +24,11 @@ import { Input } from "@/components/common/Input";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import { useAddToPlaylist } from "@/hooks/usePlaylistMutations";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import {
|
||||
type BottomSheetMethods,
|
||||
BottomSheetModal,
|
||||
BottomSheetScrollView,
|
||||
} from "@/utils/expoUiBottomSheet";
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
@@ -43,7 +43,7 @@ export const PlaylistPickerSheet: React.FC<Props> = ({
|
||||
trackToAdd,
|
||||
onCreateNew,
|
||||
}) => {
|
||||
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
||||
const bottomSheetModalRef = useRef<BottomSheetMethods>(null);
|
||||
const [api] = useAtom(apiAtom);
|
||||
const [user] = useAtom(userAtom);
|
||||
const insets = useSafeAreaInsets();
|
||||
@@ -101,17 +101,6 @@ export const PlaylistPickerSheet: React.FC<Props> = ({
|
||||
[setOpen],
|
||||
);
|
||||
|
||||
const renderBackdrop = useCallback(
|
||||
(props: BottomSheetBackdropProps) => (
|
||||
<BottomSheetBackdrop
|
||||
{...props}
|
||||
disappearsOnIndex={-1}
|
||||
appearsOnIndex={0}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
const handleSelectPlaylist = useCallback(
|
||||
async (playlist: BaseItemDto) => {
|
||||
if (!trackToAdd?.Id || !playlist.Id) return;
|
||||
@@ -142,13 +131,15 @@ export const PlaylistPickerSheet: React.FC<Props> = ({
|
||||
[api],
|
||||
);
|
||||
|
||||
if (Platform.isTV) return null;
|
||||
|
||||
return (
|
||||
<BottomSheetModal
|
||||
ref={bottomSheetModalRef}
|
||||
enablePanDownToClose
|
||||
index={0}
|
||||
snapPoints={snapPoints}
|
||||
onChange={handleSheetChanges}
|
||||
backdropComponent={renderBackdrop}
|
||||
handleIndicatorStyle={{
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import {
|
||||
BottomSheetBackdrop,
|
||||
type BottomSheetBackdropProps,
|
||||
BottomSheetModal,
|
||||
BottomSheetView,
|
||||
} from "@gorhom/bottom-sheet";
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { StyleSheet, TouchableOpacity, View } from "react-native";
|
||||
import { Platform, StyleSheet, TouchableOpacity, View } from "react-native";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { Text } from "@/components/common/Text";
|
||||
import {
|
||||
type BottomSheetMethods,
|
||||
BottomSheetModal,
|
||||
BottomSheetView,
|
||||
} from "@/utils/expoUiBottomSheet";
|
||||
|
||||
export type PlaylistSortOption = "SortName" | "DateCreated";
|
||||
|
||||
@@ -43,7 +42,7 @@ export const PlaylistSortSheet: React.FC<Props> = ({
|
||||
sortOrder,
|
||||
onSortChange,
|
||||
}) => {
|
||||
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
||||
const bottomSheetModalRef = useRef<BottomSheetMethods>(null);
|
||||
const insets = useSafeAreaInsets();
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -63,17 +62,6 @@ export const PlaylistSortSheet: React.FC<Props> = ({
|
||||
[setOpen],
|
||||
);
|
||||
|
||||
const renderBackdrop = useCallback(
|
||||
(props: BottomSheetBackdropProps) => (
|
||||
<BottomSheetBackdrop
|
||||
{...props}
|
||||
disappearsOnIndex={-1}
|
||||
appearsOnIndex={0}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
const handleSortSelect = useCallback(
|
||||
(option: PlaylistSortOption) => {
|
||||
// If selecting same option, toggle order; otherwise use sensible default
|
||||
@@ -93,13 +81,15 @@ export const PlaylistSortSheet: React.FC<Props> = ({
|
||||
[sortBy, sortOrder, onSortChange, setOpen],
|
||||
);
|
||||
|
||||
if (Platform.isTV) return null;
|
||||
|
||||
return (
|
||||
<BottomSheetModal
|
||||
ref={bottomSheetModalRef}
|
||||
enablePanDownToClose
|
||||
index={0}
|
||||
snapPoints={snapPoints}
|
||||
onChange={handleSheetChanges}
|
||||
backdropComponent={renderBackdrop}
|
||||
handleIndicatorStyle={{
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import {
|
||||
BottomSheetBackdrop,
|
||||
type BottomSheetBackdropProps,
|
||||
BottomSheetModal,
|
||||
BottomSheetView,
|
||||
} from "@gorhom/bottom-sheet";
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { Image } from "expo-image";
|
||||
import { useAtom } from "jotai";
|
||||
@@ -18,6 +12,7 @@ import React, {
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Platform,
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
@@ -36,6 +31,11 @@ import {
|
||||
} from "@/providers/AudioStorage";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { useMusicPlayer } from "@/providers/MusicPlayerProvider";
|
||||
import {
|
||||
type BottomSheetMethods,
|
||||
BottomSheetModal,
|
||||
BottomSheetView,
|
||||
} from "@/utils/expoUiBottomSheet";
|
||||
import { getAudioStreamUrl } from "@/utils/jellyfin/audio/getAudioStreamUrl";
|
||||
import { getPrimaryImageUrl } from "@/utils/jellyfin/image/getPrimaryImageUrl";
|
||||
|
||||
@@ -56,7 +56,7 @@ export const TrackOptionsSheet: React.FC<Props> = ({
|
||||
playlistId,
|
||||
onRemoveFromPlaylist,
|
||||
}) => {
|
||||
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
||||
const bottomSheetModalRef = useRef<BottomSheetMethods>(null);
|
||||
const [api] = useAtom(apiAtom);
|
||||
const [user] = useAtom(userAtom);
|
||||
const router = useRouter();
|
||||
@@ -128,17 +128,6 @@ export const TrackOptionsSheet: React.FC<Props> = ({
|
||||
[setOpen],
|
||||
);
|
||||
|
||||
const renderBackdrop = useCallback(
|
||||
(props: BottomSheetBackdropProps) => (
|
||||
<BottomSheetBackdrop
|
||||
{...props}
|
||||
disappearsOnIndex={-1}
|
||||
appearsOnIndex={0}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
const handlePlayNext = useCallback(() => {
|
||||
if (track) {
|
||||
playNext(track);
|
||||
@@ -227,13 +216,14 @@ export const TrackOptionsSheet: React.FC<Props> = ({
|
||||
const hasAlbum = !!(track?.AlbumId || track?.ParentId);
|
||||
|
||||
if (!track) return null;
|
||||
if (Platform.isTV) return null;
|
||||
|
||||
return (
|
||||
<BottomSheetModal
|
||||
ref={bottomSheetModalRef}
|
||||
enablePanDownToClose
|
||||
enableDynamicSizing
|
||||
onChange={handleSheetChanges}
|
||||
backdropComponent={renderBackdrop}
|
||||
handleIndicatorStyle={{
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user