147 lines
4.0 KiB
Rust
147 lines
4.0 KiB
Rust
use eframe::{egui, epi};
|
|
|
|
use crate::{
|
|
matrix::{self, Session},
|
|
sync,
|
|
};
|
|
|
|
pub mod login;
|
|
pub mod session;
|
|
|
|
/// Application state
|
|
#[derive(Debug, Default)]
|
|
pub struct App {
|
|
view: View,
|
|
}
|
|
|
|
impl epi::App for App {
|
|
fn name(&self) -> &str {
|
|
"retrix"
|
|
}
|
|
|
|
fn setup(
|
|
&mut self,
|
|
_ctx: &egui::CtxRef,
|
|
_frame: &epi::Frame,
|
|
storage: Option<&dyn epi::Storage>,
|
|
) {
|
|
let client = match Session::from_fs().and_then(Session::restore) {
|
|
Ok(session) => session,
|
|
_ => return,
|
|
};
|
|
let view = self.view.make_main(client);
|
|
if let Some(storage) = storage {
|
|
storage
|
|
.get_string("rooms")
|
|
.and_then(|s| ron::from_str(&s).ok())
|
|
.map(|list| view.room_list = dbg!(list));
|
|
storage
|
|
.get_string("entry")
|
|
.and_then(|s| ron::from_str(&s).ok())
|
|
.map(|entry| view.entry = entry);
|
|
}
|
|
}
|
|
|
|
fn save(&mut self, storage: &mut dyn epi::Storage) {
|
|
match self.view {
|
|
View::Login(ref login) => {
|
|
if let Ok(login) = ron::to_string(login) {
|
|
storage.set_string("login", login);
|
|
}
|
|
}
|
|
View::Main(ref main) => {
|
|
if let Ok(rooms) = ron::to_string(&main.room_list) {
|
|
storage.set_string("rooms", rooms)
|
|
}
|
|
if let Ok(entry) = ron::to_string(&main.entry) {
|
|
storage.set_string("entry", entry)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn on_exit(&mut self) {
|
|
match self.view {
|
|
View::Main(ref mut main) => {
|
|
main.request.quit();
|
|
main.sync_handle.take().map(|t| t.join());
|
|
}
|
|
_ => (),
|
|
};
|
|
}
|
|
|
|
fn update(&mut self, ctx: &egui::CtxRef, _frame: &epi::Frame) {
|
|
match self.view {
|
|
View::Login(ref mut login) => {
|
|
if login.update(ctx) {
|
|
let client =
|
|
match matrix::login(&login.homeserver, &login.user, &login.password) {
|
|
Ok(client) => client,
|
|
Err(e) => {
|
|
login.error = Some(e.to_string());
|
|
return;
|
|
}
|
|
};
|
|
self.view.make_main(client);
|
|
}
|
|
}
|
|
View::Main(ref mut view) => view.update(ctx),
|
|
};
|
|
}
|
|
}
|
|
|
|
/// Which view is currectly open
|
|
#[derive(Debug)]
|
|
pub enum View {
|
|
Login(login::Login),
|
|
Main(session::App),
|
|
}
|
|
|
|
impl View {
|
|
pub fn make_main(&mut self, client: matrix_sdk::Client) -> &mut session::App {
|
|
let (req_tx, req_rx) = tokio::sync::mpsc::unbounded_channel();
|
|
let (res_tx, res_rx) = crossbeam_channel::bounded(128);
|
|
let client2 = client.clone();
|
|
let handle = std::thread::spawn(move || {
|
|
sync::run(client2, req_rx, res_tx);
|
|
});
|
|
let view = session::App::new(client, req_tx, res_rx, handle);
|
|
for room in view.client.rooms() {
|
|
view.request.room_name(room.room_id().clone());
|
|
}
|
|
|
|
*self = View::Main(view);
|
|
match *self {
|
|
View::Main(ref mut main) => main,
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for View {
|
|
fn default() -> Self {
|
|
View::Login(login::Login::default())
|
|
}
|
|
}
|
|
|
|
/// Named ID's for widgets that need one.
|
|
#[derive(Debug, Clone, Copy, Hash)]
|
|
pub enum Id {
|
|
/// Side panel with the room list.
|
|
RoomPanel,
|
|
/// Top panel with room name an such.
|
|
RoomSummary,
|
|
/// Panel with members of a room.
|
|
MemberList,
|
|
/// Message entry.
|
|
MessageEntry,
|
|
/// Error message.
|
|
ErrorPanel,
|
|
/// Panel showing verification requests.
|
|
VerificationPanel,
|
|
/// Window for a SAS verification session.
|
|
SasVerification,
|
|
/// Window for a QR verification session.
|
|
QrVerification,
|
|
}
|