mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-02 12:08:37 +01:00
Compare commits
2 Commits
fix/episod
...
fix/downlo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a35a807223 | ||
|
|
c9dba8a1b7 |
@@ -1,3 +1,4 @@
|
||||
import { File, Paths } from "expo-file-system";
|
||||
import { useCallback } from "react";
|
||||
import { storage } from "@/utils/mmkv";
|
||||
|
||||
@@ -12,36 +13,28 @@ const useImageStorage = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* expo-file-system instead of fetch+Blob+FileReader: the latter silently
|
||||
* resolves to an empty payload under RN's New Architecture.
|
||||
*/
|
||||
const image2Base64 = useCallback(async (url?: string | null) => {
|
||||
if (!url) return null;
|
||||
|
||||
let blob: Blob;
|
||||
const tmpFile = new File(
|
||||
Paths.cache,
|
||||
`img-${Date.now()}-${Math.random().toString(36).slice(2)}.jpg`,
|
||||
);
|
||||
try {
|
||||
// Fetch the data from the URL
|
||||
const response = await fetch(url);
|
||||
blob = await response.blob();
|
||||
const downloaded = await File.downloadFileAsync(url, tmpFile, {
|
||||
idempotent: true,
|
||||
});
|
||||
return await downloaded.base64();
|
||||
} catch (error) {
|
||||
console.warn("Error fetching image:", error);
|
||||
return null;
|
||||
} finally {
|
||||
if (tmpFile.exists) tmpFile.delete();
|
||||
}
|
||||
|
||||
// Create a FileReader instance
|
||||
const reader = new FileReader();
|
||||
|
||||
// Convert blob to base64
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
reader.onloadend = () => {
|
||||
if (typeof reader.result === "string") {
|
||||
// Extract the base64 string (remove the data URL prefix)
|
||||
const base64 = reader.result.split(",")[1];
|
||||
resolve(base64);
|
||||
} else {
|
||||
reject(new Error("Failed to convert image to base64"));
|
||||
}
|
||||
};
|
||||
reader.onerror = reject;
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const saveImage = useCallback(
|
||||
|
||||
@@ -109,35 +109,30 @@ export const usePlaybackManager = ({
|
||||
staleTime: 0,
|
||||
});
|
||||
|
||||
/**
|
||||
* Derive prev/next from the current item's real position in the adjacent
|
||||
* list rather than from the array length. `getEpisodes({ adjacentTo })` does
|
||||
* not guarantee a fixed [prev, current, next] shape — at the first/last
|
||||
* episode it can still return the current item as the first/last entry — so
|
||||
* length-based indexing wrongly surfaces the current episode as "previous".
|
||||
*/
|
||||
const currentIndex = useMemo(
|
||||
() => adjacentItems?.findIndex((e) => e.Id === item?.Id) ?? -1,
|
||||
[adjacentItems, item],
|
||||
);
|
||||
|
||||
/** A neighbour is only navigable if it has an actual media file (not a
|
||||
* "Virtual"/missing episode placeholder, e.g. an absent Special). */
|
||||
const isNavigable = (episode?: BaseItemDto | null): episode is BaseItemDto =>
|
||||
!!episode && episode.Id !== item?.Id && episode.LocationType !== "Virtual";
|
||||
|
||||
const previousItem = useMemo(() => {
|
||||
if (!adjacentItems || currentIndex <= 0) return null;
|
||||
const candidate = adjacentItems[currentIndex - 1];
|
||||
return isNavigable(candidate) ? candidate : null;
|
||||
}, [adjacentItems, currentIndex, item]);
|
||||
if (!adjacentItems || adjacentItems.length <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (adjacentItems.length === 2) {
|
||||
return adjacentItems[0].Id === item?.Id ? null : adjacentItems[0];
|
||||
}
|
||||
|
||||
return adjacentItems[0];
|
||||
}, [adjacentItems, item]);
|
||||
|
||||
/** The next item in the series */
|
||||
const nextItem = useMemo(() => {
|
||||
if (!adjacentItems || currentIndex < 0) return null;
|
||||
const candidate = adjacentItems[currentIndex + 1];
|
||||
return isNavigable(candidate) ? candidate : null;
|
||||
}, [adjacentItems, currentIndex, item]);
|
||||
if (!adjacentItems || adjacentItems.length <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (adjacentItems.length === 2) {
|
||||
return adjacentItems[1].Id === item?.Id ? null : adjacentItems[1];
|
||||
}
|
||||
|
||||
return adjacentItems[2];
|
||||
}, [adjacentItems, item]);
|
||||
|
||||
/**
|
||||
* Reports playback progress.
|
||||
|
||||
Reference in New Issue
Block a user