WIP: feat(tui): update state model from server messages
This commit is contained in:
parent
622e144986
commit
3c4b3db812
7 changed files with 84 additions and 9 deletions
|
@ -12,7 +12,7 @@ keywords = { workspace = true }
|
||||||
categories = { workspace = true }
|
categories = { workspace = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["forgejo", "github"]
|
default = ["forgejo", "github", "tui"]
|
||||||
forgejo = ["git-next-forge-forgejo"]
|
forgejo = ["git-next-forge-forgejo"]
|
||||||
github = ["git-next-forge-github"]
|
github = ["git-next-forge-github"]
|
||||||
tui = ["ratatui"]
|
tui = ["ratatui"]
|
||||||
|
|
|
@ -69,9 +69,9 @@ impl Handler<ReceiveValidAppConfig> for ServerActor {
|
||||||
WebhookActor::new(socket_address, webhook_router.recipient()).start();
|
WebhookActor::new(socket_address, webhook_router.recipient()).start();
|
||||||
self.webhook_actor_addr.replace(webhook_actor_addr);
|
self.webhook_actor_addr.replace(webhook_actor_addr);
|
||||||
let shout = app_config.shout().clone();
|
let shout = app_config.shout().clone();
|
||||||
self.app_config.replace(app_config);
|
self.app_config.replace(app_config.clone());
|
||||||
self.alerts.do_send(UpdateShout::new(shout));
|
self.alerts.do_send(UpdateShout::new(shout));
|
||||||
self.send_server_updates();
|
self.send_server_updates(app_config.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@ message!(Shutdown, "Notification to shutdown the server actor");
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Message)]
|
#[derive(Clone, Debug, PartialEq, Eq, Message)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
||||||
pub enum ServerUpdate {
|
pub enum ServerUpdate {
|
||||||
|
/// List of all configured forges and aliases
|
||||||
|
ForgeRepoList { list: Vec<(ForgeAlias, RepoAlias)> },
|
||||||
/// Status of a repo
|
/// Status of a repo
|
||||||
UpdateRepoSummary {
|
UpdateRepoSummary {
|
||||||
forge_alias: ForgeAlias,
|
forge_alias: ForgeAlias,
|
||||||
|
@ -56,6 +58,22 @@ pub enum ServerUpdate {
|
||||||
Ping,
|
Ping,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<AppConfig> for ServerUpdate {
|
||||||
|
fn from(app_config: AppConfig) -> Self {
|
||||||
|
Self::ForgeRepoList {
|
||||||
|
list: app_config
|
||||||
|
.forges()
|
||||||
|
.flat_map(|(forge_alias, forge_config)| {
|
||||||
|
forge_config
|
||||||
|
.repos()
|
||||||
|
.map(|(repo_alias, _server_repo_config)| (forge_alias.clone(), repo_alias))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
message!(
|
message!(
|
||||||
SubscribeToUpdates,
|
SubscribeToUpdates,
|
||||||
Recipient<ServerUpdate>,
|
Recipient<ServerUpdate>,
|
||||||
|
|
|
@ -243,9 +243,9 @@ impl ServerActor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_server_updates(&self) {
|
fn send_server_updates(&self, server_update: ServerUpdate) {
|
||||||
self.subscribers.iter().for_each(|subscriber| {
|
self.subscribers.iter().for_each(move |subscriber| {
|
||||||
subscriber.do_send(ServerUpdate::Ping);
|
subscriber.do_send(server_update.clone());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,13 @@ use std::time::Instant;
|
||||||
|
|
||||||
use actix::Handler;
|
use actix::Handler;
|
||||||
|
|
||||||
use crate::{server::actor::messages::ServerUpdate, tui::Tui};
|
use crate::{
|
||||||
|
server::actor::messages::ServerUpdate,
|
||||||
|
tui::{
|
||||||
|
actor::model::{ForgeRepoKey, RepoState, State},
|
||||||
|
Tui,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
impl Handler<ServerUpdate> for Tui {
|
impl Handler<ServerUpdate> for Tui {
|
||||||
|
@ -10,16 +16,33 @@ impl Handler<ServerUpdate> for Tui {
|
||||||
|
|
||||||
fn handle(&mut self, msg: ServerUpdate, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: ServerUpdate, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
match msg {
|
match msg {
|
||||||
|
ServerUpdate::ForgeRepoList { list } => {
|
||||||
|
self.state = State::new(
|
||||||
|
list.into_iter()
|
||||||
|
.map(|(forge_alias, repo_alias)| ForgeRepoKey::new(forge_alias, repo_alias))
|
||||||
|
.map(|key| (key, RepoState::Loading))
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
}
|
||||||
ServerUpdate::UpdateRepoSummary {
|
ServerUpdate::UpdateRepoSummary {
|
||||||
forge_alias,
|
forge_alias,
|
||||||
repo_alias,
|
repo_alias,
|
||||||
branches,
|
branches,
|
||||||
log,
|
log,
|
||||||
} => todo!(),
|
} => {
|
||||||
|
self.state.repos().insert(
|
||||||
|
ForgeRepoKey::new(forge_alias, repo_alias),
|
||||||
|
RepoState::Loaded { branches, log },
|
||||||
|
);
|
||||||
|
}
|
||||||
ServerUpdate::RemoveRepo {
|
ServerUpdate::RemoveRepo {
|
||||||
forge_alias,
|
forge_alias,
|
||||||
repo_alias,
|
repo_alias,
|
||||||
} => todo!(),
|
} => {
|
||||||
|
self.state
|
||||||
|
.repos()
|
||||||
|
.remove(&ForgeRepoKey::new(forge_alias, repo_alias));
|
||||||
|
}
|
||||||
ServerUpdate::Ping => {
|
ServerUpdate::Ping => {
|
||||||
self.last_ping = Instant::now();
|
self.last_ping = Instant::now();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//
|
//
|
||||||
mod handlers;
|
mod handlers;
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
|
mod model;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
io::{stderr, Stderr},
|
io::{stderr, Stderr},
|
||||||
|
@ -10,6 +11,7 @@ use std::{
|
||||||
|
|
||||||
use actix::{Actor, Context};
|
use actix::{Actor, Context};
|
||||||
|
|
||||||
|
use model::State;
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
crossterm::{
|
crossterm::{
|
||||||
execute,
|
execute,
|
||||||
|
@ -24,6 +26,7 @@ pub struct Tui {
|
||||||
terminal: Option<Terminal<CrosstermBackend<Stderr>>>,
|
terminal: Option<Terminal<CrosstermBackend<Stderr>>>,
|
||||||
signal_shutdown: Sender<()>,
|
signal_shutdown: Sender<()>,
|
||||||
last_ping: Instant,
|
last_ping: Instant,
|
||||||
|
state: State,
|
||||||
}
|
}
|
||||||
impl Actor for Tui {
|
impl Actor for Tui {
|
||||||
type Context = Context<Self>;
|
type Context = Context<Self>;
|
||||||
|
@ -59,6 +62,7 @@ impl Tui {
|
||||||
terminal: None,
|
terminal: None,
|
||||||
signal_shutdown,
|
signal_shutdown,
|
||||||
last_ping: Instant::now(),
|
last_ping: Instant::now(),
|
||||||
|
state: State::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
30
crates/cli/src/tui/actor/model.rs
Normal file
30
crates/cli/src/tui/actor/model.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
//
|
||||||
|
use git_next_core::{git::graph::Log, ForgeAlias, RepoAlias, RepoBranches};
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use derive_more::derive::Constructor;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, Default, Constructor)]
|
||||||
|
pub struct State {
|
||||||
|
repos: ReposState,
|
||||||
|
}
|
||||||
|
impl State {
|
||||||
|
pub fn repos(&mut self) -> &mut ReposState {
|
||||||
|
&mut self.repos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type ReposState = BTreeMap<ForgeRepoKey, RepoState>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Constructor)]
|
||||||
|
pub struct ForgeRepoKey {
|
||||||
|
forge_alias: ForgeAlias,
|
||||||
|
repo_alias: RepoAlias,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum RepoState {
|
||||||
|
Loading,
|
||||||
|
Loaded { branches: RepoBranches, log: Log },
|
||||||
|
}
|
Loading…
Reference in a new issue