mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-01 03:28:27 +01:00
Compare commits
4 Commits
feat/playe
...
fix/chapte
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
885976d464 | ||
|
|
6b7ee0514f | ||
|
|
c663bd0413 | ||
|
|
52e6f56220 |
@@ -6,6 +6,7 @@ import {
|
||||
BottomSheetTextInput,
|
||||
BottomSheetView,
|
||||
} from "@gorhom/bottom-sheet";
|
||||
import type { BottomSheetModalMethods } from "@gorhom/bottom-sheet/lib/typescript/types";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Image } from "expo-image";
|
||||
import { useLocalSearchParams, useNavigation } from "expo-router";
|
||||
@@ -76,7 +77,7 @@ const MobilePage: React.FC = () => {
|
||||
const [issueMessage, setIssueMessage] = useState<string>();
|
||||
const [requestBody, _setRequestBody] = useState<MediaRequestBody>();
|
||||
const [issueTypeDropdownOpen, setIssueTypeDropdownOpen] = useState(false);
|
||||
const advancedReqModalRef = useRef<BottomSheetModal>(null);
|
||||
const advancedReqModalRef = useRef<BottomSheetModalMethods>(null);
|
||||
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
||||
|
||||
const {
|
||||
|
||||
@@ -74,6 +74,9 @@ function ChapterListComponent({
|
||||
transparent
|
||||
animationType='slide'
|
||||
onRequestClose={onClose}
|
||||
// iOS defaults <Modal> to portrait-only; without this it rotates the app
|
||||
// back to portrait when opened from the landscape player. Android ignores it.
|
||||
supportedOrientations={["portrait", "landscape"]}
|
||||
>
|
||||
<Pressable onPress={onClose} style={styles.backdrop}>
|
||||
<Pressable onPress={(e) => e.stopPropagation()} style={styles.sheet}>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useActionSheet } from "@expo/react-native-action-sheet";
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { useSegments } from "expo-router";
|
||||
import { type PropsWithChildren, useCallback } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Platform,
|
||||
TouchableOpacity,
|
||||
@@ -149,6 +150,7 @@ export const TouchableItemRouter: React.FC<PropsWithChildren<Props>> = ({
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const segments = useSegments();
|
||||
const { showActionSheetWithOptions } = useActionSheet();
|
||||
const markAsPlayedStatus = useMarkAsPlayed([item]);
|
||||
@@ -182,11 +184,13 @@ export const TouchableItemRouter: React.FC<PropsWithChildren<Props>> = ({
|
||||
return;
|
||||
|
||||
const options: string[] = [
|
||||
"Mark as Played",
|
||||
"Mark as Not Played",
|
||||
isFavorite ? "Unmark as Favorite" : "Mark as Favorite",
|
||||
...(isOffline ? ["Delete Download"] : []),
|
||||
"Cancel",
|
||||
t("common.mark_as_played"),
|
||||
t("common.mark_as_not_played"),
|
||||
isFavorite
|
||||
? t("music.track_options.remove_from_favorites")
|
||||
: t("music.track_options.add_to_favorites"),
|
||||
...(isOffline ? [t("home.downloads.delete_download")] : []),
|
||||
t("common.cancel"),
|
||||
];
|
||||
const cancelButtonIndex = options.length - 1;
|
||||
const destructiveButtonIndex = isOffline
|
||||
@@ -219,6 +223,7 @@ export const TouchableItemRouter: React.FC<PropsWithChildren<Props>> = ({
|
||||
isOffline,
|
||||
deleteFile,
|
||||
item.Id,
|
||||
t,
|
||||
]);
|
||||
|
||||
if (
|
||||
|
||||
@@ -69,6 +69,13 @@ const initialApi = (() => {
|
||||
|
||||
const initialUser = (() => {
|
||||
try {
|
||||
// Only return a stored user if we also have a token. Otherwise the
|
||||
// user atom would be populated while the api atom is null (e.g. after
|
||||
// a logout that left stale user JSON in storage), which causes
|
||||
// useProtectedRoute to keep us inside the (auth) group instead of
|
||||
// redirecting to /login.
|
||||
const token = storage.getString("token");
|
||||
if (!token) return null;
|
||||
const userStr = storage.getString("user");
|
||||
if (userStr) {
|
||||
return JSON.parse(userStr) as UserDto;
|
||||
@@ -402,6 +409,7 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
|
||||
);
|
||||
|
||||
storage.remove("token");
|
||||
storage.remove("user");
|
||||
clearTVDiscoverySafely();
|
||||
setUser(null);
|
||||
setApi(null);
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
"new_app_version_requires_re_download_description": "Die neue App-Version erfordert das erneute Herunterladen von Filmen und Serien. Bitte lösche alle heruntergeladenen Elemente und starte den Download erneut.",
|
||||
"back": "Zurück",
|
||||
"delete": "Löschen",
|
||||
"delete_download": "Download löschen",
|
||||
"something_went_wrong": "Etwas ist schiefgelaufen",
|
||||
"could_not_get_stream_url_from_jellyfin": "Konnte keine Stream-URL von Jellyfin erhalten",
|
||||
"eta": "ETA {{eta}}",
|
||||
@@ -498,6 +499,8 @@
|
||||
"audio": "Audio",
|
||||
"subtitle": "Untertitel",
|
||||
"play": "Abspielen",
|
||||
"mark_as_played": "Als gesehen markieren",
|
||||
"mark_as_not_played": "Als ungesehen markieren",
|
||||
"none": "Keine",
|
||||
"track": "Spur",
|
||||
"cancel": "Abbrechen",
|
||||
|
||||
@@ -534,6 +534,7 @@
|
||||
"new_app_version_requires_re_download_description": "The new update requires content to be downloaded again. Please remove all downloaded content and try again.",
|
||||
"back": "Back",
|
||||
"delete": "Delete",
|
||||
"delete_download": "Delete Download",
|
||||
"something_went_wrong": "Something Went Wrong",
|
||||
"could_not_get_stream_url_from_jellyfin": "Could not get the stream URL from Jellyfin",
|
||||
"eta": "ETA {{eta}}",
|
||||
@@ -577,6 +578,8 @@
|
||||
"audio": "Audio",
|
||||
"subtitle": "Subtitle",
|
||||
"play": "Play",
|
||||
"mark_as_played": "Mark as Played",
|
||||
"mark_as_not_played": "Mark as not Played",
|
||||
"none": "None",
|
||||
"track": "Track",
|
||||
"cancel": "Cancel",
|
||||
|
||||
Reference in New Issue
Block a user