Show error popups on some server errors

This commit is contained in:
Joscha 2022-08-20 21:06:00 +02:00
parent ab36df3c2b
commit 5d5f55107a
7 changed files with 91 additions and 38 deletions

View file

@ -5,6 +5,7 @@ use std::time::Duration;
use anyhow::bail;
use cookie::{Cookie, CookieJar};
use euphoxide::api::packet::ParsedPacket;
use euphoxide::api::{Data, Log, Nick, Send, Snowflake, Time, UserId};
use euphoxide::conn::{ConnRx, ConnTx, Joining, Status};
use log::{error, info, warn};
@ -28,7 +29,7 @@ pub enum Error {
pub enum EuphRoomEvent {
Connected,
Disconnected,
Data(Box<Data>),
Packet(Box<ParsedPacket>),
}
#[derive(Debug)]
@ -36,7 +37,7 @@ enum Event {
// Events
Connected(ConnTx),
Disconnected,
Data(Box<Data>),
Packet(Box<ParsedPacket>),
// Commands
Status(oneshot::Sender<Option<Status>>),
RequestLogs,
@ -89,8 +90,8 @@ impl State {
info!("e&{}: connected", name);
event_tx.send(Event::Connected(conn_tx))?;
while let Ok(data) = conn_rx.recv().await {
event_tx.send(Event::Data(Box::new(data)))?;
while let Some(packet) = conn_rx.recv().await {
event_tx.send(Event::Packet(Box::new(packet)))?;
}
info!("e&{}: disconnected", name);
@ -170,9 +171,9 @@ impl State {
self.last_msg_id = None;
let _ = euph_room_event_tx.send(EuphRoomEvent::Disconnected);
}
Event::Data(data) => {
self.on_data(&*data).await?;
let _ = euph_room_event_tx.send(EuphRoomEvent::Data(data));
Event::Packet(packet) => {
self.on_packet(&*packet).await?;
let _ = euph_room_event_tx.send(EuphRoomEvent::Packet(packet));
}
Event::Status(reply_tx) => self.on_status(reply_tx).await,
Event::RequestLogs => self.on_request_logs(),
@ -190,7 +191,8 @@ impl State {
})
}
async fn on_data(&mut self, data: &Data) -> anyhow::Result<()> {
async fn on_packet(&mut self, packet: &ParsedPacket) -> anyhow::Result<()> {
let data = ok_or_return!(&packet.content, Ok(()));
match data {
Data::BounceEvent(_) => {}
Data::DisconnectEvent(d) => {

View file

@ -311,7 +311,7 @@ impl Ui {
}
async fn handle_euph_room_event(&mut self, name: String, event: EuphRoomEvent) -> bool {
// TODO Redirect this to the euph room
true
let handled = self.rooms.handle_euph_room_event(name, event);
handled && self.mode == Mode::Main
}
}

View file

@ -4,7 +4,7 @@ use std::sync::Arc;
use crossterm::event::KeyCode;
use crossterm::style::{Color, ContentStyle, Stylize};
use euphoxide::api::{Data, SessionType, SessionView, Snowflake};
use euphoxide::api::{Data, PacketType, SessionType, SessionView, Snowflake};
use euphoxide::conn::{Joined, Status};
use parking_lot::FairMutex;
use tokio::sync::oneshot::error::TryRecvError;
@ -467,4 +467,64 @@ impl EuphRoom {
},
}
}
pub fn handle_euph_room_event(&mut self, event: EuphRoomEvent) -> bool {
match event {
EuphRoomEvent::Connected | EuphRoomEvent::Disconnected => true,
EuphRoomEvent::Packet(packet) => match packet.content {
Ok(data) => self.handle_euph_data(data),
Err(reason) => self.handle_euph_error(packet.r#type, reason),
},
}
}
fn handle_euph_data(&mut self, data: Data) -> bool {
// These packets don't result in any noticeable change in the UI. This
// function's main purpose is to prevent pings from causing a redraw.
#[allow(clippy::match_like_matches_macro)]
match data {
Data::PingEvent(_) | Data::PingReply(_) => {
// Pings are displayed nowhere in the room UI.
false
}
Data::DisconnectEvent(_) => {
// Followed by the server closing the connection, meaning that
// we'll get an `EuphRoomEvent::Disconnected` soon after this.
false
}
_ => true,
}
}
fn handle_euph_error(&mut self, r#type: PacketType, reason: String) -> bool {
let action = match r#type {
PacketType::AuthReply => "authenticate",
PacketType::NickReply => "set nick",
PacketType::PmInitiateReply => "initiate pm",
PacketType::SendReply => "send message",
PacketType::ChangeEmailReply => "change account email",
PacketType::ChangeNameReply => "change account name",
PacketType::ChangePasswordReply => "change account password",
PacketType::LoginReply => "log in",
PacketType::LogoutReply => "log out",
PacketType::RegisterAccountReply => "register account",
PacketType::ResendVerificationEmailReply => "resend verification email",
PacketType::ResetPasswordReply => "reset account password",
PacketType::BanReply => "ban",
PacketType::EditMessageReply => "edit message",
PacketType::GrantAccessReply => "grant room access",
PacketType::GrantManagerReply => "grant manager permissions",
PacketType::RevokeAccessReply => "revoke room access",
PacketType::RevokeManagerReply => "revoke manager permissions",
PacketType::UnbanReply => "unban",
_ => return false,
};
let description = format!("Failed to {action}.");
self.popups.push_front(Popup::ServerError {
description,
reason,
});
true
}
}

View file

@ -11,6 +11,7 @@ use tokio::sync::mpsc;
use toss::styled::Styled;
use toss::terminal::Terminal;
use crate::euph::EuphRoomEvent;
use crate::vault::Vault;
use super::euph::room::EuphRoom;
@ -365,4 +366,16 @@ impl Rooms {
true
}
pub fn handle_euph_room_event(&mut self, name: String, event: EuphRoomEvent) -> bool {
let room_visible = if let State::ShowRoom(n) = &self.state {
*n == name
} else {
true
};
let room = self.get_or_insert_room(name);
let handled = room.handle_euph_room_event(event);
handled && room_visible
}
}