Flexible routing
Another massive refactor to change the way routing works. Now any column can route anywhere. Also things are generally just much better and more modular via the new struct split borrowing technique. I didn't even try to split this into smaller commits for my sanity. Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
120
src/route.rs
120
src/route.rs
@@ -1,51 +1,107 @@
|
||||
use egui::RichText;
|
||||
use enostr::NoteId;
|
||||
use std::fmt::{self};
|
||||
use strum_macros::Display;
|
||||
|
||||
use crate::ui::{
|
||||
account_login_view::AccountLoginResponse, account_management::AccountManagementViewResponse,
|
||||
use crate::{
|
||||
account_manager::AccountsRoute,
|
||||
timeline::{TimelineId, TimelineRoute},
|
||||
};
|
||||
|
||||
/// App routing. These describe different places you can go inside Notedeck.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||
pub enum Route {
|
||||
Timeline(String),
|
||||
Thread(NoteId),
|
||||
Reply(NoteId),
|
||||
Timeline(TimelineRoute),
|
||||
Accounts(AccountsRoute),
|
||||
Relays,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Display)]
|
||||
pub enum ManageAccountRoute {
|
||||
#[default]
|
||||
AccountManagement,
|
||||
AddAccount,
|
||||
impl Route {
|
||||
pub fn timeline(timeline_id: TimelineId) -> Self {
|
||||
Route::Timeline(TimelineRoute::Timeline(timeline_id))
|
||||
}
|
||||
|
||||
pub fn timeline_id(&self) -> Option<&TimelineId> {
|
||||
if let Route::Timeline(TimelineRoute::Timeline(tid)) = self {
|
||||
Some(tid)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn thread(thread_root: NoteId) -> Self {
|
||||
Route::Timeline(TimelineRoute::Thread(thread_root))
|
||||
}
|
||||
|
||||
pub fn reply(replying_to: NoteId) -> Self {
|
||||
Route::Timeline(TimelineRoute::Reply(replying_to))
|
||||
}
|
||||
|
||||
pub fn accounts() -> Self {
|
||||
Route::Accounts(AccountsRoute::Accounts)
|
||||
}
|
||||
|
||||
pub fn add_account() -> Self {
|
||||
Route::Accounts(AccountsRoute::AddAccount)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add this to egui-nav so we don't have to deal with returning
|
||||
// and navigating headaches
|
||||
#[derive(Clone)]
|
||||
pub struct Router<R: Clone> {
|
||||
routes: Vec<R>,
|
||||
pub returning: bool,
|
||||
pub navigating: bool,
|
||||
}
|
||||
|
||||
impl<R: Clone> Router<R> {
|
||||
pub fn new(routes: Vec<R>) -> Self {
|
||||
if routes.is_empty() {
|
||||
panic!("routes can't be empty")
|
||||
}
|
||||
let returning = false;
|
||||
let navigating = false;
|
||||
Router {
|
||||
routes,
|
||||
returning,
|
||||
navigating,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn route_to(&mut self, route: R) {
|
||||
self.routes.push(route);
|
||||
}
|
||||
|
||||
pub fn go_back(&mut self) -> Option<R> {
|
||||
if self.routes.len() == 1 {
|
||||
return None;
|
||||
}
|
||||
self.routes.pop()
|
||||
}
|
||||
|
||||
pub fn top(&self) -> &R {
|
||||
self.routes.last().expect("routes can't be empty")
|
||||
}
|
||||
|
||||
pub fn routes(&self) -> &Vec<R> {
|
||||
&self.routes
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Route {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Route::Timeline(name) => write!(f, "{}", name),
|
||||
Route::Thread(_id) => write!(f, "Thread"),
|
||||
Route::Reply(_id) => write!(f, "Reply"),
|
||||
Route::Timeline(tlr) => match tlr {
|
||||
TimelineRoute::Timeline(name) => write!(f, "{}", name),
|
||||
TimelineRoute::Thread(_id) => write!(f, "Thread"),
|
||||
TimelineRoute::Reply(_id) => write!(f, "Reply"),
|
||||
},
|
||||
|
||||
Route::Relays => write!(f, "Relays"),
|
||||
|
||||
Route::Accounts(amr) => match amr {
|
||||
AccountsRoute::Accounts => write!(f, "Accounts"),
|
||||
AccountsRoute::AddAccount => write!(f, "Add Account"),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Route {
|
||||
pub fn title(&self) -> RichText {
|
||||
match self {
|
||||
Route::Thread(_) => RichText::new("Thread"),
|
||||
Route::Reply(_) => RichText::new("Reply"),
|
||||
Route::Relays => RichText::new("Relays"),
|
||||
Route::Timeline(_) => RichText::new("Timeline"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ManageAcountRouteResponse {
|
||||
AccountManagement(AccountManagementViewResponse),
|
||||
AddAccount(AccountLoginResponse),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user