Ring bell when mentioned
This commit is contained in:
parent
496cdde18d
commit
a17630aeaa
6 changed files with 65 additions and 9 deletions
|
|
@ -15,6 +15,10 @@ Procedure when bumping the version number:
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- `bell_on_mention` config option
|
||||
|
||||
## v0.9.1 - 2025-03-01
|
||||
|
||||
### Fixed
|
||||
|
|
|
|||
4
Cargo.lock
generated
4
Cargo.lock
generated
|
|
@ -1646,8 +1646,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toss"
|
||||
version = "0.3.3"
|
||||
source = "git+https://github.com/Garmelon/toss.git?tag=v0.3.3#96b2e13c4a4b0174601d90246d92d148c4230eeb"
|
||||
version = "0.3.4"
|
||||
source = "git+https://github.com/Garmelon/toss.git?tag=v0.3.4#57aa8c59308f6f0aa82bde415a42b56c3d6f7c4d"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"crossterm",
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ features = ["bot"]
|
|||
|
||||
[workspace.dependencies.toss]
|
||||
git = "https://github.com/Garmelon/toss.git"
|
||||
tag = "v0.3.3"
|
||||
tag = "v0.3.4"
|
||||
|
||||
[workspace.dependencies.vault]
|
||||
git = "https://github.com/Garmelon/vault.git"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,10 @@ pub struct Config {
|
|||
#[serde(default)]
|
||||
pub rooms_sort_order: RoomsSortOrder,
|
||||
|
||||
/// Ring the bell (character 0x07) when you are mentioned in a room.
|
||||
#[serde(default)]
|
||||
pub bell_on_mention: bool,
|
||||
|
||||
/// Time zone that chat timestamps should be displayed in.
|
||||
///
|
||||
/// This option can either be the string `"localtime"`, a [POSIX TZ string],
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use cove_config::{Config, Keys};
|
|||
use cove_input::InputEvent;
|
||||
use crossterm::style::Stylize;
|
||||
use euphoxide::{
|
||||
api::{Data, Message, MessageId, PacketType, SessionId},
|
||||
bot::instance::{Event, ServerConfig},
|
||||
api::{Data, Message, MessageId, PacketType, SessionId, packet::ParsedPacket},
|
||||
bot::instance::{ConnSnapshot, Event, ServerConfig},
|
||||
conn::{self, Joined, Joining, SessionInfo},
|
||||
};
|
||||
use jiff::tz::TimeZone;
|
||||
|
|
@ -19,7 +19,7 @@ use toss::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
euph,
|
||||
euph::{self, SpanType},
|
||||
macros::logging_unwrap,
|
||||
ui::{
|
||||
UiError, UiEvent,
|
||||
|
|
@ -73,6 +73,8 @@ pub struct EuphRoom {
|
|||
last_msg_sent: Option<oneshot::Receiver<MessageId>>,
|
||||
|
||||
nick_list: ListState<SessionId>,
|
||||
|
||||
mentioned: bool,
|
||||
}
|
||||
|
||||
impl EuphRoom {
|
||||
|
|
@ -96,6 +98,7 @@ impl EuphRoom {
|
|||
chat: ChatState::new(vault, tz),
|
||||
last_msg_sent: None,
|
||||
nick_list: ListState::new(),
|
||||
mentioned: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -164,6 +167,12 @@ impl EuphRoom {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn retrieve_mentioned(&mut self) -> bool {
|
||||
let mentioned = self.mentioned;
|
||||
self.mentioned = false;
|
||||
mentioned
|
||||
}
|
||||
|
||||
pub async fn unseen_msgs_count(&self) -> usize {
|
||||
logging_unwrap!(self.vault().unseen_msgs_count().await)
|
||||
}
|
||||
|
|
@ -557,6 +566,35 @@ impl EuphRoom {
|
|||
return false;
|
||||
}
|
||||
|
||||
if let Event::Packet(
|
||||
_,
|
||||
ParsedPacket {
|
||||
content: Ok(Data::SendEvent(send)),
|
||||
..
|
||||
},
|
||||
ConnSnapshot {
|
||||
state: conn::State::Joined(joined),
|
||||
..
|
||||
},
|
||||
) = &event
|
||||
{
|
||||
let normalized_name = euphoxide::nick::normalize(&joined.session.name);
|
||||
let content = &*send.0.content;
|
||||
for (rtype, rspan) in euph::find_spans(content) {
|
||||
if rtype != SpanType::Mention {
|
||||
continue;
|
||||
}
|
||||
let Some(mention) = content[rspan].strip_prefix('@') else {
|
||||
continue;
|
||||
};
|
||||
let normalized_mention = euphoxide::nick::normalize(mention);
|
||||
if normalized_name == normalized_mention {
|
||||
self.mentioned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We handle the packet internally first because the room event handling
|
||||
// will consume it while we only need a reference.
|
||||
let handled = if let Event::Packet(_, packet, _) = &event {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use jiff::tz::TimeZone;
|
|||
use tokio::sync::mpsc;
|
||||
use toss::{
|
||||
Style, Styled, Widget, WidgetExt,
|
||||
widgets::{BoxedAsync, Empty, Join2, Text},
|
||||
widgets::{BellState, BoxedAsync, Empty, Join2, Text},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -95,6 +95,7 @@ pub struct Rooms {
|
|||
|
||||
list: ListState<RoomIdentifier>,
|
||||
order: Order,
|
||||
bell: BellState,
|
||||
|
||||
euph_servers: HashMap<String, EuphServer>,
|
||||
euph_rooms: HashMap<RoomIdentifier, EuphRoom>,
|
||||
|
|
@ -115,6 +116,7 @@ impl Rooms {
|
|||
state: State::ShowList,
|
||||
list: ListState::new(),
|
||||
order: Order::from_rooms_sort_order(config.rooms_sort_order),
|
||||
bell: BellState::new(),
|
||||
euph_servers: HashMap::new(),
|
||||
euph_rooms: HashMap::new(),
|
||||
};
|
||||
|
|
@ -244,7 +246,9 @@ impl Rooms {
|
|||
.retain(|n, r| !r.stopped() || rooms_set.contains(n));
|
||||
|
||||
for room in rooms_set {
|
||||
self.get_or_insert_room(room).await.retain();
|
||||
let room = self.get_or_insert_room(room).await;
|
||||
room.retain();
|
||||
self.bell.ring |= room.retrieve_mentioned();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +258,7 @@ impl Rooms {
|
|||
_ => self.stabilize_rooms().await,
|
||||
}
|
||||
|
||||
match &mut self.state {
|
||||
let widget = match &mut self.state {
|
||||
State::ShowList => Self::rooms_widget(
|
||||
&self.vault,
|
||||
self.config,
|
||||
|
|
@ -297,6 +301,12 @@ impl Rooms {
|
|||
.below(delete.widget())
|
||||
.desync()
|
||||
.boxed_async(),
|
||||
};
|
||||
|
||||
if self.config.bell_on_mention {
|
||||
widget.above(self.bell.widget().desync()).boxed_async()
|
||||
} else {
|
||||
widget
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue