Fixed: Clippy & Formatting
This commit is contained in:
parent
286912dbf2
commit
3aadd2b2fe
39
src/api.rs
39
src/api.rs
|
@ -1,20 +1,14 @@
|
|||
use serde_derive::*;
|
||||
use lazy_static::*;
|
||||
use workerpool::Worker;
|
||||
use std::{
|
||||
sync::{
|
||||
Arc,
|
||||
use serde_derive::*;
|
||||
use std::sync::{
|
||||
mpsc::{channel, Receiver},
|
||||
Mutex,
|
||||
},
|
||||
Arc, Mutex,
|
||||
};
|
||||
use workerpool::Worker;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref API: Arc<Mutex<Option<RequestContext>>>
|
||||
= Arc::new(Mutex::new(None));
|
||||
|
||||
static ref JOBS: workerpool::Pool<Req>
|
||||
= workerpool::Pool::new(5);
|
||||
pub static ref API: Arc<Mutex<Option<RequestContext>>> = Arc::new(Mutex::new(None));
|
||||
static ref JOBS: workerpool::Pool<Req> = workerpool::Pool::new(5);
|
||||
}
|
||||
|
||||
pub fn execute(req: reqwest::RequestBuilder) -> Receiver<reqwest::Response> {
|
||||
|
@ -33,24 +27,29 @@ impl RequestContext {
|
|||
pub fn new(instance: String) -> Self {
|
||||
RequestContext {
|
||||
token: String::new(),
|
||||
instance: instance.clone(),
|
||||
client: reqwest::Client::new()
|
||||
instance,
|
||||
client: reqwest::Client::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn auth(&mut self, token: String) {
|
||||
self.token = token.clone();
|
||||
self.token = token;
|
||||
}
|
||||
|
||||
pub fn get<S: AsRef<str>>(&self, url: S) -> reqwest::RequestBuilder {
|
||||
self.client
|
||||
self
|
||||
.client
|
||||
.get(&format!("{}{}", self.instance, url.as_ref()))
|
||||
.header(reqwest::header::AUTHORIZATION, format!("JWT {}", self.token))
|
||||
.header(
|
||||
reqwest::header::AUTHORIZATION,
|
||||
format!("JWT {}", self.token),
|
||||
)
|
||||
}
|
||||
|
||||
/// Warning: no authentication, since it is only used for login
|
||||
pub fn post<S: AsRef<str>>(&self, url: S) -> reqwest::RequestBuilder {
|
||||
self.client
|
||||
self
|
||||
.client
|
||||
.post(&format!("{}{}", self.instance, url.as_ref()))
|
||||
}
|
||||
|
||||
|
@ -82,7 +81,7 @@ pub struct LoginData {
|
|||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct LoginInfo {
|
||||
pub token: String
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
|
@ -161,7 +160,7 @@ impl AlbumTrack {
|
|||
let mut album = album.clone();
|
||||
album.tracks = None;
|
||||
Track {
|
||||
album: album,
|
||||
album,
|
||||
id: self.id,
|
||||
title: self.title,
|
||||
artist: self.artist,
|
||||
|
|
96
src/main.rs
96
src/main.rs
|
@ -1,11 +1,11 @@
|
|||
use gtk::{self, prelude::*, *};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
cell::RefCell,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex},
|
||||
collections::HashMap,
|
||||
fs,
|
||||
path::PathBuf,
|
||||
rc::Rc,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
macro_rules! clone {
|
||||
|
@ -37,32 +37,30 @@ macro_rules! rc {
|
|||
macro_rules! wait {
|
||||
($exp:expr => | const $res:ident | $then:block) => {
|
||||
let rx = $exp;
|
||||
gtk::idle_add(move || {
|
||||
match rx.try_recv() {
|
||||
gtk::idle_add(move || match rx.try_recv() {
|
||||
Err(_) => glib::Continue(true),
|
||||
Ok($res) => {
|
||||
$then;
|
||||
glib::Continue(false)
|
||||
},
|
||||
}
|
||||
})
|
||||
};
|
||||
($exp:expr => | $res:ident | $then:block) => {
|
||||
let rx = $exp;
|
||||
gtk::idle_add(move || {
|
||||
match rx.try_recv() {
|
||||
gtk::idle_add(move || match rx.try_recv() {
|
||||
Err(_) => glib::Continue(true),
|
||||
Ok(mut $res) => {
|
||||
$then;
|
||||
glib::Continue(false)
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! client {
|
||||
() => (crate::api::API.lock().unwrap().as_ref().unwrap())
|
||||
() => {
|
||||
crate::api::API.lock().unwrap().as_ref().unwrap()
|
||||
};
|
||||
}
|
||||
|
||||
mod api;
|
||||
|
@ -127,12 +125,16 @@ impl workerpool::Worker for TrackDl {
|
|||
|
||||
let mut res = client!().get(&dl.url).send().unwrap();
|
||||
|
||||
let ext = res.headers()
|
||||
.get(reqwest::header::CONTENT_DISPOSITION).and_then(|h| h.to_str().ok())
|
||||
let ext = res
|
||||
.headers()
|
||||
.get(reqwest::header::CONTENT_DISPOSITION)
|
||||
.and_then(|h| h.to_str().ok())
|
||||
.unwrap_or(".mp3")
|
||||
.rsplitn(2, ".").next().unwrap_or("mp3");
|
||||
.rsplitn(2, '.')
|
||||
.next()
|
||||
.unwrap_or("mp3");
|
||||
|
||||
fs::create_dir_all(dl.output.clone().parent().unwrap()).unwrap();
|
||||
fs::create_dir_all(dl.output.parent().unwrap()).unwrap();
|
||||
let mut out = dl.output.clone();
|
||||
out.set_extension(ext);
|
||||
let mut file = fs::File::create(out.clone()).unwrap();
|
||||
|
@ -162,9 +164,13 @@ fn main() {
|
|||
|
||||
fs::create_dir_all(dirs::config_dir().unwrap().join("mobydick")).unwrap();
|
||||
fs::write(
|
||||
dirs::config_dir().unwrap().join("mobydick").join("data.json"),
|
||||
serde_json::to_string(&client!().to_json()).unwrap()
|
||||
).unwrap();
|
||||
dirs::config_dir()
|
||||
.unwrap()
|
||||
.join("mobydick")
|
||||
.join("data.json"),
|
||||
serde_json::to_string(&client!().to_json()).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Inhibit(false)
|
||||
});
|
||||
|
@ -175,7 +181,14 @@ fn main() {
|
|||
}
|
||||
|
||||
fn init(window: Rc<RefCell<Window>>) {
|
||||
let connected = fs::read(dirs::config_dir().unwrap().join("mobydick").join("data.json")).ok().and_then(|f| {
|
||||
let connected = fs::read(
|
||||
dirs::config_dir()
|
||||
.unwrap()
|
||||
.join("mobydick")
|
||||
.join("data.json"),
|
||||
)
|
||||
.ok()
|
||||
.and_then(|f| {
|
||||
let json: serde_json::Value = serde_json::from_slice(&f).ok()?;
|
||||
let mut api_ctx = crate::api::API.lock().ok()?;
|
||||
let mut ctx = api::RequestContext::new(json["instance"].as_str()?.to_string());
|
||||
|
@ -183,7 +196,8 @@ fn init(window: Rc<RefCell<Window>>) {
|
|||
*api_ctx = Some(ctx);
|
||||
|
||||
Some(())
|
||||
}).is_some();
|
||||
})
|
||||
.is_some();
|
||||
|
||||
let state = Rc::new(RefCell::new(AppState {
|
||||
window: window.clone(),
|
||||
|
@ -196,7 +210,12 @@ fn init(window: Rc<RefCell<Window>>) {
|
|||
let error = InfoBar::new();
|
||||
error.set_revealed(false);
|
||||
error.set_message_type(MessageType::Error);
|
||||
error.get_content_area().unwrap().downcast::<gtk::Box>().unwrap().add(&Label::new("Test test"));
|
||||
error
|
||||
.get_content_area()
|
||||
.unwrap()
|
||||
.downcast::<gtk::Box>()
|
||||
.unwrap()
|
||||
.add(&Label::new("Test test"));
|
||||
error.set_show_close_button(true);
|
||||
error.connect_close(|e| e.set_revealed(false));
|
||||
error.connect_response(|e, _| e.set_revealed(false));
|
||||
|
@ -221,17 +240,20 @@ fn init(window: Rc<RefCell<Window>>) {
|
|||
window.borrow().show_all();
|
||||
|
||||
if connected {
|
||||
let main_page = ui::main_page::render(
|
||||
state.borrow().window.clone(),
|
||||
&state.borrow().header,
|
||||
&{
|
||||
let main_page =
|
||||
ui::main_page::render(state.borrow().window.clone(), &state.borrow().header, &{
|
||||
let s = StackSwitcher::new();
|
||||
s.set_stack(&state.borrow().stack);
|
||||
s
|
||||
}
|
||||
);
|
||||
state.borrow().stack.add_titled(&main_page, "main", "Search Music");
|
||||
state.borrow().stack.add_titled(&*ui::dl_list::render().borrow(), "downloads", "Downloads");
|
||||
});
|
||||
state
|
||||
.borrow()
|
||||
.stack
|
||||
.add_titled(&main_page, "main", "Search Music");
|
||||
state
|
||||
.borrow()
|
||||
.stack
|
||||
.add_titled(&*ui::dl_list::render().borrow(), "downloads", "Downloads");
|
||||
state.borrow().stack.set_visible_child_name("main");
|
||||
} else {
|
||||
let login_page = ui::login_page::render(state.clone());
|
||||
|
@ -240,7 +262,13 @@ fn init(window: Rc<RefCell<Window>>) {
|
|||
}
|
||||
|
||||
fn show_error(state: State, msg: &str) {
|
||||
let b = state.borrow().error.get_content_area().unwrap().downcast::<gtk::Box>().unwrap();
|
||||
let b = state
|
||||
.borrow()
|
||||
.error
|
||||
.get_content_area()
|
||||
.unwrap()
|
||||
.downcast::<gtk::Box>()
|
||||
.unwrap();
|
||||
for ch in b.get_children() {
|
||||
b.remove(&ch);
|
||||
}
|
||||
|
@ -250,7 +278,13 @@ fn show_error(state: State, msg: &str) {
|
|||
}
|
||||
|
||||
fn logout(window: Rc<RefCell<Window>>) {
|
||||
fs::remove_file(dirs::config_dir().unwrap().join("mobydick").join("data.json")).ok();
|
||||
fs::remove_file(
|
||||
dirs::config_dir()
|
||||
.unwrap()
|
||||
.join("mobydick")
|
||||
.join("data.json"),
|
||||
)
|
||||
.ok();
|
||||
*api::API.lock().unwrap() = None;
|
||||
*DOWNLOADS.lock().unwrap() = HashMap::new();
|
||||
{
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
use crate::{api, ui::network_image::NetworkImage, DlStatus, Download};
|
||||
use gtk::*;
|
||||
use std::{thread, sync::mpsc::channel, rc::Rc, cell::RefCell};
|
||||
use crate::{Download, DlStatus, api, ui::network_image::NetworkImage};
|
||||
use std::{cell::RefCell, rc::Rc, sync::mpsc::channel, thread};
|
||||
|
||||
pub fn render<T>(model: T) -> Rc<RefCell<Grid>> where T: CardModel + 'static {
|
||||
pub fn render<T>(model: T) -> Rc<RefCell<Grid>>
|
||||
where
|
||||
T: CardModel + 'static,
|
||||
{
|
||||
let card = Grid::new();
|
||||
card.set_column_spacing(12);
|
||||
card.set_valign(Align::Start);
|
||||
|
@ -13,11 +16,15 @@ pub fn render<T>(model: T) -> Rc<RefCell<Grid>> where T: CardModel + 'static {
|
|||
}
|
||||
|
||||
let main_text = Label::new(model.text().as_ref());
|
||||
main_text.get_style_context().map(|c| c.add_class("h3"));
|
||||
if let Some(c) = main_text.get_style_context() {
|
||||
c.add_class("h3")
|
||||
}
|
||||
main_text.set_hexpand(true);
|
||||
main_text.set_halign(Align::Start);
|
||||
let sub_text = Label::new(model.subtext().as_ref());
|
||||
sub_text.get_style_context().map(|c| c.add_class("dim-label"));
|
||||
if let Some(c) = sub_text.get_style_context() {
|
||||
c.add_class("dim-label")
|
||||
}
|
||||
sub_text.set_hexpand(true);
|
||||
sub_text.set_halign(Align::Start);
|
||||
|
||||
|
@ -28,7 +35,9 @@ pub fn render<T>(model: T) -> Rc<RefCell<Grid>> where T: CardModel + 'static {
|
|||
let open_bt = Button::new_with_label("Play");
|
||||
open_bt.set_valign(Align::Center);
|
||||
open_bt.set_vexpand(true);
|
||||
open_bt.get_style_context().map(|c| c.add_class("suggested-action"));
|
||||
if let Some(c) = open_bt.get_style_context() {
|
||||
c.add_class("suggested-action")
|
||||
}
|
||||
|
||||
let out = dl.output.clone();
|
||||
open_bt.connect_clicked(move |_| {
|
||||
|
@ -41,18 +50,20 @@ pub fn render<T>(model: T) -> Rc<RefCell<Grid>> where T: CardModel + 'static {
|
|||
open_bt.set_valign(Align::Center);
|
||||
open_bt.set_vexpand(true);
|
||||
|
||||
let out = dl.output.clone();
|
||||
let out = dl.output;
|
||||
open_bt.connect_clicked(move |_| {
|
||||
open::that(out.parent().unwrap().clone()).unwrap();
|
||||
open::that(&(*out.parent().unwrap())).unwrap();
|
||||
println!("opened folder");
|
||||
});
|
||||
card.borrow().attach(&open_bt, 2, 0, 1, 2);
|
||||
},
|
||||
}
|
||||
DlStatus::Planned | DlStatus::Started => {
|
||||
let cancel_bt = Button::new_with_label("Cancel");
|
||||
cancel_bt.set_valign(Align::Center);
|
||||
cancel_bt.set_vexpand(true);
|
||||
cancel_bt.get_style_context().map(|c| c.add_class("destructive-action"));
|
||||
if let Some(c) = cancel_bt.get_style_context() {
|
||||
c.add_class("destructive-action")
|
||||
}
|
||||
|
||||
let track_id = dl.track.id;
|
||||
cancel_bt.connect_clicked(move |_| {
|
||||
|
@ -77,7 +88,9 @@ pub fn render<T>(model: T) -> Rc<RefCell<Grid>> where T: CardModel + 'static {
|
|||
let dl_bt = Button::new_with_label("Download");
|
||||
dl_bt.set_valign(Align::Center);
|
||||
dl_bt.set_vexpand(true);
|
||||
dl_bt.get_style_context().map(|c| c.add_class("suggested-action"));
|
||||
if let Some(c) = dl_bt.get_style_context() {
|
||||
c.add_class("suggested-action")
|
||||
}
|
||||
|
||||
rc!(dl_bt);
|
||||
{
|
||||
|
@ -153,7 +166,10 @@ impl CardModel for api::Artist {
|
|||
}
|
||||
|
||||
fn image_url(&self) -> Option<String> {
|
||||
self.albums.clone()?.iter()
|
||||
self
|
||||
.albums
|
||||
.clone()?
|
||||
.iter()
|
||||
.next()
|
||||
.and_then(|album| album.cover.medium_square_crop.clone())
|
||||
}
|
||||
|
@ -161,14 +177,18 @@ impl CardModel for api::Artist {
|
|||
fn downloads(&self) -> Vec<Download> {
|
||||
let mut dls = vec![];
|
||||
for album in self.albums.clone().unwrap_or_default() {
|
||||
let album: api::Album = client!().get(&format!("/api/v1/albums/{}/", album.id))
|
||||
.send().unwrap()
|
||||
.json().unwrap();
|
||||
let album: api::Album = client!()
|
||||
.get(&format!("/api/v1/albums/{}/", album.id))
|
||||
.send()
|
||||
.unwrap()
|
||||
.json()
|
||||
.unwrap();
|
||||
|
||||
for track in album.clone().tracks.unwrap_or_default() {
|
||||
dls.push(Download {
|
||||
url: track.listen_url.clone(),
|
||||
output: dirs::audio_dir().unwrap()
|
||||
output: dirs::audio_dir()
|
||||
.unwrap()
|
||||
.join(self.name.clone())
|
||||
.join(album.title.clone())
|
||||
.join(format!("{}.mp3", track.title.clone())),
|
||||
|
@ -187,7 +207,11 @@ impl CardModel for api::Album {
|
|||
}
|
||||
|
||||
fn subtext(&self) -> String {
|
||||
format!("{} tracks, by {}", self.tracks.clone().map(|t| t.len()).unwrap_or_default(), self.artist.name)
|
||||
format!(
|
||||
"{} tracks, by {}",
|
||||
self.tracks.clone().map(|t| t.len()).unwrap_or_default(),
|
||||
self.artist.name
|
||||
)
|
||||
}
|
||||
|
||||
fn image_url(&self) -> Option<String> {
|
||||
|
@ -195,17 +219,22 @@ impl CardModel for api::Album {
|
|||
}
|
||||
|
||||
fn downloads(&self) -> Vec<Download> {
|
||||
self.tracks.clone().unwrap_or_default().iter().map(|track|
|
||||
Download {
|
||||
self
|
||||
.tracks
|
||||
.clone()
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|track| Download {
|
||||
url: track.listen_url.clone(),
|
||||
output: dirs::audio_dir().unwrap()
|
||||
output: dirs::audio_dir()
|
||||
.unwrap()
|
||||
.join(self.artist.name.clone())
|
||||
.join(self.title.clone())
|
||||
.join(format!("{}.mp3", track.title.clone())),
|
||||
status: DlStatus::Planned,
|
||||
track: track.clone().into_full(&self),
|
||||
}
|
||||
).collect()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +254,8 @@ impl CardModel for api::Track {
|
|||
fn downloads(&self) -> Vec<Download> {
|
||||
vec![Download {
|
||||
url: self.listen_url.clone(),
|
||||
output: dirs::audio_dir().unwrap()
|
||||
output: dirs::audio_dir()
|
||||
.unwrap()
|
||||
.join(self.artist.name.clone())
|
||||
.join(self.album.title.clone())
|
||||
.join(format!("{}.mp3", self.title.clone())),
|
||||
|
@ -235,6 +265,6 @@ impl CardModel for api::Track {
|
|||
}
|
||||
|
||||
fn download_status(&self) -> Option<Download> {
|
||||
crate::DOWNLOADS.lock().ok()?.get(&self.id).map(|x| x.clone())
|
||||
crate::DOWNLOADS.lock().ok()?.get(&self.id).cloned()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::ui::card;
|
||||
use gtk::{prelude::*, *};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use crate::{ui::card};
|
||||
|
||||
pub fn render() -> Rc<RefCell<gtk::Box>> {
|
||||
let cont = gtk::Box::new(Orientation::Vertical, 12);
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use crate::{api::*, ui::title, State};
|
||||
use gtk::*;
|
||||
use std::{
|
||||
rc::Rc,
|
||||
cell::RefCell,
|
||||
};
|
||||
use crate::{State, api::*, ui::title};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub fn render(state: State) -> gtk::Box {
|
||||
let cont = gtk::Box::new(Orientation::Vertical, 24);
|
||||
|
@ -12,17 +9,16 @@ pub fn render(state: State) -> gtk::Box {
|
|||
cont.set_size_request(300, -1);
|
||||
let title = title("Login");
|
||||
|
||||
let instance = Input::new("Instance URL")
|
||||
.with_placeholder("demo.funkwhale.audio");
|
||||
let instance = Input::new("Instance URL").with_placeholder("demo.funkwhale.audio");
|
||||
let username = Input::new("Username");
|
||||
let password = Input::new_password("Password");
|
||||
|
||||
let login_bt = Button::new_with_label("Login");
|
||||
login_bt.get_style_context().map(|c| c.add_class("suggested-action"));
|
||||
if let Some(c) = login_bt.get_style_context() {
|
||||
c.add_class("suggested-action")
|
||||
}
|
||||
login_bt.set_margin_bottom(48);
|
||||
let widgets = Rc::new(RefCell::new((
|
||||
instance, username, password
|
||||
)));
|
||||
let widgets = Rc::new(RefCell::new((instance, username, password)));
|
||||
login_bt.connect_clicked(clone!(state, widgets => move |_| {
|
||||
let mut api_ctx = crate::api::API.lock().unwrap();
|
||||
let mut instance_url = widgets.borrow().0.get_text().unwrap().trim_end_matches('/').to_string();
|
||||
|
@ -35,8 +31,8 @@ pub fn render(state: State) -> gtk::Box {
|
|||
|
||||
let state = state.clone();
|
||||
wait!(execute(api_ctx.as_ref().unwrap().post("/api/v1/token/").json(&LoginData {
|
||||
username: widgets.borrow().1.get_text().clone().unwrap(),
|
||||
password: widgets.borrow().2.get_text().clone().unwrap(),
|
||||
username: widgets.borrow().1.get_text().unwrap(),
|
||||
password: widgets.borrow().2.get_text().unwrap(),
|
||||
})) => |res| {
|
||||
let res: Result<LoginInfo, _> = res.json();
|
||||
|
||||
|
@ -44,7 +40,7 @@ pub fn render(state: State) -> gtk::Box {
|
|||
Err(_) => crate::show_error(state.clone(), "Somehting went wrong, check your username and password, and the URL of your instance."),
|
||||
Ok(res) => {
|
||||
if let Some(ref mut client) = *crate::api::API.lock().unwrap() {
|
||||
client.auth(res.token.clone());
|
||||
client.auth(res.token);
|
||||
}
|
||||
|
||||
let state = state.borrow();
|
||||
|
@ -69,7 +65,6 @@ pub fn render(state: State) -> gtk::Box {
|
|||
}));
|
||||
|
||||
{
|
||||
|
||||
let (ref instance, ref username, ref password) = *widgets.borrow();
|
||||
cont.add(&title);
|
||||
cont.add(&instance.render());
|
||||
|
@ -78,10 +73,18 @@ pub fn render(state: State) -> gtk::Box {
|
|||
cont.add(&login_bt);
|
||||
}
|
||||
|
||||
widgets.borrow().0.entry.connect_activate(clone!(widgets => move |_| {
|
||||
widgets
|
||||
.borrow()
|
||||
.0
|
||||
.entry
|
||||
.connect_activate(clone!(widgets => move |_| {
|
||||
widgets.borrow().1.entry.grab_focus();
|
||||
}));
|
||||
widgets.borrow().1.entry.connect_activate(clone!(widgets => move |_| {
|
||||
widgets
|
||||
.borrow()
|
||||
.1
|
||||
.entry
|
||||
.connect_activate(clone!(widgets => move |_| {
|
||||
widgets.borrow().2.entry.grab_focus();
|
||||
}));
|
||||
widgets.borrow().2.entry.connect_activate(move |_| {
|
||||
|
@ -100,10 +103,7 @@ struct Input<'a> {
|
|||
impl<'a> Input<'a> {
|
||||
fn new(text: &'a str) -> Input {
|
||||
let entry = gtk::Entry::new();
|
||||
Input {
|
||||
label: text,
|
||||
entry
|
||||
}
|
||||
Input { label: text, entry }
|
||||
}
|
||||
|
||||
fn new_password(text: &'a str) -> Input {
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
use crate::{
|
||||
api::{self, execute},
|
||||
ui::{card, title},
|
||||
};
|
||||
use gdk::ContextExt;
|
||||
use gdk_pixbuf::PixbufExt;
|
||||
use gtk::*;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
fs,
|
||||
rc::Rc,
|
||||
};
|
||||
use crate::{api::{self, execute}, ui::{title, card}};
|
||||
use std::{cell::RefCell, fs, rc::Rc};
|
||||
|
||||
pub fn render(window: Rc<RefCell<Window>>, header: &HeaderBar, switcher: &StackSwitcher) -> gtk::Box {
|
||||
pub fn render(
|
||||
window: Rc<RefCell<Window>>,
|
||||
header: &HeaderBar,
|
||||
switcher: &StackSwitcher,
|
||||
) -> gtk::Box {
|
||||
let cont = gtk::Box::new(Orientation::Vertical, 12);
|
||||
cont.set_margin_top(48);
|
||||
cont.set_margin_bottom(48);
|
||||
cont.set_margin_start(96);
|
||||
cont.set_margin_end(96);
|
||||
|
||||
let avatar_path = dirs::cache_dir().unwrap().join("mobydick").join("avatar.png");
|
||||
let avatar_path = dirs::cache_dir()
|
||||
.unwrap()
|
||||
.join("mobydick")
|
||||
.join("avatar.png");
|
||||
|
||||
let avatar = DrawingArea::new();
|
||||
avatar.set_size_request(32, 32);
|
||||
|
@ -135,4 +141,3 @@ fn update_results(res: api::SearchResult, cont: >k::Box) {
|
|||
|
||||
cont.show_all();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ pub mod network_image;
|
|||
|
||||
fn title(text: &str) -> gtk::Label {
|
||||
let lbl = gtk::Label::new(text);
|
||||
lbl.get_style_context().map(|c| c.add_class("h2"));
|
||||
if let Some(c) = lbl.get_style_context() {
|
||||
c.add_class("h2")
|
||||
}
|
||||
lbl
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use gtk::*;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
fs, rc::Rc,
|
||||
};
|
||||
use crate::api::execute;
|
||||
use gtk::{Image, ImageExt};
|
||||
use std::{cell::RefCell, fs, rc::Rc};
|
||||
|
||||
pub struct NetworkImage {
|
||||
pub img: Rc<RefCell<Image>>,
|
||||
|
@ -15,7 +12,10 @@ impl NetworkImage {
|
|||
rc!(image);
|
||||
|
||||
let dest_file = url.split("/media/").last().unwrap().replace('/', "-");
|
||||
let dest = dirs::cache_dir().unwrap().join(env!("CARGO_PKG_NAME")).join(dest_file.to_string());
|
||||
let dest = dirs::cache_dir()
|
||||
.unwrap()
|
||||
.join(env!("CARGO_PKG_NAME"))
|
||||
.join(dest_file);
|
||||
|
||||
if dest.exists() {
|
||||
let pb = gdk_pixbuf::Pixbuf::new_from_file_at_scale(dest, 64, 64, true).unwrap();
|
||||
|
@ -32,8 +32,6 @@ impl NetworkImage {
|
|||
});
|
||||
}
|
||||
|
||||
NetworkImage {
|
||||
img: image.clone(),
|
||||
}
|
||||
NetworkImage { img: image }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue