email-client

A gtk4 Email Client
git clone git://archive.git.mtrnord.blog/erooster-mail/email-client.git
Log | Files | Refs | LICENSE

main.rs (3544B)


      1 use color_eyre::Result;
      2 use gtk::{gdk::Display, gio, prelude::*, Application};
      3 use login_view::LoginView;
      4 use main_view::MainView;
      5 use relm4::component::AsyncComponent;
      6 use relm4::component::AsyncComponentController;
      7 use relm4::component::AsyncController;
      8 use relm4::prelude::*;
      9 use std::convert::identity;
     10 
     11 #[rustfmt::skip]
     12 mod config;
     13 
     14 mod folder_view;
     15 mod imap_state;
     16 mod login_view;
     17 mod main_view;
     18 
     19 struct App {
     20     main_view: Controller<MainView>,
     21     login_view: AsyncController<LoginView>,
     22     active_child: Child,
     23 }
     24 
     25 #[derive(Debug)]
     26 pub enum AppMsg {
     27     ToMainView,
     28 }
     29 
     30 #[derive(Debug)]
     31 enum Child {
     32     LoginView,
     33     MainView,
     34 }
     35 
     36 #[relm4::component]
     37 impl SimpleComponent for App {
     38     type Init = ();
     39     type Input = AppMsg;
     40     type Output = ();
     41 
     42     view! {
     43         #[root]
     44         #[name(main_window)]
     45         gtk::ApplicationWindow {
     46             set_title: Some("Email"),
     47             set_default_size: (1280, 720),
     48 
     49             match model.active_child {
     50                Child::LoginView => {
     51                     gtk::Box {
     52                         set_halign: gtk::Align::Fill,
     53                         set_valign: gtk::Align::Fill,
     54                         model.login_view.widget(),
     55                     }
     56                 },
     57                 Child::MainView => {
     58                     gtk::Box {
     59                         set_halign: gtk::Align::Fill,
     60                         set_valign: gtk::Align::Fill,
     61                         model.main_view.widget(),
     62                     }
     63                 }
     64             },
     65         }
     66     }
     67 
     68     fn init(
     69         _: Self::Init,
     70         root: &Self::Root,
     71         sender: ComponentSender<Self>,
     72     ) -> ComponentParts<Self> {
     73         // TODO: Check if we are logged in and if not go to login
     74         // FIXME: Remove Placeholder
     75         let model = App {
     76             active_child: Child::LoginView,
     77             main_view: MainView::builder().launch(()).detach(),
     78             login_view: LoginView::builder()
     79                 .launch(())
     80                 .forward(sender.input_sender(), identity),
     81         };
     82         let widgets = view_output!();
     83         ComponentParts { model, widgets }
     84     }
     85 
     86     fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
     87         match msg {
     88             AppMsg::ToMainView => self.active_child = Child::MainView,
     89         }
     90     }
     91 }
     92 
     93 fn main() -> Result<()> {
     94     color_eyre::install()?;
     95 
     96     // Show traces to find potential performance bottlenecks, for example
     97     tracing_subscriber::fmt()
     98         .with_span_events(tracing_subscriber::fmt::format::FmtSpan::FULL)
     99         .with_max_level(tracing::Level::TRACE)
    100         .init();
    101     tracing::info!("Starting application!");
    102 
    103     // Load app resources
    104     let path = &format!(
    105         "{}/{}/{}.gresource",
    106         config::DATADIR,
    107         config::PKGNAME,
    108         config::APP_ID
    109     );
    110     let res = gio::Resource::load(path).expect("Could not load resources");
    111     gio::resources_register(&res);
    112 
    113     let app = Application::builder()
    114         .application_id("dev.nordgedanken.Email")
    115         .build();
    116     // Connect to signals
    117     app.connect_startup(|_| load_css());
    118     let app = RelmApp::with_app(app);
    119     app.run::<App>(());
    120     Ok(())
    121 }
    122 
    123 fn load_css() {
    124     let provider = gtk::CssProvider::new();
    125     provider.load_from_resource(&format!("{}/style.css", config::PATH_ID));
    126     if let Some(display) = Display::default() {
    127         gtk::StyleContext::add_provider_for_display(
    128             &display,
    129             &provider,
    130             gtk::STYLE_PROVIDER_PRIORITY_APPLICATION,
    131         );
    132     }
    133 }