use crate::dots_menu::{DotsMenu, MenuAction};
use crate::metadata_modal::MetadataModal;
use crate::playlist_modal::PlaylistModal;
use dioxus::prelude::*;
use hooks::db_reactivity::Table;
use hooks::use_player_controller::PlayerController;
use reader::Track;
use server::source::PlaylistOps;
#[component]
pub(crate) fn TrackActions(track: Track) -> Element {
let mut ctrl = use_context::<PlayerController>();
let active_source = use_context::<Signal<::server::source::ActiveSource>>();
let generations = hooks::db_reactivity::use_generations();
let mut is_open = use_signal(|| false);
let mut show_playlist_modal = use_signal(|| false);
let mut show_metadata = use_signal(|| false);
let capabilities = active_source.read().capabilities();
let mut actions = vec![
MenuAction::new(i18n::t("play_next").to_string(), "fa-solid fa-forward-step"),
MenuAction::new(i18n::t("add_to_queue").to_string(), "fa-solid fa-list-ul"),
];
let play_next_idx = 0;
let add_to_queue_idx = 1;
let playlist_idx = if capabilities.playlists != PlaylistOps::None {
let idx = actions.len();
actions.push(MenuAction::new(
i18n::t("add_to_playlist").to_string(),
"fa-solid fa-plus",
));
Some(idx)
} else {
None
};
let share_idx = actions.len();
actions.push(MenuAction::new(
i18n::t("share_musicbrainz").to_string(),
"fa-solid fa-share-nodes",
));
let radio_idx = if capabilities.radio {
let idx = actions.len();
actions.push(MenuAction::new(
"Start radio",
"fa-solid fa-tower-broadcast",
));
Some(idx)
} else {
None
};
let metadata_idx = actions.len();
actions.push(MenuAction::new(
i18n::t("view_metadata").to_string(),
"fa-solid fa-circle-info",
));
rsx! {
DotsMenu {
actions,
is_open: is_open(),
on_open: move |_| is_open.set(true),
on_close: move |_| is_open.set(false),
button_class: "w-11 h-11 bg-white/10 text-white/70 hover:bg-white/15 hover:text-white active:scale-95".to_string(),
anchor: "right".to_string(),
placement: "top".to_string(),
icon: "fa-solid fa-ellipsis".to_string(),
on_action: {
let action_track = track.clone();
move |idx: usize| {
is_open.set(false);
if idx == play_next_idx {
ctrl.queue_play_next(vec![action_track.clone()]);
} else if idx == add_to_queue_idx {
ctrl.add_to_queue(vec![action_track.clone()]);
} else if playlist_idx == Some(idx) {
show_playlist_modal.set(true);
} else if idx == share_idx {
let source = active_source.peek().clone();
crate::track_row::share_track(action_track.clone(), source);
} else if radio_idx == Some(idx) {
let source = active_source.peek().clone();
crate::track_row::play_radio(action_track.clone(), source, ctrl);
} else if idx == metadata_idx {
show_metadata.set(true);
}
}
},
}
if *show_playlist_modal.read() {
PlaylistModal {
overlay_class: Some("overlay".to_string()),
on_close: move |_| show_playlist_modal.set(false),
on_add_to_playlist: {
let playlist_track = track.clone();
move |playlist_id: String| {
let item_ref = playlist_track.id.key().into_owned();
let source = active_source.peek().clone();
spawn(async move {
match source.add_to_playlist(&playlist_id, &[item_ref]).await {
Ok(_) => generations.bump(Table::Playlists),
Err(error) => tracing::warn!(%error, "failed to add fullscreen track to playlist"),
}
});
show_playlist_modal.set(false);
}
},
on_create_playlist: {
let playlist_track = track.clone();
move |name: String| {
let item_ref = playlist_track.id.key().into_owned();
let source = active_source.peek().clone();
spawn(async move {
match source.create_playlist(&name, &[item_ref]).await {
Ok(_) => generations.bump(Table::Playlists),
Err(error) => tracing::warn!(%error, "failed to create playlist from fullscreen track"),
}
});
show_playlist_modal.set(false);
}
},
}
}
if *show_metadata.read() {
MetadataModal {
track: track.clone(),
on_close: move |_| show_metadata.set(false),
}
}
}
}