Fixed bug with sync not working

This commit is contained in:
Alex Kim
2025-08-03 16:30:16 +10:00
parent 8213504665
commit 2bf75b02e3
3 changed files with 40 additions and 32 deletions

View File

@@ -239,16 +239,15 @@ export default function page() {
]);
useEffect(() => {
if (!stream || offline) return;
if (!stream || !api) return;
const reportPlaybackStart = async () => {
await getPlaystateApi(api!).reportPlaybackStart({
console.log("reporting playback start", currentPlayStateInfo());
await getPlaystateApi(api).reportPlaybackStart({
playbackStartInfo: currentPlayStateInfo() as PlaybackStartInfo,
});
};
reportPlaybackStart();
}, [stream]);
}, [stream, api]);
const togglePlay = async () => {
lightHapticFeedback();

View File

@@ -1,4 +1,3 @@
import { PlaybackProgressInfo } from "@jellyfin/sdk/lib/generated-client";
import { getPlaystateApi } from "@jellyfin/sdk/lib/utils/api";
import { getUserLibraryApi } from "@jellyfin/sdk/lib/utils/api/user-library-api";
import { useNetInfo } from "@react-native-community/netinfo";
@@ -74,17 +73,20 @@ export const usePlaybackManager = () => {
// Handle local state update for downloaded items
if (localItem) {
const isItemConsideredPlayed =
(localItem.item.UserData?.PlayedPercentage ?? 0) > 90;
updateDownloadedItem(itemId, {
...localItem,
item: {
...localItem.item,
UserData: {
...localItem.item.UserData,
PlaybackPositionTicks: positionTicks,
Played: false,
PlaybackPositionTicks: isItemConsideredPlayed ? 0 : positionTicks,
Played: isItemConsideredPlayed,
LastPlayedDate: new Date().toISOString(),
PlayedPercentage:
(positionTicks / localItem.item.RunTimeTicks!) * 100,
PlayedPercentage: isItemConsideredPlayed
? 0
: (positionTicks / localItem.item.RunTimeTicks!) * 100,
},
},
});
@@ -92,15 +94,20 @@ export const usePlaybackManager = () => {
// Handle remote state update if online
if (isOnline && api) {
await getPlaystateApi(api).reportPlaybackProgress({
playbackProgressInfo: {
ItemId: itemId,
PositionTicks: positionTicks,
AudioStreamIndex: metadata?.AudioStreamIndex,
SubtitleStreamIndex: metadata?.SubtitleStreamIndex,
} as PlaybackProgressInfo,
});
try {
await getPlaystateApi(api).reportPlaybackProgress({
playbackProgressInfo: {
ItemId: itemId,
PositionTicks: positionTicks,
...(metadata && { AudioStreamIndex: metadata.AudioStreamIndex }),
...(metadata && {
SubtitleStreamIndex: metadata.SubtitleStreamIndex,
}),
},
});
} catch (error) {
console.error("Failed to report playback progress on server", error);
}
// If it was a downloaded item, re-sync with the server for the latest state.
// This is crucial because the server might have marked the item as "Played"
// based on its own rules (e.g., >95% progress).

View File

@@ -1,4 +1,4 @@
import { getUserLibraryApi } from "@jellyfin/sdk/lib/utils/api";
import { getItemsApi, getUserLibraryApi } from "@jellyfin/sdk/lib/utils/api";
import { useNetInfo } from "@react-native-community/netinfo";
import { useAtomValue } from "jotai";
import { useDownload } from "@/providers/DownloadProvider";
@@ -46,7 +46,8 @@ export const useTwoWaySync = () => {
// If the remote item has been played more recently or at the same time,
// we take the server's version as the source of truth.
if (remoteLastPlayed >= localLastPlayed) {
if (remoteLastPlayed > localLastPlayed) {
updateDownloadedItem(itemId, {
...localItem,
item: {
@@ -61,20 +62,21 @@ export const useTwoWaySync = () => {
},
});
return false;
} else {
} else if (remoteLastPlayed < localLastPlayed) {
// Since we're this is the source of truth, essentially need to make sure the played status matches the local item.
localItem.item.UserData?.Played
? await markItemPlayed(localItem.item.Id!)
: await markItemUnplayed(localItem.item.Id!);
// The local item was played more recently (i.e., while offline),
// so we need to push its state to the server using our manager.
await reportPlaybackProgress(
localItem.item.Id!,
localItem.item.UserData?.PlaybackPositionTicks || 0,
);
await getItemsApi(api).updateItemUserData({
itemId: localItem.item.Id!,
userId: user.Id,
updateUserItemDataDto: {
Played: localItem.item.UserData?.Played,
PlaybackPositionTicks: localItem.item.UserData?.PlaybackPositionTicks,
PlayedPercentage: localItem.item.UserData?.PlayedPercentage,
LastPlayedDate: localItem.item.UserData?.LastPlayedDate,
},
});
return true;
}
return false;
};
return { syncPlaybackState };