2019-02-03 21:46:29 +01:00
|
|
|
use gtk::{self, prelude::*, *};
|
|
|
|
use std::{
|
|
|
|
cell::RefCell,
|
|
|
|
rc::Rc,
|
2019-02-08 13:35:58 +01:00
|
|
|
sync::{Arc, Mutex},
|
2019-02-03 21:46:29 +01:00
|
|
|
fs,
|
|
|
|
path::PathBuf,
|
|
|
|
};
|
|
|
|
|
2019-02-05 14:11:02 +01:00
|
|
|
macro_rules! clone {
|
|
|
|
(@param _) => ( _ );
|
|
|
|
(@param $x:ident) => ( $x );
|
|
|
|
($($n:ident),+ => move || $body:expr) => (
|
|
|
|
{
|
|
|
|
$( let $n = $n.clone(); )+
|
|
|
|
move || $body
|
|
|
|
}
|
|
|
|
);
|
|
|
|
($($n:ident),+ => move |$($p:tt),+| $body:expr) => (
|
|
|
|
{
|
|
|
|
$( let $n = $n.clone(); )+
|
|
|
|
move |$(clone!(@param $p),)+| $body
|
|
|
|
}
|
|
|
|
);
|
2019-02-08 13:35:58 +01:00
|
|
|
($($n:ident),+) => (
|
|
|
|
$( let $n = $n.clone(); )+
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! rc {
|
|
|
|
($($n:ident),+) => (
|
|
|
|
$( let $n = std::rc::Rc::new(std::cell::RefCell::new($n)); )+
|
|
|
|
)
|
2019-02-05 14:11:02 +01:00
|
|
|
}
|
|
|
|
|
2019-02-06 21:05:20 +01:00
|
|
|
macro_rules! wait {
|
2019-02-08 13:35:58 +01:00
|
|
|
($exp:expr => | const $res:ident | $then:block) => {
|
|
|
|
let rx = $exp;
|
|
|
|
gtk::idle_add(move || {
|
|
|
|
match rx.try_recv() {
|
|
|
|
Err(_) => glib::Continue(true),
|
|
|
|
Ok($res) => {
|
|
|
|
$then;
|
|
|
|
glib::Continue(false)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
2019-02-06 21:05:20 +01:00
|
|
|
($exp:expr => | $res:ident | $then:block) => {
|
|
|
|
let rx = $exp;
|
|
|
|
gtk::idle_add(move || {
|
|
|
|
match rx.try_recv() {
|
|
|
|
Err(_) => glib::Continue(true),
|
|
|
|
Ok(mut $res) => {
|
|
|
|
$then;
|
|
|
|
glib::Continue(false)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:58 +01:00
|
|
|
macro_rules! client {
|
|
|
|
() => (crate::api::API.lock().unwrap().as_ref().unwrap())
|
|
|
|
}
|
|
|
|
|
2019-02-03 21:46:29 +01:00
|
|
|
mod api;
|
2019-02-05 14:11:02 +01:00
|
|
|
mod ui;
|
|
|
|
|
2019-02-03 21:46:29 +01:00
|
|
|
#[derive(Debug)]
|
2019-02-05 14:11:02 +01:00
|
|
|
pub struct AppState {
|
2019-02-03 21:46:29 +01:00
|
|
|
stack: Stack,
|
|
|
|
err_revealer: Revealer,
|
|
|
|
err_label: Label,
|
|
|
|
downloads: Arc<RefCell<Vec<Download>>>,
|
|
|
|
}
|
|
|
|
|
2019-02-05 14:11:02 +01:00
|
|
|
pub type State = Rc<RefCell<AppState>>;
|
2019-02-03 21:46:29 +01:00
|
|
|
|
2019-02-08 13:35:58 +01:00
|
|
|
#[derive(Debug, Clone)]
|
2019-02-05 14:11:02 +01:00
|
|
|
pub struct Download {
|
2019-02-03 21:46:29 +01:00
|
|
|
url: String,
|
|
|
|
done: bool,
|
|
|
|
output: PathBuf,
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:58 +01:00
|
|
|
lazy_static! {
|
|
|
|
static ref DOWNLOADS: Arc<Mutex<Vec<Download>>> = Arc::new(Mutex::new(vec![]));
|
|
|
|
}
|
|
|
|
|
2019-02-03 21:46:29 +01:00
|
|
|
fn main() {
|
|
|
|
if gtk::init().is_err() {
|
|
|
|
println!("Failed to initialize GTK.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let window = Window::new(WindowType::Toplevel);
|
|
|
|
window.set_title("Funkload");
|
|
|
|
window.set_default_size(1080, 720);
|
|
|
|
|
2019-02-08 13:35:58 +01:00
|
|
|
let connected = fs::read("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());
|
|
|
|
ctx.auth(json["token"].as_str()?.to_string());
|
|
|
|
*api_ctx = Some(ctx);
|
|
|
|
|
|
|
|
Some(())
|
|
|
|
}).is_some();
|
2019-02-03 21:46:29 +01:00
|
|
|
|
|
|
|
let err_revealer = Revealer::new();
|
|
|
|
let err_label = Label::new("Error");
|
|
|
|
err_revealer.add(&err_label);
|
|
|
|
let state = Rc::new(RefCell::new(AppState {
|
|
|
|
stack: Stack::new(),
|
|
|
|
err_revealer: err_revealer,
|
|
|
|
err_label: err_label,
|
|
|
|
downloads: Arc::new(RefCell::new(Vec::new())),
|
|
|
|
}));
|
|
|
|
|
2019-02-05 14:11:02 +01:00
|
|
|
let login_page = ui::login_page::render(state.clone());
|
2019-02-03 21:46:29 +01:00
|
|
|
|
2019-02-05 14:11:02 +01:00
|
|
|
state.borrow().stack.add_named(&login_page, "login");
|
2019-02-05 17:32:26 +01:00
|
|
|
let scrolled = ScrolledWindow::new(None, None);
|
|
|
|
scrolled.add(&state.borrow().stack);
|
|
|
|
window.add(&scrolled);
|
2019-02-03 21:46:29 +01:00
|
|
|
window.show_all();
|
|
|
|
|
2019-02-08 13:35:58 +01:00
|
|
|
if connected {
|
|
|
|
let main_page = ui::main_page::render();
|
2019-02-05 14:11:02 +01:00
|
|
|
state.borrow().stack.add_named(&main_page, "main");
|
|
|
|
state.borrow().stack.set_visible_child_name("main");
|
2019-02-03 21:46:29 +01:00
|
|
|
}
|
|
|
|
|
2019-02-08 13:35:58 +01:00
|
|
|
window.connect_delete_event(move |_, _| {
|
2019-02-03 21:46:29 +01:00
|
|
|
gtk::main_quit();
|
|
|
|
|
2019-02-08 13:35:58 +01:00
|
|
|
fs::write("data.json", serde_json::to_string(&client!().to_json()).unwrap()).unwrap();
|
2019-02-03 21:46:29 +01:00
|
|
|
|
|
|
|
Inhibit(false)
|
2019-02-08 13:35:58 +01:00
|
|
|
});
|
2019-02-03 21:46:29 +01:00
|
|
|
|
|
|
|
gtk::main();
|
|
|
|
}
|