diff --git a/src/player.rs b/src/player.rs index 0ebf4ba..c099dc1 100644 --- a/src/player.rs +++ b/src/player.rs @@ -299,7 +299,7 @@ impl Player { // only want to autoplay if there hasn't been any manual intervention. // // In other words, this will be `true` after a new track has been fully - // loaded and it'll be `false` if a track is still currently loading. + // loaded and it'll be `false` if a track is still currently loading. let mut new = false; loop { @@ -326,6 +326,8 @@ impl Player { match msg { Messages::Next | Messages::Init | Messages::TryAgain => { + player.bookmarked.swap(false, Ordering::Relaxed); + // We manually skipped, so we shouldn't actually wait for the song // to be over until we recieve the `NewSong` signal. new = false; @@ -394,15 +396,10 @@ impl Player { continue; } Messages::Bookmark => { - if player.bookmarked.load(Ordering::Relaxed) { - continue; - } - - player.bookmarked.swap(true, Ordering::Relaxed); let current = player.current.load(); let current = current.as_ref().unwrap(); - bookmark::bookmark( + let bookmarked = bookmark::bookmark( current.full_path.clone(), if current.custom_name { Some(current.display_name.clone()) @@ -411,6 +408,8 @@ impl Player { }, ) .await?; + + player.bookmarked.swap(bookmarked, Ordering::Relaxed); } Messages::Quit => break, } diff --git a/src/tracks/bookmark.rs b/src/tracks/bookmark.rs index a5964fb..d8d91cd 100644 --- a/src/tracks/bookmark.rs +++ b/src/tracks/bookmark.rs @@ -1,11 +1,13 @@ use tokio::fs::{create_dir_all, OpenOptions}; -use tokio::io::AsyncWriteExt; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; use crate::data_dir; -pub async fn bookmark(path: String, custom: Option) -> eyre::Result<()> { - let mut entry = format!("\n{path}"); - +/// Bookmarks a given track with a full path and optional custom name. +/// +/// Returns whether the track is now bookmarked, or not. +pub async fn bookmark(path: String, custom: Option) -> eyre::Result { + let mut entry = format!("{path}"); if let Some(custom) = custom { entry.push('!'); entry.push_str(&custom); @@ -17,11 +19,25 @@ pub async fn bookmark(path: String, custom: Option) -> eyre::Result<()> let mut file = OpenOptions::new() .create(true) .write(true) - .append(true) + .read(true) + .append(false) .open(data_dir.join("bookmarks.txt")) .await?; - file.write_all(entry.as_bytes()).await?; + let mut text = String::new(); + file.read_to_string(&mut text).await?; - Ok(()) + let mut lines: Vec<&str> = text.lines().collect(); + let previous_len = lines.len(); + lines.retain(|line| (*line != entry)); + let contains = lines.len() != previous_len; + + if !contains { + lines.push(&entry); + } + + file.set_len(0).await?; + file.write_all(format!("\n{}\n", lines.join("\n")).as_bytes()).await?; + + Ok(!contains) }