mirror of
https://github.com/narrrl/proton-stream.git
synced 2026-11-03 16:41:26 +01:00
feat(core,app,android,ios): keep a show in Continue watching after an episode ends
Continue watching listed only part-watched episodes, so finishing one -
the most ordinary moment to want the next - dropped the show from the
shelf. Title::continue_with now reads the episode touched last: a
part-watched one is resumed, a finished one offers the episode after it
("Next: S01E04"), and one reset to the start (what leaving the shelf
does) keeps the title off. A few seconds of an episode are passed over.
The phones computed their own shelf from episode records. The bridge now
exports the engine's choice as TitleRecord.continue_index, and Play on a
title lands there on every client.
Undo on the phones re-saved a watch state with a fresh time, which both
reordered the shelf and could not express "never played". A new
restore_watch_state puts the state back as it was read.
This commit is contained in:
1 parent
c6b0457c4d
commit
a306d02cf1
15 files changed
+225
-68
No files matched your search
@@ -1312,9 +1312,18 @@ impl App {
|
||||
})?;
|
||||
Some((title.name.clone(), episode.watch))
|
||||
});
|
||||
let Some((name, Some(before))) = found else {
|
||||
let Some((name, before)) = found else {
|
||||
return;
|
||||
};
|
||||
// An episode Continue watching offers next has never been played.
|
||||
// Its undo is a reset as old as time, which the finished episode
|
||||
// before it outranks.
|
||||
let before = before.unwrap_or(pstr_core::catalog::WatchState {
|
||||
position_secs: 0.0,
|
||||
duration_secs: None,
|
||||
watched: false,
|
||||
updated_at: 0,
|
||||
});
|
||||
self.engine.save_watch_state(
|
||||
share_id.clone(),
|
||||
link_id.clone(),
|
||||
|
||||
@@ -382,7 +382,7 @@ fn tile_shape(tiles: Tiles) -> (f32, f32) {
|
||||
}
|
||||
}
|
||||
|
||||
/// The top shelf: one card per part-watched title, scrolling sideways.
|
||||
/// The top shelf: one card per title in progress, scrolling sideways.
|
||||
fn continue_row(
|
||||
ui: &mut egui::Ui,
|
||||
art: &mut Art<'_>,
|
||||
@@ -395,21 +395,17 @@ fn continue_row(
|
||||
.show(ui, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
for title in titles {
|
||||
let Some(episode) = title.resume() else {
|
||||
let Some(episode) = title.continue_with() else {
|
||||
continue;
|
||||
};
|
||||
let remaining = episode
|
||||
.watch
|
||||
.and_then(|watch| watch.duration_secs)
|
||||
.map(|duration| {
|
||||
format!(
|
||||
"{} left",
|
||||
ui::format_time(
|
||||
duration - episode.watch.map_or(0.0, |w| w.position_secs)
|
||||
)
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| episode.label());
|
||||
let remaining = match episode.resume_at() {
|
||||
Some(at) => episode
|
||||
.watch
|
||||
.and_then(|watch| watch.duration_secs)
|
||||
.map(|duration| format!("{} left", ui::format_time(duration - at)))
|
||||
.unwrap_or_else(|| episode.label()),
|
||||
None => format!("Next: {}", episode.label()),
|
||||
};
|
||||
|
||||
let picture = art.of(title);
|
||||
let response = ui::card(
|
||||
@@ -550,7 +546,7 @@ fn tile_menu(
|
||||
});
|
||||
}
|
||||
if continuing
|
||||
&& let Some(episode) = title.resume()
|
||||
&& let Some(episode) = title.continue_with()
|
||||
&& ui
|
||||
.button("Remove from Continue watching")
|
||||
.on_hover_text("Forget where you stopped in it")
|
||||
|
||||
Reference in new issue
Block a user