Schedule: "waiting · searched N min ago" and "release rejected" (with AnimeFlow's reason) from its new episode fields
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a407d3cbb0
commit
572104f49e
5 files changed
+37
-7
No files matched your search
@@ -210,7 +210,8 @@ marked with what the Jellyfin server has of it when AnimeFlow is
|
||||
connected (Settings, Jellyfin & integrations): **on Jellyfin** (Put it
|
||||
up, right-click to queue), **downloading**, **waiting for release**
|
||||
(aired in Japan, AnimeFlow downloads it by itself once a release
|
||||
appears), **failed**, **not monitored** (Request asks AnimeFlow for it),
|
||||
appears; with when AnimeFlow last searched, or **release rejected** when
|
||||
it found releases it won't take, the reason on hover), **failed**, **not monitored** (Request asks AnimeFlow for it),
|
||||
or the time left until it airs. A show AnimeFlow does not follow can be asked for with **Request
|
||||
series**. Episodes you already watched on Jellyfin carry a check on the
|
||||
cover; one you started shows how far you got.
|
||||
|
||||
@@ -210,8 +210,11 @@ class AnimeFlowEpisode {
|
||||
final EpisodeStatus status;
|
||||
/// 0..1, only while downloading.
|
||||
final double? progress;
|
||||
/// Only when failed.
|
||||
/// Why it failed; for a missing one with rejected releases, a
|
||||
/// ready-to-show sentence ("2 release(s) found, rejected: …").
|
||||
final String? reason;
|
||||
/// Last search for a monitored, not yet downloaded episode.
|
||||
final DateTime? lastSearchedAt;
|
||||
|
||||
const AnimeFlowEpisode({
|
||||
required this.season,
|
||||
@@ -224,6 +227,7 @@ class AnimeFlowEpisode {
|
||||
required this.status,
|
||||
this.progress,
|
||||
this.reason,
|
||||
this.lastSearchedAt,
|
||||
});
|
||||
|
||||
static AnimeFlowEpisode fromJson(Map j) => AnimeFlowEpisode(
|
||||
@@ -239,6 +243,7 @@ class AnimeFlowEpisode {
|
||||
status: EpisodeStatus.parse(j['status']),
|
||||
progress: (j['progress'] as num?)?.toDouble(),
|
||||
reason: _str(j['reason']),
|
||||
lastSearchedAt: _time(j['last_searched_at']),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,8 +48,10 @@ class ScheduleEntry {
|
||||
final ScheduleStatus status;
|
||||
/// 0..1 while downloading.
|
||||
final double? progress;
|
||||
/// Why it failed.
|
||||
/// Why it failed, or (missing) why the releases found were rejected.
|
||||
final String? reason;
|
||||
/// AnimeFlow's last search for it (missing).
|
||||
final DateTime? lastSearchedAt;
|
||||
/// AnimeFlow tracks the series.
|
||||
final bool tracked;
|
||||
/// AnimeFlow's series id (requests).
|
||||
@@ -74,6 +76,7 @@ class ScheduleEntry {
|
||||
required this.status,
|
||||
this.progress,
|
||||
this.reason,
|
||||
this.lastSearchedAt,
|
||||
this.tracked = false,
|
||||
this.seriesId,
|
||||
this.season,
|
||||
@@ -87,6 +90,7 @@ class ScheduleEntry {
|
||||
status: status ?? this.status,
|
||||
progress: progress,
|
||||
reason: reason,
|
||||
lastSearchedAt: lastSearchedAt,
|
||||
tracked: tracked,
|
||||
seriesId: seriesId,
|
||||
season: season,
|
||||
@@ -231,7 +235,8 @@ List<ScheduleEntry> matchSchedule(
|
||||
airing: a,
|
||||
status: ScheduleStatus.of(e.status),
|
||||
progress: e.status == EpisodeStatus.downloading ? e.progress : null,
|
||||
reason: e.status == EpisodeStatus.failed ? e.reason : null,
|
||||
reason: e.status == EpisodeStatus.failed || e.status == EpisodeStatus.missing ? e.reason : null,
|
||||
lastSearchedAt: e.lastSearchedAt,
|
||||
tracked: true,
|
||||
seriesId: it.seriesId,
|
||||
season: e.season,
|
||||
|
||||
@@ -42,9 +42,21 @@ bool _waiting(ScheduleEntry e, DateTime now) =>
|
||||
|
||||
const waitingHint = 'Aired in Japan; downloads automatically when a release appears';
|
||||
|
||||
String _ago(DateTime t, DateTime now) {
|
||||
final m = now.difference(t).inMinutes;
|
||||
return m < 1 ? 'just now' : m < 60 ? '$m min ago' : '${m ~/ 60} h ago';
|
||||
}
|
||||
|
||||
/// Status line: text, colour, icon.
|
||||
(String, Color, IconData) statusBadge(ScheduleEntry e, DateTime now) => _waiting(e, now)
|
||||
? ('waiting for release', Colors.amber.shade200, Icons.hourglass_top)
|
||||
? e.reason != null
|
||||
// Releases exist but AnimeFlow rejected them (the hint says why).
|
||||
? ('release rejected', Colors.orangeAccent, Icons.block)
|
||||
: (
|
||||
e.lastSearchedAt == null ? 'waiting for release' : 'waiting · searched ${_ago(e.lastSearchedAt!, now)}',
|
||||
Colors.amber.shade200,
|
||||
Icons.hourglass_top,
|
||||
)
|
||||
: switch (e.status) {
|
||||
ScheduleStatus.available => ('on Jellyfin', Colors.greenAccent, Icons.check_circle),
|
||||
ScheduleStatus.downloading => (
|
||||
@@ -67,7 +79,11 @@ const waitingHint = 'Aired in Japan; downloads automatically when a release appe
|
||||
};
|
||||
|
||||
/// What the status line means, when its text alone does not say.
|
||||
String? statusHint(ScheduleEntry e, DateTime now) => _waiting(e, now) ? waitingHint : null;
|
||||
String? statusHint(ScheduleEntry e, DateTime now) => !_waiting(e, now)
|
||||
? null
|
||||
: e.reason != null
|
||||
? '${e.reason}${e.lastSearchedAt == null ? '' : ' · searched ${_ago(e.lastSearchedAt!, now)}'}'
|
||||
: waitingHint;
|
||||
|
||||
class DayColumn extends StatelessWidget {
|
||||
final DateTime day;
|
||||
|
||||
@@ -1188,7 +1188,10 @@ panel) and chat messages (Copy message, and a link in it).
|
||||
episode (`schedule_model.dart`). AnimeFlow's `missing` (aired,
|
||||
monitored, no release grabbed yet; AnimeFlow grabs it by itself once
|
||||
one appears), and its `upcoming` past the AniList air time, read
|
||||
"waiting for release"; Request is offered only for an `unmonitored`
|
||||
"waiting for release" (with "searched N min ago" from the episode's
|
||||
`last_searched_at`, or "release rejected" with AnimeFlow's `reason`
|
||||
sentence on hover when it found releases it won't take); Request is
|
||||
offered only for an `unmonitored`
|
||||
episode (and "Request series" for a show AnimeFlow does not track).
|
||||
Air dates (AnimeFlow's `air_date`, midnight Japan time; Jellyfin's
|
||||
premiere date)
|
||||
|
||||
Reference in new issue
Block a user