Skip to content

Commit

Permalink
Merge branch 'jpochyla:master' into feature/rework-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
SO9010 authored Jun 19, 2024
2 parents d7e89ed + 913dae1 commit 9d9acb1
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 40 deletions.
41 changes: 25 additions & 16 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [ master ]
branches: [master]
pull_request:
branches: [ master ]
branches: [master]

env:
CARGO_TERM_COLOR: always
Expand All @@ -20,7 +20,7 @@ jobs:
uses: Swatinem/rust-cache@v2

- name: Install Linux Dependencies
if: ${{ runner.os == 'Linux' }}
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libgtk-3-dev libssl-dev libasound2-dev

- name: Check Formatting
Expand All @@ -40,7 +40,7 @@ jobs:
uses: Swatinem/rust-cache@v2

- name: Install Linux Dependencies
if: ${{ runner.os == 'Linux' }}
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libgtk-3-dev libssl-dev libasound2-dev

- name: Run Tests
Expand All @@ -49,51 +49,60 @@ jobs:

- name: Build Release
run: cargo build --release


- name: Build x86_64 for MacOS
if: runner.os == 'macOS'
run: |
rustup target add x86_64-apple-darwin
cargo build --release --target x86_64-apple-darwin
- name: Build aarch64 for MacOS
if: ${{ runner.os == 'macOS' }}
if: runner.os == 'macOS'
run: |
rustup target add aarch64-apple-darwin
cargo build --release --target aarch64-apple-darwin
- name: Bundle macOS Release
if: ${{ runner.os == 'macOS' }}
if: runner.os == 'macOS'
run: |
cargo install cargo-bundle
cargo bundle --release
working-directory: psst-gui

- name: Create macOS universal binary
if: ${{ runner.os == 'macOS' }}
run: lipo target/release/psst-gui target/aarch64-apple-darwin/release/psst-gui -create -output target/release/bundle/osx/Psst.app/Contents/MacOS/psst-gui
if: runner.os == 'macOS'
run: |
lipo -create -output target/release/bundle/osx/Psst.app/Contents/MacOS/psst-gui \
target/x86_64-apple-darwin/release/psst-gui \
target/aarch64-apple-darwin/release/psst-gui
- name: Create macOS Disk Image
if: ${{ runner.os == 'macOS' }}
if: runner.os == 'macOS'
run: |
hdiutil create Psst-uncompressed.dmg -volname "Psst" -srcfolder target/release/bundle/osx
hdiutil convert Psst-uncompressed.dmg -format UDZO -o Psst.dmg
- name: Make Linux Binary Executable
if: ${{ runner.os == 'Linux' }}
if: runner.os == 'Linux'
run: chmod +x target/release/psst-gui

- name: Upload Linux Binary
uses: actions/upload-artifact@v3
if: ${{ runner.os == 'Linux' }}
if: runner.os == 'Linux'
with:
name: psst-gui
path: target/release/psst-gui

- name: Upload macOS Disk Image
uses: actions/upload-artifact@v3
if: ${{ runner.os == 'macOS' }}
if: runner.os == 'macOS'
with:
name: Psst.dmg
path: ./Psst.dmg

- name: Upload Windows Executable
uses: actions/upload-artifact@v3
if: ${{ runner.os == 'Windows' }}
if: runner.os == 'Windows'
with:
name: Psst.exe
path: target/release/psst-gui.exe
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ cargo bundle --release
- Reorder tracks
- Rename playlist
- Playlist folders
- [ ] Playback queue
- [x] Playback queue
- [ ] React to audio output device events
- Pause after disconnecting headphones
- Transfer playback after connecting headphones
Expand Down
4 changes: 3 additions & 1 deletion psst-core/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ fn main() {
// And construct the http-style url
remote_url = format!("https://{domain}/{path}");
}
remote_url = remote_url.trim_end_matches(".git").to_owned();
let trimmed_url = remote_url.trim_end_matches(".git");
remote_url.clone_from(&String::from(trimmed_url));

