about summary refs log tree commit diff stats
path: root/crates/yt/src/commands/select/implm/standalone/mod.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-18 18:01:29 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-18 18:01:29 +0200
commitc4524db090d2d31af8bc3e7ec64c1ea9f5ec72aa (patch)
treef80cefb7b315155e4cca0bb4b78e5e6cd5418ab5 /crates/yt/src/commands/select/implm/standalone/mod.rs
parenttest(crates/yt): Add basic integration tests (diff)
downloadyt-c4524db090d2d31af8bc3e7ec64c1ea9f5ec72aa.zip
feat(crates/yt): Separate all commands from their implementation code
This also comes with a re-worked and tested implementation of the
comments rendering code.
Diffstat (limited to 'crates/yt/src/commands/select/implm/standalone/mod.rs')
-rw-r--r--crates/yt/src/commands/select/implm/standalone/mod.rs122
1 files changed, 122 insertions, 0 deletions
diff --git a/crates/yt/src/commands/select/implm/standalone/mod.rs b/crates/yt/src/commands/select/implm/standalone/mod.rs
new file mode 100644
index 0000000..dd6de45
--- /dev/null
+++ b/crates/yt/src/commands/select/implm/standalone/mod.rs
@@ -0,0 +1,122 @@
+use std::io::{Write, stderr};
+
+use crate::{
+    ansi_escape_codes,
+    app::App,
+    commands::select::{SelectCommand, SharedSelectionCommandArgs},
+    storage::db::{
+        insert::{Operations, video::Operation},
+        video::{Priority, Video, VideoStatus},
+    },
+};
+
+use anyhow::{Context, Result, bail};
+
+pub(super) mod add;
+
+pub(crate) async fn handle_select_cmd(
+    app: &App,
+    cmd: SelectCommand,
+    video: &mut Video,
+    line_number: Option<i64>,
+    ops: &mut Operations<Operation>,
+) -> Result<()> {
+    let status = match cmd {
+        SelectCommand::Pick { shared } => Some((VideoStatus::Pick, shared)),
+        SelectCommand::Drop { shared } => Some((VideoStatus::Drop, shared)),
+        SelectCommand::Watched { shared } => Some((VideoStatus::Watched, shared)),
+        SelectCommand::Watch { shared } => {
+            if let VideoStatus::Cached {
+                cache_path,
+                is_focused,
+            } = &video.status
+            {
+                Some((
+                    VideoStatus::Cached {
+                        cache_path: cache_path.to_owned(),
+                        is_focused: *is_focused,
+                    },
+                    shared,
+                ))
+            } else {
+                Some((VideoStatus::Watch, shared))
+            }
+        }
+        SelectCommand::Url { shared } => {
+            let Some(url) = shared.url else {
+                bail!("You need to provide a url to `select url ..`")
+            };
+
+            let mut firefox = std::process::Command::new("firefox");
+            firefox.args(["-P", "timesinks.youtube"]);
+            firefox.arg(url.as_str());
+            let _handle = firefox.spawn().context("Failed to run firefox")?;
+            None
+        }
+        SelectCommand::File { .. } | SelectCommand::Split { .. } | SelectCommand::Add { .. } => {
+            unreachable!("These should have been filtered out")
+        }
+    };
+
+    if let Some((status, shared)) = status {
+        handle_status_change(
+            app,
+            video,
+            shared,
+            line_number,
+            status,
+            line_number.is_none(),
+            ops,
+        )
+        .await?;
+    }
+
+    Ok(())
+}
+
+async fn handle_status_change(
+    app: &App,
+    video: &mut Video,
+    shared: SharedSelectionCommandArgs,
+    line_number: Option<i64>,
+    new_status: VideoStatus,
+    is_single: bool,
+    ops: &mut Operations<Operation>,
+) -> Result<()> {
+    let priority = compute_priority(line_number, shared.priority);
+
+    video.set_status(new_status, ops);
+    if let Some(priority) = priority {
+        video.set_priority(priority, ops);
+    }
+
+    if let Some(subtitle_langs) = shared.subtitle_langs {
+        video.set_subtitle_langs(subtitle_langs, ops);
+    }
+    if let Some(playback_speed) = shared.playback_speed {
+        video.set_playback_speed(playback_speed, ops);
+    }
+
+    if !is_single {
+        ansi_escape_codes::clear_whole_line();
+        ansi_escape_codes::move_to_col(1);
+    }
+
+    eprint!("{}", &video.to_line_display(app, None).await?);
+
+    if is_single {
+        eprintln!();
+    } else {
+        stderr().flush()?;
+    }
+
+    Ok(())
+}
+
+fn compute_priority(line_number: Option<i64>, priority: Option<i64>) -> Option<Priority> {
+    if let Some(pri) = priority {
+        Some(Priority::from(pri))
+    } else {
+        line_number.map(Priority::from)
+    }
+}