chore: upgrade Biome to 2.4.16, clean up lint, and fix TV password modal (#1598)

This commit is contained in:
Gauvain
2026-05-29 08:32:21 +02:00
committed by GitHub
parent afe9d33ee4
commit 0ba3f44615
34 changed files with 85 additions and 46 deletions

View File

@@ -414,7 +414,7 @@ export const PlayButton: React.FC<Props> = ({
]);
const derivedTargetWidth = useDerivedValue(() => {
if (!item || !item.RunTimeTicks) return 0;
if (!item?.RunTimeTicks) return 0;
const userData = item.UserData;
if (userData?.PlaybackPositionTicks) {
return userData.PlaybackPositionTicks > 0

View File

@@ -78,7 +78,7 @@ export const PlayButton: React.FC<Props> = ({
};
const derivedTargetWidth = useDerivedValue(() => {
if (!item || !item.RunTimeTicks) return 0;
if (!item?.RunTimeTicks) return 0;
const userData = item.UserData;
if (userData?.PlaybackPositionTicks) {
return userData.PlaybackPositionTicks > 0

View File

@@ -116,7 +116,7 @@ export const DownloadCard = ({ process, ...props }: DownloadCardProps) => {
}, [process?.progress]);
// Return null after all hooks have been called
if (!process || !process.item || !process.item.Id) {
if (!process?.item?.Id) {
return null;
}

View File

@@ -351,7 +351,7 @@ export const TVHeroCarousel: React.FC<TVHeroCarouselProps> = ({
// Get subtitle for episodes
const episodeSubtitle = useMemo(() => {
if (!activeItem || activeItem.Type !== "Episode") return null;
if (activeItem?.Type !== "Episode") return null;
return `S${activeItem.ParentIndexNumber} E${activeItem.IndexNumber} · ${activeItem.Name}`;
}, [activeItem]);

View File

@@ -180,4 +180,4 @@ const styles = StyleSheet.create({
},
});
export { CARD_WIDTH, CARD_HEIGHT };
export { CARD_HEIGHT, CARD_WIDTH };

View File

@@ -155,7 +155,7 @@ export const TVLiveTVGuide: React.FC = () => {
);
// Fetch programs for visible channels
const { data: programsData, isLoading: isLoadingPrograms } = useQuery({
const { data: programsData } = useQuery({
queryKey: [
"livetv",
"tv-guide",

View File

@@ -14,6 +14,7 @@ import {
} from "react-native";
import { Text } from "@/components/common/Text";
import { useTVFocusAnimation } from "@/components/tv";
import { useTVBackPress } from "@/hooks/useTVBackPress";
import { scaleSize } from "@/utils/scaleSize";
interface TVPasswordEntryModalProps {
@@ -201,6 +202,13 @@ export const TVPasswordEntryModal: React.FC<TVPasswordEntryModalProps> = ({
setIsReady(false);
}, [visible]);
// Close the modal on the TV remote back/menu button while it is open.
useTVBackPress(() => {
if (!visible) return false;
onClose();
return true;
}, [visible, onClose]);
const handleSubmit = async () => {
if (!password) {
setError(t("password.enter_password"));

View File

@@ -59,6 +59,7 @@ import { useRemoteControl } from "./hooks/useRemoteControl";
import { useVideoTime } from "./hooks/useVideoTime";
import { TechnicalInfoOverlay } from "./TechnicalInfoOverlay";
import { TrickplayBubble } from "./TrickplayBubble";
import type { Track } from "./types";
import { useControlsTimeout } from "./useControlsTimeout";
interface Props {
@@ -315,6 +316,31 @@ export const Controls: FC<Props> = ({
[onSubtitleIndexChange],
);
// Re-fetch subtitle streams from the server (e.g. after a server-side
// download) and map them to the modal's Track shape. setTrack drives the
// player through the same handler used for manual subtitle selection.
const refreshSubtitleTracks = useCallback(async (): Promise<Track[]> => {
try {
const streams = (await onRefreshSubtitleTracks?.()) ?? [];
// Skip streams without a real index: `?? -1` would alias them to the
// "disable subtitles" sentinel and mis-route selection.
return streams
.filter((stream) => typeof stream.Index === "number")
.map((stream) => {
const index = stream.Index as number;
return {
name:
stream.DisplayTitle ||
`${stream.Language || "Unknown"} (${stream.Codec})`,
index,
setTrack: () => onSubtitleIndexChange?.(index),
};
});
} catch {
return [];
}
}, [onRefreshSubtitleTracks, onSubtitleIndexChange]);
const {
trickPlayUrl,
calculateTrickplayUrl,
@@ -572,6 +598,9 @@ export const Controls: FC<Props> = ({
disableTrack?.setTrack();
},
onLocalSubtitleDownloaded: handleLocalSubtitleDownloaded,
refreshSubtitleTracks: onRefreshSubtitleTracks
? refreshSubtitleTracks
: undefined,
});
controlsInteractionRef.current();
}, [
@@ -581,6 +610,8 @@ export const Controls: FC<Props> = ({
videoContextSubtitleTracks,
subtitleIndex,
handleLocalSubtitleDownloaded,
onRefreshSubtitleTracks,
refreshSubtitleTracks,
]);
const handleToggleTechnicalInfo = useCallback(() => {

View File

@@ -28,4 +28,4 @@ type Track = {
localPath?: string;
};
export type { EmbeddedSubtitle, ExternalSubtitle, TranscodedSubtitle, Track };
export type { EmbeddedSubtitle, ExternalSubtitle, Track, TranscodedSubtitle };