egui-test/src/ui.rs

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,
}