Implement download status for films
This commit is contained in:
parent
6ca3ab6a50
commit
b8cb3b1673
5 changed files with 95 additions and 4 deletions
|
|
@ -72,6 +72,15 @@ impl DataManager {
|
|||
.set_film_watched_status(uuid, watched)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn set_film_downloaded_status(
|
||||
uuid: &str,
|
||||
downloaded: bool,
|
||||
) -> Result<(), DataManagerError> {
|
||||
sqlite_manager!()
|
||||
.set_film_downloaded_status(uuid, downloaded)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,10 +30,13 @@ impl SqliteManager {
|
|||
connection
|
||||
.prepare(
|
||||
"
|
||||
select films.uuid, films.name, films.original_name, films.release_date, films.runtime_minutes,
|
||||
coalesce(watched_media.watched, 0) as watched
|
||||
from films left join watched_media
|
||||
on films.uuid is watched_media.media_uuid
|
||||
select films.uuid, films.name, films.original_name, films.release_date,
|
||||
films.runtime_minutes,
|
||||
coalesce(watched_media.watched, 0) as watched,
|
||||
coalesce(downloaded_media.downloaded, 0) as downloaded
|
||||
from films
|
||||
left join watched_media on films.uuid is watched_media.media_uuid
|
||||
left join downloaded_media on films.uuid is downloaded_media.media_uuid
|
||||
",
|
||||
)?
|
||||
.query(())?
|
||||
|
|
@ -92,6 +95,32 @@ impl SqliteManager {
|
|||
.await
|
||||
.map_err(convert_error)
|
||||
}
|
||||
|
||||
pub async fn set_film_downloaded_status(
|
||||
&self,
|
||||
uuid: &str,
|
||||
downloaded: bool,
|
||||
) -> Result<(), DataManagerError> {
|
||||
self
|
||||
.client
|
||||
.conn({
|
||||
let uuid = uuid.to_string();
|
||||
move |connection| {
|
||||
connection.execute(
|
||||
"
|
||||
insert into downloaded_media (media_uuid, downloaded)
|
||||
values (:uuid, :downloaded)
|
||||
on conflict (media_uuid) do
|
||||
update set downloaded = :downloaded
|
||||
",
|
||||
named_params! { ":uuid": uuid, ":downloaded": downloaded },
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.await
|
||||
.map_err(convert_error)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for SqliteManager {
|
||||
|
|
@ -141,6 +170,7 @@ fn row_to_film_overview(row: &Row) -> rusqlite::Result<FilmOverview> {
|
|||
let release_date = row.get("release_date")?;
|
||||
let runtime = row.get("runtime_minutes")?;
|
||||
let watched = row.get("watched")?;
|
||||
let downloaded = row.get("downloaded")?;
|
||||
|
||||
Ok(FilmOverview {
|
||||
uuid,
|
||||
|
|
@ -149,6 +179,7 @@ fn row_to_film_overview(row: &Row) -> rusqlite::Result<FilmOverview> {
|
|||
release_date,
|
||||
runtime,
|
||||
watched,
|
||||
downloaded,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,17 +16,21 @@ pub struct FilmDetails {
|
|||
#[derive(Debug)]
|
||||
pub enum FilmDetailsInput {
|
||||
ToggleWatchedStatus,
|
||||
ToggleDownloadedStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FilmDetailsOutput {
|
||||
WatchedStatusChanged(bool),
|
||||
DownloadedStatusChanged(bool),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FilmDetailsCmdOutput {
|
||||
WatchedStatusPersistSucceeded,
|
||||
WatchedStatusPersistFailed(DataManagerError),
|
||||
DownloadedStatusPersistSucceeded,
|
||||
DownloadedStatusPersistFailed(DataManagerError),
|
||||
}
|
||||
|
||||
#[component(pub)]
|
||||
|
|
@ -54,13 +58,23 @@ impl Component for FilmDetails {
|
|||
},
|
||||
|
||||
gtk4::Box {
|
||||
set_orientation: Orientation::Horizontal,
|
||||
set_align: Align::Center,
|
||||
set_spacing: 20,
|
||||
|
||||
ToggleButton {
|
||||
#[watch]
|
||||
set_label: if model.film_overview.watched { "Watched" } else { "Watch" },
|
||||
set_active: model.film_overview.watched,
|
||||
connect_toggled => FilmDetailsInput::ToggleWatchedStatus,
|
||||
},
|
||||
|
||||
ToggleButton {
|
||||
#[watch]
|
||||
set_label: if model.film_overview.downloaded { "Downloaded" } else { "Mark downloaded" },
|
||||
set_active: model.film_overview.downloaded,
|
||||
connect_toggled => FilmDetailsInput::ToggleDownloadedStatus,
|
||||
},
|
||||
},
|
||||
|
||||
gtk4::Box {
|
||||
|
|
@ -111,6 +125,23 @@ impl Component for FilmDetails {
|
|||
}
|
||||
));
|
||||
}
|
||||
FilmDetailsInput::ToggleDownloadedStatus => {
|
||||
let downloaded = !self.film_overview.downloaded;
|
||||
self.film_overview.downloaded = downloaded;
|
||||
sender.emit_output(FilmDetailsOutput::DownloadedStatusChanged(downloaded));
|
||||
|
||||
sender.oneshot_command(clone!(
|
||||
#[strong(rename_to = uuid)]
|
||||
self.film_overview.uuid,
|
||||
async move {
|
||||
let result = DataManager::set_film_downloaded_status(uuid.as_str(), downloaded).await;
|
||||
match result {
|
||||
Ok(()) => FilmDetailsCmdOutput::DownloadedStatusPersistSucceeded,
|
||||
Err(error) => FilmDetailsCmdOutput::DownloadedStatusPersistFailed(error),
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,6 +156,10 @@ impl Component for FilmDetails {
|
|||
FilmDetailsCmdOutput::WatchedStatusPersistFailed(error) => {
|
||||
println!("Watched status persist failed: {error:?}");
|
||||
}
|
||||
FilmDetailsCmdOutput::DownloadedStatusPersistSucceeded => {}
|
||||
FilmDetailsCmdOutput::DownloadedStatusPersistFailed(error) => {
|
||||
println!("Downloaded status persist failed: {error:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ pub enum FilmGridItemInput {
|
|||
ItemClicked,
|
||||
DetailsClosed,
|
||||
WatchedStatusChanged(bool),
|
||||
DownloadedStatusChanged(bool),
|
||||
SetVisible(bool),
|
||||
}
|
||||
|
||||
|
|
@ -127,6 +128,13 @@ impl FactoryComponent for FilmGridItem {
|
|||
set_visible: self.film.watched,
|
||||
set_icon_name: Some("eye-outline-filled-symbolic"),
|
||||
},
|
||||
|
||||
#[name="downloaded"]
|
||||
Image {
|
||||
#[watch]
|
||||
set_visible: self.film.downloaded,
|
||||
set_icon_name: Some("folder-download-symbolic"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -178,6 +186,7 @@ impl FactoryComponent for FilmGridItem {
|
|||
FilmGridItemInput::ItemClicked => {
|
||||
let details_controller = FilmDetails::builder()
|
||||
.launch(self.film.clone())
|
||||
// TODO: Replace this with Connector::forward.
|
||||
.connect_receiver(clone!(
|
||||
#[strong]
|
||||
sender,
|
||||
|
|
@ -185,6 +194,9 @@ impl FactoryComponent for FilmGridItem {
|
|||
FilmDetailsOutput::WatchedStatusChanged(watched) => {
|
||||
sender.input(FilmGridItemInput::WatchedStatusChanged(watched));
|
||||
}
|
||||
FilmDetailsOutput::DownloadedStatusChanged(downloaded) => {
|
||||
sender.input(FilmGridItemInput::DownloadedStatusChanged(downloaded));
|
||||
}
|
||||
}
|
||||
));
|
||||
self.details = Some(details_controller);
|
||||
|
|
@ -195,6 +207,9 @@ impl FactoryComponent for FilmGridItem {
|
|||
FilmGridItemInput::WatchedStatusChanged(watched) => {
|
||||
self.film.watched = watched;
|
||||
}
|
||||
FilmGridItemInput::DownloadedStatusChanged(downloaded) => {
|
||||
self.film.downloaded = downloaded;
|
||||
}
|
||||
FilmGridItemInput::SetVisible(visible) => {
|
||||
self.visible = visible;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ pub struct FilmOverview {
|
|||
// In minutes.
|
||||
pub runtime: u32,
|
||||
pub watched: bool,
|
||||
pub downloaded: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue