Skip to content

Commit

Permalink
wip navigation improvments
Browse files Browse the repository at this point in the history
  • Loading branch information
xou816 committed Nov 22, 2020
1 parent 63236e3 commit f635cdc
Show file tree
Hide file tree
Showing 10 changed files with 263 additions and 150 deletions.
1 change: 0 additions & 1 deletion src/app/backend/api.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use isahc::prelude::*;
use isahc::HttpClientBuilder;
use serde_json::from_str;
use std::convert::Into;
use std::cell::RefCell;
Expand Down
5 changes: 3 additions & 2 deletions src/app/components/browser/browser_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::app::{AppModel, AppAction, BrowserAction, ActionDispatcher};
use crate::app::dispatch::Worker;
use crate::app::models::*;
use crate::app::backend::api::SpotifyApiClient;
use crate::app::state::LibraryState;
use crate::app::state::{ScreenName, LibraryState};

use super::*;

Expand Down Expand Up @@ -100,7 +100,8 @@ impl BrowserModel for BrowserModelImpl {
}

fn open_album(&self, album_uri: &str) {
self.dispatcher.dispatch(BrowserAction::NavigateToDetails(album_uri.to_owned()).into());
let screen = ScreenName::Details(album_uri.to_owned());
self.dispatcher.dispatch(BrowserAction::NavigationPush(screen).into());

let album = self.get_saved_albums().and_then(|albums| {
albums.iter().find(|a| a.id.eq(album_uri)).cloned()
Expand Down
67 changes: 33 additions & 34 deletions src/app/components/navigation/navigation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use std::rc::Rc;

use crate::app::components::{EventListener, ListenerComponent, DetailsFactory, BrowserFactory, SearchFactory};
use crate::app::{AppEvent, BrowserEvent};
use crate::app::state::ScreenName;

struct NamedWidget(pub String, pub Box<dyn ListenerComponent>);
struct NamedWidget(pub ScreenName, pub Box<dyn ListenerComponent>);

pub trait NavigationModel {
fn go_back(&self);
Expand Down Expand Up @@ -40,65 +41,63 @@ impl Navigation {
Self { model, stack, browser_factory, details_factory, search_factory, children: RefCell::new(vec![]) }
}

fn add_component(&self, component: Box<dyn ListenerComponent>, name: String) {

fn push_screen(&self, name: &ScreenName) {
let component: Box<dyn ListenerComponent> = match name {
ScreenName::Library => Box::new(self.browser_factory.make_browser()),
ScreenName::Details(_) => Box::new(self.details_factory.make_details()),
ScreenName::Search => Box::new(self.search_factory.make_search_results())
};

let widget = component.get_root_widget();
widget.show_all();
self.stack.add_named(widget, &name);
self.children.borrow_mut().push(NamedWidget(name, component));
}

fn switch_to(&self, name: &str) {
self.stack.set_visible_child_name(name);
self.stack.add_named(widget, name.identifier());
self.children.borrow_mut().push(NamedWidget(name.clone(), component));
self.stack.set_visible_child_name(name.identifier());
}

fn create_browser(&self) -> &str {
let name = "library";
let browser = self.browser_factory.make_browser();
self.add_component(Box::new(browser), name.to_owned());
name
}

fn create_details(&self, name: String) {
let details = self.details_factory.make_details();
self.add_component(Box::new(details), name);
}

fn create_search(&self) -> &str {
let name = "search";
let search_results = self.search_factory.make_search_results();
self.add_component(Box::new(search_results), name.to_owned());
name
}

fn pop(&self) {
let mut children = self.children.borrow_mut();
let popped = children.pop();
if let Some(NamedWidget(name, _)) = children.last() {
self.stack.set_visible_child_name(name);
self.stack.set_visible_child_name(name.identifier());
}
if let Some(NamedWidget(_, child)) = popped {
self.stack.remove(child.get_root_widget());
}
}

fn pop_to(&self, screen: &ScreenName) {
self.stack.set_visible_child_name(screen.identifier());
let mut children = self.children.borrow_mut();
let i = children
.iter()
.position(|NamedWidget(name, _)| name == screen)
.unwrap();
let remainder = children.split_off(i + 1);
for NamedWidget(_, widget) in remainder {
self.stack.remove(widget.get_root_widget());
}
}
}

impl EventListener for Navigation {

fn on_event(&self, event: &AppEvent) {
match event {
AppEvent::Started => {
self.create_browser();
},
AppEvent::BrowserEvent(BrowserEvent::NavigatedToDetails(tag)) => {
self.create_details(tag.clone());
self.switch_to(tag);
self.push_screen(&ScreenName::Library);
},
AppEvent::BrowserEvent(BrowserEvent::NavigatedToSearch) => {
let name = self.create_search();
self.switch_to(name);
AppEvent::BrowserEvent(BrowserEvent::NavigationPushed(name)) => {
self.push_screen(name);
},
AppEvent::BrowserEvent(BrowserEvent::NavigationPopped) => {
self.pop();
},
AppEvent::BrowserEvent(BrowserEvent::NavigationPoppedTo(name)) => {
self.pop_to(name);
}
_ => {}
};
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/navigation/navigation_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl NavigationModelImpl {
impl NavigationModel for NavigationModelImpl {

fn go_back(&self) {
self.dispatcher.dispatch(BrowserAction::GoBack.into())
self.dispatcher.dispatch(BrowserAction::NavigationPop.into())
}

fn can_go_back(&self) -> bool {
Expand Down
11 changes: 11 additions & 0 deletions src/app/components/search/search_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ impl SearchBar {
});
}

{
let model = model.clone();
search_entry.connect_focus_in_event(move |s, _| {
let query = s.get_text().as_str().to_string();
if !query.is_empty() {
model.search(query);
}
glib::signal::Inhibit(false)
});
}

Self {}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/search/search_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::cell::{Ref, RefCell};
use std::ops::Deref;
use ref_filter_map::ref_filter_map;
use crate::app::backend::api::SpotifyApiClient;
use crate::app::state::{AppModel, SearchState, BrowserAction};
use crate::app::state::{AppModel, SearchState, BrowserAction, ScreenName};
use crate::app::dispatch::{Worker, ActionDispatcher};
use crate::app::models::*;
use super::SearchResults;
Expand Down Expand Up @@ -66,7 +66,7 @@ impl SearchResultsModel {
}

pub fn open_album(&self, uri: &str) {
self.dispatcher.dispatch(BrowserAction::NavigateToDetails(uri.to_owned()).into());
self.dispatcher.dispatch(BrowserAction::NavigationPush(ScreenName::Details(uri.to_string())).into());

let api = self.spotify();
if let Some(id) = uri.split(":").last() {
Expand Down
Loading

0 comments on commit f635cdc

Please sign in to comment.