mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-24 03:58:08 +00:00
fix: download status
This commit is contained in:
@@ -23,12 +23,12 @@ export default function page() {
|
||||
const [seasonIndexState, setSeasonIndexState] = useState<SeasonIndexState>(
|
||||
{},
|
||||
);
|
||||
const { getDownloadedItems, deleteItems } = useDownload();
|
||||
const { downloadedItems, deleteItems } = useDownload();
|
||||
|
||||
const series = useMemo(() => {
|
||||
try {
|
||||
return (
|
||||
getDownloadedItems()
|
||||
downloadedItems
|
||||
?.filter((f) => f.item.SeriesId === seriesId)
|
||||
?.sort(
|
||||
(a, b) => a?.item.ParentIndexNumber! - b.item.ParentIndexNumber!,
|
||||
@@ -37,7 +37,7 @@ export default function page() {
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}, [getDownloadedItems]);
|
||||
}, [downloadedItems, seriesId]);
|
||||
|
||||
// Group episodes by season in a single pass
|
||||
const seasonGroups = useMemo(() => {
|
||||
|
||||
@@ -18,10 +18,7 @@ import ActiveDownloads from "@/components/downloads/ActiveDownloads";
|
||||
import { DownloadSize } from "@/components/downloads/DownloadSize";
|
||||
import { MovieCard } from "@/components/downloads/MovieCard";
|
||||
import { SeriesCard } from "@/components/downloads/SeriesCard";
|
||||
import {
|
||||
downloadsRefreshAtom,
|
||||
useDownload,
|
||||
} from "@/providers/DownloadProvider";
|
||||
import { useDownload } from "@/providers/DownloadProvider";
|
||||
import { type DownloadedItem } from "@/providers/Downloads/types";
|
||||
import { queueAtom } from "@/utils/atoms/queue";
|
||||
import { writeToLog } from "@/utils/log";
|
||||
@@ -30,13 +27,8 @@ export default function page() {
|
||||
const navigation = useNavigation();
|
||||
const { t } = useTranslation();
|
||||
const [queue, setQueue] = useAtom(queueAtom);
|
||||
const [refreshKey] = useAtom(downloadsRefreshAtom);
|
||||
const {
|
||||
removeProcess,
|
||||
getDownloadedItems,
|
||||
deleteFileByType,
|
||||
deleteAllFiles,
|
||||
} = useDownload();
|
||||
const { removeProcess, downloadedItems, deleteFileByType, deleteAllFiles } =
|
||||
useDownload();
|
||||
const router = useRouter();
|
||||
const bottomSheetModalRef = useRef<BottomSheetModal>(null);
|
||||
|
||||
@@ -66,10 +58,7 @@ export default function page() {
|
||||
);
|
||||
};
|
||||
|
||||
const downloadedFiles = useMemo(
|
||||
() => getDownloadedItems(),
|
||||
[getDownloadedItems, refreshKey],
|
||||
);
|
||||
const downloadedFiles = downloadedItems;
|
||||
|
||||
const movies = useMemo(() => {
|
||||
try {
|
||||
|
||||
@@ -64,12 +64,8 @@ export const DownloadItems: React.FC<DownloadProps> = ({
|
||||
const { settings } = useSettings();
|
||||
const [downloadUnwatchedOnly, setDownloadUnwatchedOnly] = useState(false);
|
||||
|
||||
const { processes, startBackgroundDownload, getDownloadedItems } =
|
||||
useDownload();
|
||||
const downloadedFiles = useMemo(
|
||||
() => getDownloadedItems(),
|
||||
[getDownloadedItems],
|
||||
);
|
||||
const { processes, startBackgroundDownload, downloadedItems } = useDownload();
|
||||
const downloadedFiles = downloadedItems;
|
||||
|
||||
const [selectedOptions, setSelectedOptions] = useState<
|
||||
SelectedOptions | undefined
|
||||
|
||||
@@ -119,18 +119,24 @@ export const DownloadCard = ({ process, ...props }: DownloadCardProps) => {
|
||||
{/* Action buttons in bottom right corner */}
|
||||
<View className='absolute bottom-2 right-2 flex flex-row items-center space-x-2 z-10'>
|
||||
{process.status === "downloading" && Platform.OS !== "ios" && (
|
||||
<TouchableOpacity onPress={() => handlePause()} className='p-1'>
|
||||
<TouchableOpacity
|
||||
onPress={() => handlePause()}
|
||||
className='p-2 bg-neutral-800 rounded-full'
|
||||
>
|
||||
<Ionicons name='pause' size={20} color='white' />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
{process.status === "paused" && Platform.OS !== "ios" && (
|
||||
<TouchableOpacity onPress={() => handleResume()} className='p-1'>
|
||||
<TouchableOpacity
|
||||
onPress={() => handleResume()}
|
||||
className='p-2 bg-neutral-800 rounded-full'
|
||||
>
|
||||
<Ionicons name='play' size={20} color='white' />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
<TouchableOpacity
|
||||
onPress={() => handleDelete(process.id)}
|
||||
className='p-1'
|
||||
className='p-2 bg-neutral-800 rounded-full'
|
||||
>
|
||||
<Ionicons name='close' size={20} color='red' />
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -13,17 +13,13 @@ export const DownloadSize: React.FC<DownloadSizeProps> = ({
|
||||
items,
|
||||
...props
|
||||
}) => {
|
||||
const { getDownloadedItemSize, getDownloadedItems } = useDownload();
|
||||
const downloadedFiles = useMemo(
|
||||
() => getDownloadedItems(),
|
||||
[getDownloadedItems],
|
||||
);
|
||||
const { getDownloadedItemSize, downloadedItems } = useDownload();
|
||||
const [size, setSize] = useState<string | undefined>();
|
||||
|
||||
const itemIds = useMemo(() => items.map((i) => i.Id), [items]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!downloadedFiles) return;
|
||||
if (!downloadedItems) return;
|
||||
|
||||
let s = 0;
|
||||
|
||||
@@ -35,7 +31,7 @@ export const DownloadSize: React.FC<DownloadSizeProps> = ({
|
||||
}
|
||||
}
|
||||
setSize(s.bytesToReadable());
|
||||
}, [itemIds]);
|
||||
}, [itemIds, downloadedItems, getDownloadedItemSize]);
|
||||
|
||||
const sizeText = useMemo(() => {
|
||||
if (!size) return "...";
|
||||
|
||||
@@ -72,7 +72,7 @@ export const HomeIndex = () => {
|
||||
|
||||
const scrollViewRef = useRef<ScrollView>(null);
|
||||
|
||||
const { getDownloadedItems, cleanCacheDirectory } = useDownload();
|
||||
const { downloadedItems, cleanCacheDirectory } = useDownload();
|
||||
const prevIsConnected = useRef<boolean | null>(false);
|
||||
const {
|
||||
isConnected,
|
||||
@@ -92,8 +92,8 @@ export const HomeIndex = () => {
|
||||
|
||||
const hasDownloads = useMemo(() => {
|
||||
if (Platform.isTV) return false;
|
||||
return getDownloadedItems().length > 0;
|
||||
}, [getDownloadedItems]);
|
||||
return downloadedItems.length > 0;
|
||||
}, [downloadedItems]);
|
||||
|
||||
useEffect(() => {
|
||||
if (Platform.isTV) {
|
||||
|
||||
@@ -28,11 +28,7 @@ export const SeasonEpisodesCarousel: React.FC<Props> = ({
|
||||
}) => {
|
||||
const [api] = useAtom(apiAtom);
|
||||
const [user] = useAtom(userAtom);
|
||||
const { getDownloadedItems } = useDownload();
|
||||
const downloadedFiles = useMemo(
|
||||
() => getDownloadedItems(),
|
||||
[getDownloadedItems],
|
||||
);
|
||||
const { downloadedItems } = useDownload();
|
||||
|
||||
const scrollRef = useRef<HorizontalScrollRef>(null);
|
||||
|
||||
@@ -45,10 +41,10 @@ export const SeasonEpisodesCarousel: React.FC<Props> = ({
|
||||
}, [item]);
|
||||
|
||||
const { data: episodes, isPending } = useQuery({
|
||||
queryKey: ["episodes", seasonId, isOffline],
|
||||
queryKey: ["episodes", seasonId, isOffline, downloadedItems],
|
||||
queryFn: async () => {
|
||||
if (isOffline) {
|
||||
return downloadedFiles
|
||||
return downloadedItems
|
||||
?.filter(
|
||||
(f) => f.item.Type === "Episode" && f.item.SeasonId === seasonId,
|
||||
)
|
||||
|
||||
@@ -55,11 +55,8 @@ export const EpisodeList: React.FC<Props> = ({ item, close, goToItem }) => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const { getDownloadedItems } = useDownload();
|
||||
const downloadedFiles = useMemo(
|
||||
() => getDownloadedItems(),
|
||||
[getDownloadedItems],
|
||||
);
|
||||
const { downloadedItems } = useDownload();
|
||||
const downloadedFiles = downloadedItems;
|
||||
|
||||
const seasonIndex = seasonIndexState[item.ParentId ?? ""];
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ export const usePlaybackManager = ({
|
||||
const api = useAtomValue(apiAtom);
|
||||
const user = useAtomValue(userAtom);
|
||||
const { isConnected } = useNetworkStatus();
|
||||
const { getDownloadedItemById, updateDownloadedItem, getDownloadedItems } =
|
||||
const { getDownloadedItemById, updateDownloadedItem, downloadedItems } =
|
||||
useDownload();
|
||||
|
||||
/** Whether the device is online. actually it's connected to the internet. */
|
||||
@@ -77,14 +77,20 @@ export const usePlaybackManager = ({
|
||||
|
||||
// Adjacent episodes logic
|
||||
const { data: adjacentItems } = useQuery({
|
||||
queryKey: ["adjacentItems", item?.Id, item?.SeriesId, isOffline],
|
||||
queryKey: [
|
||||
"adjacentItems",
|
||||
item?.Id,
|
||||
item?.SeriesId,
|
||||
isOffline,
|
||||
downloadedItems,
|
||||
],
|
||||
queryFn: async (): Promise<BaseItemDto[] | null> => {
|
||||
if (!item || !item.SeriesId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isOffline) {
|
||||
return getOfflineAdjacentItems(item, getDownloadedItems() || []);
|
||||
return getOfflineAdjacentItems(item, downloadedItems || []);
|
||||
}
|
||||
|
||||
if (!api) {
|
||||
|
||||
@@ -25,12 +25,17 @@ const DownloadContext = createContext<ReturnType<
|
||||
function useDownloadProvider() {
|
||||
const [api] = useAtom(apiAtom);
|
||||
const [processes, setProcesses] = useAtom<JobStatus[]>(processesAtom);
|
||||
const [, setRefreshKey] = useAtom(downloadsRefreshAtom);
|
||||
const [refreshKey, setRefreshKey] = useAtom(downloadsRefreshAtom);
|
||||
const successHapticFeedback = useHaptic("success");
|
||||
|
||||
// Track task ID to process ID mapping
|
||||
const taskMapRef = useRef<Map<number, string>>(new Map());
|
||||
|
||||
// Reactive downloaded items that updates when refreshKey changes
|
||||
const downloadedItems = useMemo(() => {
|
||||
return getAllDownloadedItems();
|
||||
}, [refreshKey]);
|
||||
|
||||
// Trigger refresh of download lists
|
||||
const triggerRefresh = useCallback(() => {
|
||||
setRefreshKey((prev) => prev + 1);
|
||||
@@ -114,7 +119,8 @@ function useDownloadProvider() {
|
||||
return {
|
||||
processes,
|
||||
startBackgroundDownload,
|
||||
getDownloadedItems: getAllDownloadedItems,
|
||||
downloadedItems, // Reactive value that auto-updates
|
||||
getDownloadedItems: getAllDownloadedItems, // Keep for backward compatibility
|
||||
getDownloadsDatabase,
|
||||
deleteAllFiles,
|
||||
deleteFile,
|
||||
@@ -144,6 +150,7 @@ export function useDownload() {
|
||||
return {
|
||||
processes: [],
|
||||
startBackgroundDownload: async () => {},
|
||||
downloadedItems: [],
|
||||
getDownloadedItems: () => [],
|
||||
getDownloadsDatabase: () => ({ movies: {}, series: {}, other: {} }),
|
||||
deleteAllFiles: async () => {},
|
||||
|
||||
Reference in New Issue
Block a user