let outfile = format!("{}/remote-url.txt", outdir);
let mut file = fs::File::create(outfile).unwrap();
write!(file, r#""{}""#, remote_url).ok();
Expand Down
4 changes: 4 additions & 0 deletions psst-core/src/player/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ impl Player {
PlayerCommand::Seek { position } => self.seek(position),
PlayerCommand::Configure { config } => self.configure(config),
PlayerCommand::SetQueueBehavior { behavior } => self.queue.set_behaviour(behavior),
PlayerCommand::AddToQueue { item } => self.queue.add(item),
PlayerCommand::SetVolume { volume } => self.set_volume(volume),
}
}
Expand Down Expand Up @@ -422,6 +423,9 @@ pub enum PlayerCommand {
SetQueueBehavior {
behavior: QueueBehavior,
},
AddToQueue {
item: PlaybackItem,
},
/// Change playback volume to a value in 0.0..=1.0 range.
SetVolume {
volume: f64,
Expand Down
32 changes: 30 additions & 2 deletions psst-core/src/player/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ impl Default for QueueBehavior {

pub struct Queue {
items: Vec<PlaybackItem>,
user_items: Vec<PlaybackItem>,
position: usize,
user_items_position: usize,
positions: Vec<usize>,
behavior: QueueBehavior,
}
Expand All @@ -27,7 +29,9 @@ impl Queue {
pub fn new() -> Self {
Self {
items: Vec::new(),
user_items: Vec::new(),
position: 0,
user_items_position: 0,
positions: Vec::new(),
behavior: QueueBehavior::default(),
}
Expand All @@ -46,6 +50,22 @@ impl Queue {
self.compute_positions();
}

pub fn add(&mut self, item: PlaybackItem) {
self.user_items.push(item);
}

fn handle_added_queue(&mut self) {
if self.user_items.len() > self.user_items_position {
self.items.insert(
self.positions.len(),
self.user_items[self.user_items_position],
);
self.positions
.insert(self.position + 1, self.positions.len());
self.user_items_position += 1;
}
}

pub fn set_behaviour(&mut self, behavior: QueueBehavior) {
self.behavior = behavior;
self.compute_positions();
Expand Down Expand Up @@ -81,10 +101,12 @@ impl Queue {
}

pub fn skip_to_next(&mut self) {
self.handle_added_queue();
self.position = self.next_position();
}

pub fn skip_to_following(&mut self) {
self.handle_added_queue();
self.position = self.following_position();
}

Expand All @@ -94,8 +116,14 @@ impl Queue {
}

pub fn get_following(&self) -> Option<&PlaybackItem> {
let position = self.positions.get(self.following_position()).copied()?;
self.items.get(position)
if let Some(position) = self.positions.get(self.position).copied() {
if let Some(item) = self.items.get(position) {
return Some(item);
}
} else {
return self.user_items.first();
}
None
}

fn previous_position(&self) -> usize {
Expand Down
5 changes: 3 additions & 2 deletions psst-gui/src/cmd.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::time::Duration;

use druid::{Selector, WidgetId};
use psst_core::item_id::ItemId;
use psst_core::{item_id::ItemId, player::item::PlaybackItem};

use crate::{
data::{Nav, PlaybackPayload, QueueBehavior},
data::{Nav, PlaybackPayload, QueueBehavior, QueueEntry},
ui::find::Find,
};

Expand Down Expand Up @@ -56,6 +56,7 @@ pub const PLAY_PAUSE: Selector = Selector::new("app.play-pause");
pub const PLAY_RESUME: Selector = Selector::new("app.play-resume");
pub const PLAY_NEXT: Selector = Selector::new("app.play-next");
pub const PLAY_STOP: Selector = Selector::new("app.play-stop");
pub const ADD_TO_QUEUE: Selector<(QueueEntry, PlaybackItem)> = Selector::new("app.add-to-queue");
pub const PLAY_QUEUE_BEHAVIOR: Selector<QueueBehavior> = Selector::new("app.play-queue-behavior");
pub const PLAY_SEEK: Selector<f64> = Selector::new("app.play-seek");

Expand Down
14 changes: 14 additions & 0 deletions psst-gui/src/controller/playback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,12 @@ impl PlaybackController {
self.send(PlayerEvent::Command(PlayerCommand::SetVolume { volume }));
}

fn add_to_queue(&mut self, item: &PlaybackItem) {
self.send(PlayerEvent::Command(PlayerCommand::AddToQueue {
item: *item,
}));
}

fn set_queue_behavior(&mut self, behavior: QueueBehavior) {
self.send(PlayerEvent::Command(PlayerCommand::SetQueueBehavior {
behavior: match behavior {
Expand Down Expand Up @@ -406,6 +412,14 @@ where
self.stop();
ctx.set_handled();
}
Event::Command(cmd) if cmd.is(cmd::ADD_TO_QUEUE) => {
log::info!("adding to queue");
let (entry, item) = cmd.get_unchecked(cmd::ADD_TO_QUEUE);

self.add_to_queue(item);
data.add_queued_entry(entry.clone());
ctx.set_handled();
}
Event::Command(cmd) if cmd.is(cmd::PLAY_QUEUE_BEHAVIOR) => {
let behavior = cmd.get_unchecked(cmd::PLAY_QUEUE_BEHAVIOR);
data.set_queue_behavior(behavior.to_owned());
Expand Down
1 change: 1 addition & 0 deletions psst-gui/src/data/id.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[allow(dead_code)]
pub trait Id {
type Id: PartialEq;

Expand Down
21 changes: 20 additions & 1 deletion psst-gui/src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ pub struct AppState {
pub personalized: Personalized,
pub alerts: Vector<Alert>,
pub finder: Finder,
pub added_queue: Vector<QueueEntry>,
}

impl AppState {
Expand Down Expand Up @@ -118,6 +119,7 @@ impl AppState {
cache_size: Promise::Empty,
},
playback,
added_queue: Vector::new(),
search: Search {
input: "".into(),
results: Promise::Empty,
Expand Down Expand Up @@ -180,11 +182,28 @@ impl AppState {

impl AppState {
pub fn queued_entry(&self, item_id: ItemId) -> Option<QueueEntry> {
self.playback
if let Some(queued) = self
.playback
.queue
.iter()
.find(|queued| queued.item.id() == item_id)
.cloned()
{
Some(queued)
} else if let Some(queued) = self
.added_queue
.iter()
.find(|queued| queued.item.id() == item_id)
.cloned()
{
return Some(queued);
} else {
None
}
}

pub fn add_queued_entry(&mut self, queue_entry: QueueEntry) {
self.added_queue.push_back(queue_entry);
}

pub fn loading_playback(&mut self, item: Playable, origin: PlaybackOrigin) {
Expand Down
11 changes: 0 additions & 11 deletions psst-gui/src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::time::Duration;

use druid::{
im::Vector,
lens::Unit,
widget::{CrossAxisAlignment, Either, Flex, Label, List, Scroll, Slider, Split, ViewSwitcher},
Color, Env, Insets, Key, LensExt, Menu, MenuItem, Selector, Widget, WidgetExt, WindowDesc,
};
Expand Down Expand Up @@ -114,7 +113,6 @@ fn root_widget() -> impl Widget<AppState> {

let playlists = Flex::column()
.must_fill_main_axis(true)
.with_child(sidebar_logo_widget())
.with_child(sidebar_menu_widget())
.with_default_spacer()
.with_flex_child(playlists, 1.0)
Expand Down Expand Up @@ -277,15 +275,6 @@ fn route_widget() -> impl Widget<AppState> {
.expand()
}

fn sidebar_logo_widget() -> impl Widget<AppState> {
icons::LOGO
.scale((29.0, 32.0))
.with_color(theme::GREY_500)
.padding((0.0, theme::grid(2.0), 0.0, theme::grid(1.0)))
.center()
.lens(Unit)
}

fn sidebar_menu_widget() -> impl Widget<AppState> {
Flex::column()
.with_default_spacer()
Expand Down
10 changes: 7 additions & 3 deletions psst-gui/src/ui/preferences.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use druid::{
Button, Controller, CrossAxisAlignment, Flex, Label, LineBreaking, MainAxisAlignment,
RadioGroup, SizedBox, Slider, TextBox, ViewSwitcher,
},
Color, Data, Env, Event, EventCtx, LensExt, LifeCycle, LifeCycleCtx, Selector, Widget,
Color, Data, Env, Event, EventCtx, Insets, LensExt, LifeCycle, LifeCycleCtx, Selector, Widget,
WidgetExt,
};
use psst_core::connection::Credentials;
Expand Down Expand Up @@ -95,6 +95,12 @@ pub fn preferences_widget() -> impl Widget<AppState> {
.scroll()
.vertical()
.content_must_fill(true)
.padding(if cfg!(target_os = "macos") {
// Accommodate the window controls on Mac.
Insets::new(0.0, 24.0, 0.0, 0.0)
} else {
Insets::ZERO
})
}

fn tabs_widget() -> impl Widget<AppState> {
Expand Down Expand Up @@ -222,7 +228,6 @@ fn general_tab_widget() -> impl Widget<AppState> {
|usize: &usize| usize.to_string(),
)),
)
.padding((theme::grid(1.5), 0.0))
.lens(AppState::config.then(Config::seek_duration)),
);

Expand All @@ -240,7 +245,6 @@ fn general_tab_widget() -> impl Widget<AppState> {
|usize: &usize| usize.to_string(),
)),
)
.padding((theme::grid(1.5), 0.0))
.lens(AppState::config.then(Config::paginated_limit)),
);

Expand Down
Loading

0 comments on commit 9d9acb1

Please sign in to comment.