Remove pseudo message after server replied
This commit is contained in:
parent
a0b89b3990
commit
cfcc663169
5 changed files with 84 additions and 12 deletions
|
|
@ -36,7 +36,7 @@ enum Event {
|
||||||
Status(oneshot::Sender<Option<Status>>),
|
Status(oneshot::Sender<Option<Status>>),
|
||||||
RequestLogs,
|
RequestLogs,
|
||||||
Nick(String),
|
Nick(String),
|
||||||
Send(Option<Snowflake>, String),
|
Send(Option<Snowflake>, String, oneshot::Sender<Snowflake>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -164,7 +164,7 @@ impl State {
|
||||||
Event::Status(reply_tx) => self.on_status(reply_tx).await,
|
Event::Status(reply_tx) => self.on_status(reply_tx).await,
|
||||||
Event::RequestLogs => self.on_request_logs(),
|
Event::RequestLogs => self.on_request_logs(),
|
||||||
Event::Nick(name) => self.on_nick(name),
|
Event::Nick(name) => self.on_nick(name),
|
||||||
Event::Send(parent, content) => self.on_send(parent, content),
|
Event::Send(parent, content, id_tx) => self.on_send(parent, content, id_tx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -291,11 +291,18 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_send(&self, parent: Option<Snowflake>, content: String) {
|
fn on_send(
|
||||||
|
&self,
|
||||||
|
parent: Option<Snowflake>,
|
||||||
|
content: String,
|
||||||
|
id_tx: oneshot::Sender<Snowflake>,
|
||||||
|
) {
|
||||||
if let Some(conn_tx) = &self.conn_tx {
|
if let Some(conn_tx) = &self.conn_tx {
|
||||||
let conn_tx = conn_tx.clone();
|
let conn_tx = conn_tx.clone();
|
||||||
task::spawn(async move {
|
task::spawn(async move {
|
||||||
let _ = conn_tx.send(Send { content, parent }).await;
|
if let Ok(reply) = conn_tx.send(Send { content, parent }).await {
|
||||||
|
let _ = id_tx.send(reply.0.id);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -348,9 +355,15 @@ impl Room {
|
||||||
.map_err(|_| Error::Stopped)
|
.map_err(|_| Error::Stopped)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(&self, parent: Option<Snowflake>, content: String) -> Result<(), Error> {
|
pub fn send(
|
||||||
|
&self,
|
||||||
|
parent: Option<Snowflake>,
|
||||||
|
content: String,
|
||||||
|
) -> Result<oneshot::Receiver<Snowflake>, Error> {
|
||||||
|
let (id_tx, id_rx) = oneshot::channel();
|
||||||
self.event_tx
|
self.event_tx
|
||||||
.send(Event::Send(parent, content))
|
.send(Event::Send(parent, content, id_tx))
|
||||||
|
.map(|_| id_rx)
|
||||||
.map_err(|_| Error::Stopped)
|
.map_err(|_| Error::Stopped)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,17 @@ impl<M: Msg, S: MsgStore<M>> ChatState<M, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [`Reaction::Composed`] message was sent, either successfully or
|
||||||
|
/// unsuccessfully.
|
||||||
|
///
|
||||||
|
/// If successful, include the message's id as an argument. If unsuccessful,
|
||||||
|
/// instead pass a `None`.
|
||||||
|
pub async fn sent(&mut self, id: Option<M::Id>) {
|
||||||
|
match self.mode {
|
||||||
|
Mode::Tree => self.tree.sent(id).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,20 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sent(&mut self, id: Option<M::Id>) {
|
||||||
|
if let Cursor::Pseudo { coming_from, .. } = &self.cursor {
|
||||||
|
if let Some(id) = id {
|
||||||
|
self.cursor = Cursor::Msg(id);
|
||||||
|
self.editor.clear();
|
||||||
|
} else {
|
||||||
|
self.cursor = match coming_from {
|
||||||
|
Some(id) => Cursor::Msg(id.clone()),
|
||||||
|
None => Cursor::Bottom,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TreeViewState<M: Msg, S: MsgStore<M>>(Arc<Mutex<InnerTreeViewState<M, S>>>);
|
pub struct TreeViewState<M: Msg, S: MsgStore<M>>(Arc<Mutex<InnerTreeViewState<M, S>>>);
|
||||||
|
|
@ -287,6 +301,10 @@ impl<M: Msg, S: MsgStore<M>> TreeViewState<M, S> {
|
||||||
.handle_key_event(terminal, crossterm_lock, event, can_compose)
|
.handle_key_event(terminal, crossterm_lock, event, can_compose)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn sent(&mut self, id: Option<M::Id>) {
|
||||||
|
self.0.lock().await.sent(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ use std::sync::Arc;
|
||||||
use crossterm::event::{KeyCode, KeyEvent};
|
use crossterm::event::{KeyCode, KeyEvent};
|
||||||
use crossterm::style::{Color, ContentStyle, Stylize};
|
use crossterm::style::{Color, ContentStyle, Stylize};
|
||||||
use parking_lot::FairMutex;
|
use parking_lot::FairMutex;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::oneshot::error::TryRecvError;
|
||||||
|
use tokio::sync::{mpsc, oneshot};
|
||||||
use toss::styled::Styled;
|
use toss::styled::Styled;
|
||||||
use toss::terminal::Terminal;
|
use toss::terminal::Terminal;
|
||||||
|
|
||||||
use crate::euph::api::{SessionType, SessionView};
|
use crate::euph::api::{SessionType, SessionView, Snowflake};
|
||||||
use crate::euph::{self, Joined, Status};
|
use crate::euph::{self, Joined, Status};
|
||||||
use crate::vault::EuphVault;
|
use crate::vault::EuphVault;
|
||||||
|
|
||||||
|
|
@ -34,10 +35,13 @@ enum State {
|
||||||
pub struct EuphRoom {
|
pub struct EuphRoom {
|
||||||
ui_event_tx: mpsc::UnboundedSender<UiEvent>,
|
ui_event_tx: mpsc::UnboundedSender<UiEvent>,
|
||||||
|
|
||||||
|
room: Option<euph::Room>,
|
||||||
|
|
||||||
state: State,
|
state: State,
|
||||||
|
|
||||||
room: Option<euph::Room>,
|
|
||||||
chat: ChatState<euph::SmallMessage, EuphVault>,
|
chat: ChatState<euph::SmallMessage, EuphVault>,
|
||||||
|
last_msg_sent: Option<oneshot::Receiver<Snowflake>>,
|
||||||
|
|
||||||
nick_list: ListState<String>,
|
nick_list: ListState<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,9 +49,10 @@ impl EuphRoom {
|
||||||
pub fn new(vault: EuphVault, ui_event_tx: mpsc::UnboundedSender<UiEvent>) -> Self {
|
pub fn new(vault: EuphVault, ui_event_tx: mpsc::UnboundedSender<UiEvent>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ui_event_tx,
|
ui_event_tx,
|
||||||
state: State::Normal,
|
|
||||||
room: None,
|
room: None,
|
||||||
|
state: State::Normal,
|
||||||
chat: ChatState::new(vault),
|
chat: ChatState::new(vault),
|
||||||
|
last_msg_sent: None,
|
||||||
nick_list: ListState::new(),
|
nick_list: ListState::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +90,25 @@ impl EuphRoom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn widget(&self) -> BoxedWidget {
|
async fn stabilize_pseudo_msg(&mut self) {
|
||||||
|
if let Some(id_rx) = &mut self.last_msg_sent {
|
||||||
|
match id_rx.try_recv() {
|
||||||
|
Ok(id) => {
|
||||||
|
self.chat.sent(Some(id)).await;
|
||||||
|
self.last_msg_sent = None;
|
||||||
|
}
|
||||||
|
Err(TryRecvError::Empty) => {} // Wait a bit longer
|
||||||
|
Err(TryRecvError::Closed) => {
|
||||||
|
self.chat.sent(None).await;
|
||||||
|
self.last_msg_sent = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn widget(&mut self) -> BoxedWidget {
|
||||||
|
self.stabilize_pseudo_msg().await;
|
||||||
|
|
||||||
let status = self.status().await;
|
let status = self.status().await;
|
||||||
let chat = match &status {
|
let chat = match &status {
|
||||||
Some(Some(Status::Joined(joined))) => self.widget_with_nick_list(&status, joined),
|
Some(Some(Status::Joined(joined))) => self.widget_with_nick_list(&status, joined),
|
||||||
|
|
@ -295,7 +318,10 @@ impl EuphRoom {
|
||||||
Reaction::NotHandled => {}
|
Reaction::NotHandled => {}
|
||||||
Reaction::Handled => return true,
|
Reaction::Handled => return true,
|
||||||
Reaction::Composed { parent, content } => {
|
Reaction::Composed { parent, content } => {
|
||||||
let _ = room.send(parent, content);
|
match room.send(parent, content) {
|
||||||
|
Ok(id_rx) => self.last_msg_sent = Some(id_rx),
|
||||||
|
Err(_) => self.chat.sent(None).await,
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,10 @@ impl EditorState {
|
||||||
self.0.lock().set_text(text);
|
self.0.lock().set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear(&self) {
|
||||||
|
self.set_text(String::new());
|
||||||
|
}
|
||||||
|
|
||||||
pub fn insert_char(&self, ch: char) {
|
pub fn insert_char(&self, ch: char) {
|
||||||
self.0.lock().insert_char(ch);
|
self.0.lock().insert_char(ch);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue