Skip to content

Commit

Permalink
notify main app of the url to open
Browse files Browse the repository at this point in the history
  • Loading branch information
xou816 committed Nov 26, 2024
1 parent 9a3a235 commit 501f2fa
Show file tree
Hide file tree
Showing 9 changed files with 155 additions and 62 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@ env_logger = "0.10.0"
percent-encoding = "2.2.0"
oauth2 = "4.4"
url = "2.4.1"
open = "5.3.0"
open = "5.3.0"
18 changes: 15 additions & 3 deletions src/app/components/login/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ use gtk::prelude::*;
use gtk::subclass::prelude::*;
use gtk::CompositeTemplate;
use std::rc::Rc;
use url::Url;

use crate::app::components::EventListener;
use crate::app::state::LoginEvent;
use crate::app::AppEvent;
use crate::app::state::{LoginEvent, LoginStartedEvent};
use crate::app::{AppEvent, Worker};

use super::LoginModel;
mod imp {
Expand Down Expand Up @@ -92,10 +93,11 @@ pub struct Login {
parent: gtk::Window,
login_window: LoginWindow,
model: Rc<LoginModel>,
worker: Worker,
}

impl Login {
pub fn new(parent: gtk::Window, model: LoginModel) -> Self {
pub fn new(parent: gtk::Window, model: LoginModel, worker: Worker) -> Self {
let model = Rc::new(model);

let login_window = LoginWindow::new();
Expand All @@ -114,6 +116,7 @@ impl Login {
parent,
login_window,
model,
worker,
}
}

Expand All @@ -135,6 +138,12 @@ impl Login {
self.show_self();
self.login_window.show_auth_error(true);
}

fn open_login_url(&self, url: Url) {
if let Err(_) = open::that(url.as_str()) {
warn!("Could not open login page");
}
}
}

impl EventListener for Login {
Expand All @@ -146,6 +155,9 @@ impl EventListener for Login {
AppEvent::LoginEvent(LoginEvent::LoginFailed) => {
self.reveal_error();
}
AppEvent::LoginEvent(LoginEvent::LoginStarted(LoginStartedEvent::OpenUrl(url))) => {
self.open_login_url(url.clone());
}
AppEvent::Started => {
self.model.try_autologin();
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/login/login_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ impl LoginModel {

pub fn try_autologin(&self) {
self.dispatcher
.dispatch(LoginAction::TryLogin(TryLoginAction::Reconnect).into());
.dispatch(LoginAction::TryLogin(TryLoginAction::Restore).into());
}

pub fn login_with_spotify(&self) {
self.dispatcher
.dispatch(LoginAction::TryLogin(TryLoginAction::NewLogin).into())
.dispatch(LoginAction::TryLogin(TryLoginAction::InitLogin).into())
}
}
9 changes: 4 additions & 5 deletions src/app/components/player_notifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use futures::channel::mpsc::UnboundedSender;
use librespot::core::spotify_id::{SpotifyId, SpotifyItemType};

use crate::app::components::EventListener;
use crate::app::state::{
Device, LoginAction, LoginEvent, LoginStartedEvent, PlaybackEvent, SettingsEvent,
};
use crate::app::state::{Device, LoginAction, LoginEvent, LoginStartedEvent, PlaybackEvent, SettingsEvent};
use crate::app::{ActionDispatcher, AppAction, AppEvent, AppModel, SongsSource};
use crate::connect::ConnectCommand;
use crate::player::Command;
Expand Down Expand Up @@ -85,8 +83,9 @@ impl PlayerNotifier {
fn notify_login(&self, event: &LoginEvent) {
info!("notify_login: {:?}", event);
let command = match event {
LoginEvent::LoginStarted(LoginStartedEvent::Reconnect) => Some(Command::Reconnect),
LoginEvent::LoginStarted(LoginStartedEvent::NewLogin) => Some(Command::NewLogin),
LoginEvent::LoginStarted(LoginStartedEvent::Restore) => Some(Command::Restore),
LoginEvent::LoginStarted(LoginStartedEvent::InitLogin) => Some(Command::InitLogin),
LoginEvent::LoginStarted(LoginStartedEvent::CompleteLogin) => Some(Command::CompleteLogin),
LoginEvent::FreshTokenRequested => Some(Command::RefreshToken),
LoginEvent::LogoutCompleted => Some(Command::Logout),
_ => None,
Expand Down
10 changes: 7 additions & 3 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ impl App {
dispatcher.box_clone(),
worker.clone(),
),
App::make_login(builder, dispatcher.box_clone()),
App::make_login(builder, dispatcher.box_clone(), worker.clone()),
App::make_navigation(
builder,
Rc::clone(model),
Expand Down Expand Up @@ -179,10 +179,14 @@ impl App {
))
}

fn make_login(builder: &gtk::Builder, dispatcher: Box<dyn ActionDispatcher>) -> Box<Login> {
fn make_login(
builder: &gtk::Builder,
dispatcher: Box<dyn ActionDispatcher>,
worker: Worker,
) -> Box<Login> {
let parent: gtk::Window = builder.object("window").unwrap();
let model = LoginModel::new(dispatcher);
Box::new(Login::new(parent, model))
Box::new(Login::new(parent, model, worker))
}

fn make_selection_toolbar(
Expand Down
27 changes: 19 additions & 8 deletions src/app/state/login_state.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
use gettextrs::*;
use std::borrow::Cow;
use url::Url;

use crate::app::models::PlaylistSummary;
use crate::app::state::{AppAction, AppEvent, UpdatableState};

#[derive(Clone, Debug)]
pub enum TryLoginAction {
Reconnect,
NewLogin,
Restore,
InitLogin,
CompleteLogin
}

#[derive(Clone, Debug)]
pub enum LoginAction {
ShowLogin,
OpenLoginUrl(Url),
TryLogin(TryLoginAction),
SetLoginSuccess(String),
SetUserPlaylists(Vec<PlaylistSummary>),
Expand All @@ -32,8 +35,10 @@ impl From<LoginAction> for AppAction {

#[derive(Clone, Debug)]
pub enum LoginStartedEvent {
Reconnect,
NewLogin,
Restore,
InitLogin,
CompleteLogin,
OpenUrl(Url),
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -71,8 +76,14 @@ impl UpdatableState for LoginState {
info!("update_with({:?})", action);
match action.into_owned() {
LoginAction::ShowLogin => vec![LoginEvent::LoginShown.into()],
LoginAction::TryLogin(TryLoginAction::Reconnect) => {
vec![LoginEvent::LoginStarted(LoginStartedEvent::Reconnect).into()]
LoginAction::OpenLoginUrl(url) => {
vec![LoginEvent::LoginStarted(LoginStartedEvent::OpenUrl(url)).into()]
}
LoginAction::TryLogin(TryLoginAction::Restore) => {
vec![LoginEvent::LoginStarted(LoginStartedEvent::Restore).into()]
}
LoginAction::TryLogin(TryLoginAction::CompleteLogin) => {
vec![LoginEvent::LoginStarted(LoginStartedEvent::CompleteLogin).into()]
}
LoginAction::SetLoginSuccess(username) => {
self.user = Some(username);
Expand Down Expand Up @@ -106,8 +117,8 @@ impl UpdatableState for LoginState {
self.playlists = summaries;
vec![LoginEvent::UserPlaylistsLoaded.into()]
}
LoginAction::TryLogin(TryLoginAction::NewLogin) => {
vec![LoginEvent::LoginStarted(LoginStartedEvent::NewLogin).into()]
LoginAction::TryLogin(TryLoginAction::InitLogin) => {
vec![LoginEvent::LoginStarted(LoginStartedEvent::InitLogin).into()]
}
}
}
Expand Down
19 changes: 15 additions & 4 deletions src/player/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Arc;
use tokio::task;
use url::Url;

use crate::app::state::{LoginAction, PlaybackAction};
use crate::app::AppAction;
Expand All @@ -18,8 +19,9 @@ pub use token_store::*;

#[derive(Debug, Clone)]
pub enum Command {
Reconnect,
NewLogin,
Restore,
InitLogin,
CompleteLogin,
RefreshToken,
Logout,
PlayerLoad { track: SpotifyId, resume: bool },
Expand Down Expand Up @@ -89,20 +91,28 @@ impl SpotifyPlayerDelegate for AppPlayerDelegate {
.unbounded_send(PlaybackAction::Preload.into())
.unwrap();
}

fn login_challenge_started(&self, url: Url) {
self.sender
.borrow_mut()
.unbounded_send(LoginAction::OpenLoginUrl(url).into())
.unwrap();
}
}

#[tokio::main]
async fn player_main(
player_settings: SpotifyPlayerSettings,
appaction_sender: UnboundedSender<AppAction>,
token_store: Arc<TokenStore>,
sender: UnboundedSender<Command>,
receiver: UnboundedReceiver<Command>,
) {
task::LocalSet::new()
.run_until(async move {
task::spawn_local(async move {
let delegate = Rc::new(AppPlayerDelegate::new(appaction_sender.clone()));
let player = SpotifyPlayer::new(player_settings, delegate, token_store);
let player = SpotifyPlayer::new(player_settings, delegate, token_store, sender);
player.start(receiver).await.unwrap();
})
.await
Expand All @@ -117,8 +127,9 @@ pub fn start_player_service(
token_store: Arc<TokenStore>,
) -> UnboundedSender<Command> {
let (sender, receiver) = unbounded::<Command>();
let sender_clone = sender.clone();
std::thread::spawn(move || {
player_main(player_settings, appaction_sender, token_store, receiver)
player_main(player_settings, appaction_sender, token_store, sender_clone, receiver)
});
sender
}
Loading

0 comments on commit 501f2fa

Please sign in to comment.