Merge branch '1-add-queue' into 'main'
Add functioning queue See merge request libretunes/libretunes!11
This commit is contained in:
commit
59b11dae76
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -1311,8 +1311,10 @@ checksum = "f41f2deec9249d16ef6b1a8442fbe16013f67053797052aa0b7d2f5ebd0f0098"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"icondata_ai",
|
"icondata_ai",
|
||||||
"icondata_bs",
|
"icondata_bs",
|
||||||
|
"icondata_cg",
|
||||||
"icondata_core",
|
"icondata_core",
|
||||||
"icondata_io",
|
"icondata_io",
|
||||||
|
"icondata_ri",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1333,6 +1335,15 @@ dependencies = [
|
|||||||
"icondata_core",
|
"icondata_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icondata_cg"
|
||||||
|
version = "0.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b90cda35aa524761219a8dbd006513734e08a4cf92ee05820b01749e76435462"
|
||||||
|
dependencies = [
|
||||||
|
"icondata_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icondata_core"
|
name = "icondata_core"
|
||||||
version = "0.0.2"
|
version = "0.0.2"
|
||||||
@ -1348,6 +1359,15 @@ dependencies = [
|
|||||||
"icondata_core",
|
"icondata_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icondata_ri"
|
||||||
|
version = "0.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b1d3adc5b64b22d10ab23a7b1a005f4cb52f3d08909f578fbaa09af9f9c0b7b"
|
||||||
|
dependencies = [
|
||||||
|
"icondata_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -23,6 +23,8 @@ leptos_icons = { version = "0.1.0", default_features = false, features = [
|
|||||||
"BsPauseFill",
|
"BsPauseFill",
|
||||||
"BsSkipStartFill",
|
"BsSkipStartFill",
|
||||||
"BsSkipEndFill",
|
"BsSkipEndFill",
|
||||||
|
"RiPlayListMediaFill",
|
||||||
|
"CgTrash",
|
||||||
"IoReturnUpBackSharp",
|
"IoReturnUpBackSharp",
|
||||||
"AiEyeFilled",
|
"AiEyeFilled",
|
||||||
"AiEyeInvisibleFilled"
|
"AiEyeInvisibleFilled"
|
||||||
|
11
src/app.rs
11
src/app.rs
@ -1,3 +1,6 @@
|
|||||||
|
use crate::playbar::PlayBar;
|
||||||
|
use crate::playstatus::PlayStatus;
|
||||||
|
use crate::queue::Queue;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_meta::*;
|
use leptos_meta::*;
|
||||||
use leptos_router::*;
|
use leptos_router::*;
|
||||||
@ -34,7 +37,13 @@ pub fn App() -> impl IntoView {
|
|||||||
/// Renders the home page of your application.
|
/// Renders the home page of your application.
|
||||||
#[component]
|
#[component]
|
||||||
fn HomePage() -> impl IntoView {
|
fn HomePage() -> impl IntoView {
|
||||||
view! {}
|
let mut play_status = PlayStatus::default();
|
||||||
|
let play_status = create_rw_signal(play_status);
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<PlayBar status=play_status/>
|
||||||
|
<Queue status=play_status/>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 404 - Not Found
|
/// 404 - Not Found
|
||||||
|
@ -4,6 +4,8 @@ pub mod songdata;
|
|||||||
pub mod playstatus;
|
pub mod playstatus;
|
||||||
pub mod playbar;
|
pub mod playbar;
|
||||||
pub mod database;
|
pub mod database;
|
||||||
|
pub mod queue;
|
||||||
|
pub mod song;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod pages;
|
pub mod pages;
|
||||||
pub mod users;
|
pub mod users;
|
||||||
|
@ -6,6 +6,7 @@ use leptos::html::{Audio, Div};
|
|||||||
use leptos::leptos_dom::*;
|
use leptos::leptos_dom::*;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_icons::BsIcon::*;
|
use leptos_icons::BsIcon::*;
|
||||||
|
use leptos_icons::RiIcon::*;
|
||||||
use leptos_icons::*;
|
use leptos_icons::*;
|
||||||
|
|
||||||
/// Width and height of the forward/backward skip buttons
|
/// Width and height of the forward/backward skip buttons
|
||||||
@ -13,6 +14,9 @@ const SKIP_BTN_SIZE: &str = "3.5em";
|
|||||||
/// Width and height of the play/pause button
|
/// Width and height of the play/pause button
|
||||||
const PLAY_BTN_SIZE: &str = "5em";
|
const PLAY_BTN_SIZE: &str = "5em";
|
||||||
|
|
||||||
|
// Width and height of the queue button
|
||||||
|
const QUEUE_BTN_SIZE: &str = "3.5em";
|
||||||
|
|
||||||
/// Threshold in seconds for skipping to the previous song instead of skipping to the start of the current song
|
/// Threshold in seconds for skipping to the previous song instead of skipping to the start of the current song
|
||||||
const MIN_SKIP_BACK_TIME: f64 = 5.0;
|
const MIN_SKIP_BACK_TIME: f64 = 5.0;
|
||||||
|
|
||||||
@ -32,7 +36,7 @@ const ARROW_KEY_SKIP_TIME: f64 = 5.0;
|
|||||||
/// * `None` if the audio element is not available
|
/// * `None` if the audio element is not available
|
||||||
/// * `Some((current_time, duration))` if the audio element is available
|
/// * `Some((current_time, duration))` if the audio element is available
|
||||||
///
|
///
|
||||||
fn get_song_time_duration(status: impl SignalWithUntracked<Value = PlayStatus>) -> Option<(f64, f64)> {
|
pub fn get_song_time_duration(status: impl SignalWithUntracked<Value = PlayStatus>) -> Option<(f64, f64)> {
|
||||||
status.with_untracked(|status| {
|
status.with_untracked(|status| {
|
||||||
if let Some(audio) = status.get_audio() {
|
if let Some(audio) = status.get_audio() {
|
||||||
Some((audio.current_time(), audio.duration()))
|
Some((audio.current_time(), audio.duration()))
|
||||||
@ -53,7 +57,7 @@ fn get_song_time_duration(status: impl SignalWithUntracked<Value = PlayStatus>)
|
|||||||
/// * `status` - The `PlayStatus` to get the audio element from, as a signal
|
/// * `status` - The `PlayStatus` to get the audio element from, as a signal
|
||||||
/// * `time` - The time to skip to, in seconds
|
/// * `time` - The time to skip to, in seconds
|
||||||
///
|
///
|
||||||
fn skip_to(status: impl SignalUpdate<Value = PlayStatus>, time: f64) {
|
pub fn skip_to(status: impl SignalUpdate<Value = PlayStatus>, time: f64) {
|
||||||
if time.is_infinite() || time.is_nan() {
|
if time.is_infinite() || time.is_nan() {
|
||||||
error!("Unable to skip to non-finite time: {}", time);
|
error!("Unable to skip to non-finite time: {}", time);
|
||||||
return
|
return
|
||||||
@ -77,7 +81,7 @@ fn skip_to(status: impl SignalUpdate<Value = PlayStatus>, time: f64) {
|
|||||||
/// * `status` - The `PlayStatus` to get the audio element from, as a signal
|
/// * `status` - The `PlayStatus` to get the audio element from, as a signal
|
||||||
/// * `play` - `true` to play the song, `false` to pause it
|
/// * `play` - `true` to play the song, `false` to pause it
|
||||||
///
|
///
|
||||||
fn set_playing(status: impl SignalUpdate<Value = PlayStatus>, play: bool) {
|
pub fn set_playing(status: impl SignalUpdate<Value = PlayStatus>, play: bool) {
|
||||||
status.update(|status| {
|
status.update(|status| {
|
||||||
if let Some(audio) = status.get_audio() {
|
if let Some(audio) = status.get_audio() {
|
||||||
if play {
|
if play {
|
||||||
@ -101,6 +105,14 @@ fn set_playing(status: impl SignalUpdate<Value = PlayStatus>, play: bool) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn toggle_queue(status: impl SignalUpdate<Value = PlayStatus>) {
|
||||||
|
status.update(|status| {
|
||||||
|
status.queue_open = !status.queue_open;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// Set the source of the audio player
|
/// Set the source of the audio player
|
||||||
///
|
///
|
||||||
/// Logs an error if the audio element is not available
|
/// Logs an error if the audio element is not available
|
||||||
@ -309,6 +321,30 @@ fn ProgressBar(percentage: MaybeSignal<f64>, status: RwSignal<PlayStatus>) -> im
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn QueueToggle(status: RwSignal<PlayStatus>) -> impl IntoView {
|
||||||
|
|
||||||
|
let update_queue = move |_| {
|
||||||
|
toggle_queue(status);
|
||||||
|
log!("queue button pressed, queue status: {:?}", status.with_untracked(|status| status.queue_open));
|
||||||
|
};
|
||||||
|
|
||||||
|
// We use this to prevent the buttons from being focused when clicked
|
||||||
|
// If buttons were focused on clicks, then pressing space bar to play/pause would "click" the button
|
||||||
|
// and trigger unwanted behavior
|
||||||
|
let prevent_focus = move |e: MouseEvent| {
|
||||||
|
e.prevent_default();
|
||||||
|
};
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<div class="queue-toggle">
|
||||||
|
<button on:click=update_queue on:mousedown=prevent_focus>
|
||||||
|
<Icon class="controlbtn" width=QUEUE_BTN_SIZE height=QUEUE_BTN_SIZE icon=Icon::from(RiPlayListMediaFill) />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The main play bar component, containing the progress bar, media info, play controls, and play duration
|
/// The main play bar component, containing the progress bar, media info, play controls, and play duration
|
||||||
#[component]
|
#[component]
|
||||||
pub fn PlayBar(status: RwSignal<PlayStatus>) -> impl IntoView {
|
pub fn PlayBar(status: RwSignal<PlayStatus>) -> impl IntoView {
|
||||||
@ -457,6 +493,7 @@ pub fn PlayBar(status: RwSignal<PlayStatus>) -> impl IntoView {
|
|||||||
<MediaInfo status=status />
|
<MediaInfo status=status />
|
||||||
<PlayControls status=status />
|
<PlayControls status=status />
|
||||||
<PlayDuration elapsed_secs=elapsed_secs.into() total_secs=total_secs.into() />
|
<PlayDuration elapsed_secs=elapsed_secs.into() total_secs=total_secs.into() />
|
||||||
|
<QueueToggle status=status />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ use crate::songdata::SongData;
|
|||||||
pub struct PlayStatus {
|
pub struct PlayStatus {
|
||||||
/// Whether or not the audio player is currently playing
|
/// Whether or not the audio player is currently playing
|
||||||
pub playing: bool,
|
pub playing: bool,
|
||||||
|
/// Whether or not the queue is open
|
||||||
|
pub queue_open: bool,
|
||||||
/// A reference to the HTML audio element
|
/// A reference to the HTML audio element
|
||||||
pub audio_player: Option<NodeRef<Audio>>,
|
pub audio_player: Option<NodeRef<Audio>>,
|
||||||
/// A queue of songs that have been played, ordered from oldest to newest
|
/// A queue of songs that have been played, ordered from oldest to newest
|
||||||
@ -53,6 +55,7 @@ impl Default for PlayStatus {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
playing: false,
|
playing: false,
|
||||||
|
queue_open: false,
|
||||||
audio_player: None,
|
audio_player: None,
|
||||||
history: VecDeque::new(),
|
history: VecDeque::new(),
|
||||||
queue: VecDeque::new(),
|
queue: VecDeque::new(),
|
||||||
|
121
src/queue.rs
Normal file
121
src/queue.rs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
use crate::playstatus::PlayStatus;
|
||||||
|
use crate::song::Song;
|
||||||
|
use leptos::ev::MouseEvent;
|
||||||
|
use leptos::leptos_dom::*;
|
||||||
|
use leptos::*;
|
||||||
|
use leptos_icons::*;
|
||||||
|
use leptos_icons::CgIcon::*;
|
||||||
|
use leptos::ev::DragEvent;
|
||||||
|
|
||||||
|
const RM_BTN_SIZE: &str = "2.5rem";
|
||||||
|
|
||||||
|
fn remove_song_fn(index: usize, status: RwSignal<PlayStatus>) {
|
||||||
|
if index == 0 {
|
||||||
|
log!("Error: Trying to remove currently playing song (index 0) from queue");
|
||||||
|
} else {
|
||||||
|
log!("Remove Song from Queue: Song is not currently playing, deleting song from queue and not adding to history");
|
||||||
|
status.update(|status| {
|
||||||
|
status.queue.remove(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Queue(status: RwSignal<PlayStatus>) -> impl IntoView {
|
||||||
|
|
||||||
|
let remove_song = move |index: usize| {
|
||||||
|
remove_song_fn(index, status);
|
||||||
|
log!("Removed song {}", index + 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
let prevent_focus = move |e: MouseEvent| {
|
||||||
|
e.prevent_default();
|
||||||
|
};
|
||||||
|
|
||||||
|
let index_being_dragged = create_rw_signal(-1);
|
||||||
|
|
||||||
|
let index_being_hovered = create_rw_signal(-1);
|
||||||
|
|
||||||
|
let on_drag_start = move |_e: DragEvent, index: usize| {
|
||||||
|
// set the index of the item being dragged
|
||||||
|
index_being_dragged.set(index as i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
let on_drop = move |e: DragEvent| {
|
||||||
|
e.prevent_default();
|
||||||
|
// if the index of the item being dragged is not the same as the index of the item being hovered over
|
||||||
|
if index_being_dragged.get() != index_being_hovered.get() && index_being_dragged.get() > 0 && index_being_hovered.get() > 0 {
|
||||||
|
// get the index of the item being dragged
|
||||||
|
let dragged_index = index_being_dragged.get_untracked() as usize;
|
||||||
|
// get the index of the item being hovered over
|
||||||
|
let hovered_index = index_being_hovered.get_untracked() as usize;
|
||||||
|
// update the queue
|
||||||
|
status.update(|status| {
|
||||||
|
// remove the dragged item from the list
|
||||||
|
let dragged_item = status.queue.remove(dragged_index);
|
||||||
|
// insert the dragged item at the index of the item being hovered over
|
||||||
|
status.queue.insert(hovered_index, dragged_item.unwrap());
|
||||||
|
});
|
||||||
|
// reset the index of the item being dragged
|
||||||
|
index_being_dragged.set(-1);
|
||||||
|
// reset the index of the item being hovered over
|
||||||
|
index_being_hovered.set(-1);
|
||||||
|
log!("drag end. Moved item from index {} to index {}", dragged_index, hovered_index);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// reset the index of the item being dragged
|
||||||
|
index_being_dragged.set(-1);
|
||||||
|
// reset the index of the item being hovered over
|
||||||
|
index_being_hovered.set(-1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let on_drag_enter = move |_e: DragEvent, index: usize| {
|
||||||
|
// set the index of the item being hovered over
|
||||||
|
index_being_hovered.set(index as i32);
|
||||||
|
};
|
||||||
|
|
||||||
|
let on_drag_over = move |e: DragEvent| {
|
||||||
|
e.prevent_default();
|
||||||
|
};
|
||||||
|
|
||||||
|
view!{
|
||||||
|
<Show
|
||||||
|
when=move || status.with(|status| status.queue_open)
|
||||||
|
fallback=|| view!{""}>
|
||||||
|
<div class="queue">
|
||||||
|
<div class="queue-header">
|
||||||
|
<h2>Queue</h2>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
{
|
||||||
|
move || status.with(|status| status.queue.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(index, song)| view! {
|
||||||
|
<div class="queue-item"
|
||||||
|
draggable="true"
|
||||||
|
on:dragstart=move |e: DragEvent| on_drag_start(e, index)
|
||||||
|
on:drop=on_drop
|
||||||
|
on:dragenter=move |e: DragEvent| on_drag_enter(e, index)
|
||||||
|
on:dragover=on_drag_over
|
||||||
|
>
|
||||||
|
<Song song_image_path=song.image_path.clone() song_title=song.name.clone() song_artist=song.artist.clone() />
|
||||||
|
<Show
|
||||||
|
when=move || index != 0
|
||||||
|
fallback=|| view!{
|
||||||
|
<p>Playing</p>
|
||||||
|
}>
|
||||||
|
<button on:click=move |_| remove_song(index) on:mousedown=prevent_focus>
|
||||||
|
<Icon class="remove-song" width=RM_BTN_SIZE height=RM_BTN_SIZE icon=Icon::from(CgTrash) />
|
||||||
|
</button>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>())
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
14
src/song.rs
Normal file
14
src/song.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use leptos::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Song(song_image_path: String, song_title: String, song_artist: String) -> impl IntoView {
|
||||||
|
view!{
|
||||||
|
<div class="queue-song">
|
||||||
|
<img src={song_image_path} alt={song_title.clone()} />
|
||||||
|
<div class="queue-song-info">
|
||||||
|
<h3>{song_title}</h3>
|
||||||
|
<p>{song_artist}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/// Holds information about a song
|
/// Holds information about a song
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct SongData {
|
pub struct SongData {
|
||||||
/// Song name
|
/// Song name
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
@import 'playbar.scss';
|
@import 'playbar.scss';
|
||||||
@import 'theme.scss';
|
@import 'theme.scss';
|
||||||
|
@import 'queue.scss';
|
||||||
@import 'login.scss';
|
@import 'login.scss';
|
||||||
@import 'signup.scss';
|
@import 'signup.scss';
|
||||||
|
|
||||||
|
@ -88,4 +88,28 @@
|
|||||||
right: 10px;
|
right: 10px;
|
||||||
top: 13px;
|
top: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.queue-toggle {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 13px;
|
||||||
|
top: 13px;
|
||||||
|
right: 90px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
.controlbtn {
|
||||||
|
color: $text-controls-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controlbtn:hover {
|
||||||
|
color: $controls-hover-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controlbtn:active {
|
||||||
|
color: $controls-click-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
background-color: transparent;
|
||||||
|
border: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
76
style/queue.scss
Normal file
76
style/queue.scss
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
@import 'theme.scss';
|
||||||
|
|
||||||
|
.queue {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 400px;
|
||||||
|
height: calc(100% - 78.9px); /* Adjust height to fit the queue */
|
||||||
|
background-color: #424242; /* Queue background color */
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
|
overflow-y: auto; /* Add scroll bar when queue is too long */
|
||||||
|
|
||||||
|
.queue-header {
|
||||||
|
background-color: #333; /* Header background color */
|
||||||
|
color: #fff; /* Header text color */
|
||||||
|
padding: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.queue-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
|
||||||
|
.queue-song {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid #ccc; /* Separator line color */
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 50px; /* Adjust maximum width for images */
|
||||||
|
margin-right: 10px; /* Add spacing between image and text */
|
||||||
|
border-radius: 5px; /* Add border radius to image */
|
||||||
|
}
|
||||||
|
|
||||||
|
.queue-song-info {
|
||||||
|
h3 {
|
||||||
|
margin: 0; /* Remove default margin for heading */
|
||||||
|
color: #fff; /* Adjust text color for song */
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0; /* Remove default margin for paragraph */
|
||||||
|
color: #aaa; /* Adjust text color for artist */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left: auto;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ $controls-click-color: #909090;
|
|||||||
$play-bar-background-color: #212121;
|
$play-bar-background-color: #212121;
|
||||||
$play-grad-start: #0a0533;
|
$play-grad-start: #0a0533;
|
||||||
$play-grad-end: $accent-color;
|
$play-grad-end: $accent-color;
|
||||||
|
$queue-background-color: $play-bar-background-color;
|
||||||
|
|
||||||
$auth-inputs: #796dd4;
|
$auth-inputs: #796dd4;
|
||||||
$auth-containers: white;
|
$auth-containers: white;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user