Files
plezy/lib/models/trakt/trakt_scrobble_request.dart
T
2026-04-19 11:31:27 +02:00

111 lines
3.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'trakt_ids.dart';
/// Body for `POST /scrobble/{start|pause|stop}` and `POST /sync/history`.
///
/// Either movie IDs or show IDs + season/episode are set, never both.
/// [progress] is the percent (0100) for scrobble; ignored for `/sync/history`.
class TraktScrobbleRequest {
final TraktIds? _movieIds;
final TraktIds? _showIds;
final int? _season;
final int? _episode;
final double? progress;
const TraktScrobbleRequest._({TraktIds? movieIds, TraktIds? showIds, int? season, int? episode, this.progress})
: _movieIds = movieIds,
_showIds = showIds,
_season = season,
_episode = episode;
bool get isMovie => _movieIds != null;
bool get isEpisode => _showIds != null;
TraktScrobbleRequest copyWith({double? progress}) => TraktScrobbleRequest._(
movieIds: _movieIds,
showIds: _showIds,
season: _season,
episode: _episode,
progress: progress ?? this.progress,
);
/// Build a movie scrobble payload.
factory TraktScrobbleRequest.movie({required TraktIds ids, double? progress}) {
return TraktScrobbleRequest._(movieIds: ids, progress: progress);
}
/// Build an episode scrobble payload using the show's external IDs plus
/// season/episode index. Trakt prefers this shape over an episode-IDs-only
/// payload because it works even when the episode itself isn't in Trakt's
/// catalog yet.
factory TraktScrobbleRequest.episode({
required TraktIds showIds,
required int season,
required int number,
double? progress,
}) {
return TraktScrobbleRequest._(showIds: showIds, season: season, episode: number, progress: progress);
}
Map<String, dynamic> toJson() => {
if (_movieIds != null) 'movie': {'ids': _movieIds.toJson()},
if (_showIds != null) 'show': {'ids': _showIds.toJson()},
if (_season != null && _episode != null) 'episode': {'season': _season, 'number': _episode},
'progress': ?progress,
};
/// Build a `POST /sync/history` body that adds this item to history.
///
/// Optional [watchedAt] (ISO-8601 UTC) lets the server attribute the play
/// to a specific point in time; defaults to "now" on Trakt's side.
Map<String, dynamic> toHistoryAddBody({String? watchedAt}) {
if (isMovie) {
return {
'movies': [
{'watched_at': ?watchedAt, 'ids': _movieIds!.toJson()},
],
};
}
return {
'shows': [
{
'ids': _showIds!.toJson(),
'seasons': [
{
'number': _season,
'episodes': [
{'watched_at': ?watchedAt, 'number': _episode},
],
},
],
},
],
};
}
/// Build a `POST /sync/history/remove` body that removes this item from history.
Map<String, dynamic> toHistoryRemoveBody() {
if (isMovie) {
return {
'movies': [
{'ids': _movieIds!.toJson()},
],
};
}
return {
'shows': [
{
'ids': _showIds!.toJson(),
'seasons': [
{
'number': _season,
'episodes': [
{'number': _episode},
],
},
],
},
],
};
}
}