Skip to content
This repository was archived by the owner on Sep 27, 2024. It is now read-only.

Commit 9d60d40

Browse files
Velin92jonnyandrew
andauthored
get_mentions_state() implemented on the Rust side (only for users and @room) (#849)
* get_mentions_state() implemented and tested * more tests * more tests * Update crates/wysiwyg/src/mentions_state.rs Co-authored-by: jonnyandrew <[email protected]> * added also parsing for the rooms --------- Co-authored-by: jonnyandrew <[email protected]>
1 parent 0663938 commit 9d60d40

File tree

12 files changed

+284
-27
lines changed

12 files changed

+284
-27
lines changed

bindings/wysiwyg-ffi/src/ffi_composer_model.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::ffi_composer_state::ComposerState;
88
use crate::ffi_composer_update::ComposerUpdate;
99
use crate::ffi_dom_creation_error::DomCreationError;
1010
use crate::ffi_link_actions::LinkAction;
11+
use crate::ffi_mentions_state::MentionsState;
1112
use crate::into_ffi::IntoFfi;
1213
use crate::{ActionState, ComposerAction, SuggestionPattern};
1314

@@ -370,6 +371,10 @@ impl ComposerModel {
370371
self.inner.lock().unwrap().get_link_action().into()
371372
}
372373

374+
pub fn get_mentions_state(self: &Arc<Self>) -> MentionsState {
375+
self.inner.lock().unwrap().get_mentions_state().into()
376+
}
377+
373378
/// Force a panic for test purposes
374379
pub fn debug_panic(self: &Arc<Self>) {
375380
#[cfg(debug_assertions)]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#[derive(uniffi::Record)]
2+
pub struct MentionsState {
3+
pub user_ids: Vec<String>,
4+
pub room_ids: Vec<String>,
5+
pub room_aliases: Vec<String>,
6+
pub has_at_room_mention: bool,
7+
}
8+
9+
impl From<wysiwyg::MentionsState> for MentionsState {
10+
fn from(value: wysiwyg::MentionsState) -> Self {
11+
Self {
12+
user_ids: value.user_ids.into_iter().collect(),
13+
room_ids: value.room_ids.into_iter().collect(),
14+
room_aliases: value.room_aliases.into_iter().collect(),
15+
has_at_room_mention: value.has_at_room_mention,
16+
}
17+
}
18+
}

bindings/wysiwyg-ffi/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ mod ffi_composer_state;
2121
mod ffi_composer_update;
2222
mod ffi_dom_creation_error;
2323
mod ffi_link_actions;
24+
mod ffi_mentions_state;
2425
mod ffi_menu_action;
2526
mod ffi_menu_state;
2627
mod ffi_pattern_key;
@@ -38,6 +39,7 @@ pub use crate::ffi_composer_state::ComposerState;
3839
pub use crate::ffi_composer_update::ComposerUpdate;
3940
pub use crate::ffi_dom_creation_error::DomCreationError;
4041
pub use crate::ffi_link_actions::LinkAction;
42+
pub use crate::ffi_mentions_state::MentionsState;
4143
pub use crate::ffi_menu_action::MenuAction;
4244
pub use crate::ffi_menu_state::MenuState;
4345
pub use crate::ffi_pattern_key::PatternKey;

crates/matrix_mentions/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414

1515
mod mention;
1616

17-
pub use crate::mention::{Mention, MentionKind};
17+
pub use crate::mention::{Mention, MentionKind, RoomIdentificationType};

crates/matrix_mentions/src/mention.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,22 @@ pub struct Mention {
2626

2727
#[derive(Clone, Debug, PartialEq, Eq)]
2828
pub enum MentionKind {
29-
Room,
29+
Room(RoomIdentificationType),
3030
User,
3131
}
3232

33+
impl MentionKind {
34+
pub fn is_room(&self) -> bool {
35+
matches!(self, MentionKind::Room(_))
36+
}
37+
}
38+
39+
#[derive(Clone, Debug, PartialEq, Eq)]
40+
pub enum RoomIdentificationType {
41+
Id,
42+
Alias,
43+
}
44+
3345
impl Mention {
3446
fn new(
3547
uri: String,
@@ -134,17 +146,24 @@ impl Mention {
134146
fn from_room(room_uri: &str) -> Option<Mention> {
135147
// In all cases, use the alias/room ID being linked to as the
136148
// anchor’s text.
149+
let room_id_type: RoomIdentificationType;
137150
let text = match parse_matrix_id(room_uri)? {
138-
MatrixId::Room(room_id) => room_id.to_string(),
139-
MatrixId::RoomAlias(room_alias) => room_alias.to_string(),
151+
MatrixId::Room(room_id) => {
152+
room_id_type = RoomIdentificationType::Id;
153+
room_id.to_string()
154+
}
155+
MatrixId::RoomAlias(room_alias) => {
156+
room_id_type = RoomIdentificationType::Alias;
157+
room_alias.to_string()
158+
}
140159
_ => return None,
141160
};
142161

143162
Some(Mention::new(
144163
room_uri.to_string(),
145164
text.clone(),
146165
text,
147-
MentionKind::Room,
166+
MentionKind::Room(room_id_type),
148167
))
149168
}
150169
}
@@ -200,7 +219,7 @@ fn parse_external_id(uri: &str) -> Result<MatrixToUri, IdParseError> {
200219
mod test {
201220
use ruma_common::{MatrixToUri, MatrixUri};
202221

203-
use crate::mention::{Mention, MentionKind};
222+
use crate::mention::{Mention, MentionKind, RoomIdentificationType};
204223

205224
#[test]
206225
fn parse_uri_matrix_to_valid_user() {
@@ -232,7 +251,10 @@ mod test {
232251
assert_eq!(parsed.uri(), uri);
233252
assert_eq!(parsed.mx_id(), "!roomid:example.org");
234253
assert_eq!(parsed.display_text(), "!roomid:example.org");
235-
assert_eq!(parsed.kind(), &MentionKind::Room);
254+
assert_eq!(
255+
parsed.kind(),
256+
&MentionKind::Room(RoomIdentificationType::Id)
257+
);
236258
}
237259

238260
#[test]
@@ -243,7 +265,10 @@ mod test {
243265
assert_eq!(parsed.uri(), uri);
244266
assert_eq!(parsed.mx_id(), "!roomid:example.org");
245267
assert_eq!(parsed.display_text(), "!roomid:example.org");
246-
assert_eq!(parsed.kind(), &MentionKind::Room);
268+
assert_eq!(
269+
parsed.kind(),
270+
&MentionKind::Room(RoomIdentificationType::Id)
271+
);
247272
}
248273

249274
#[test]
@@ -254,7 +279,10 @@ mod test {
254279
assert_eq!(parsed.uri(), uri);
255280
assert_eq!(parsed.mx_id(), "#room:example.org");
256281
assert_eq!(parsed.display_text(), "#room:example.org");
257-
assert_eq!(parsed.kind(), &MentionKind::Room);
282+
assert_eq!(
283+
parsed.kind(),
284+
&MentionKind::Room(RoomIdentificationType::Alias)
285+
);
258286
}
259287

260288
#[test]
@@ -265,7 +293,10 @@ mod test {
265293
assert_eq!(parsed.uri(), uri);
266294
assert_eq!(parsed.mx_id(), "#room:example.org");
267295
assert_eq!(parsed.display_text(), "#room:example.org");
268-
assert_eq!(parsed.kind(), &MentionKind::Room);
296+
assert_eq!(
297+
parsed.kind(),
298+
&MentionKind::Room(RoomIdentificationType::Alias)
299+
);
269300
}
270301

271302
#[test]
@@ -319,7 +350,10 @@ mod test {
319350
assert_eq!(parsed.uri(), uri);
320351
assert_eq!(parsed.mx_id(), "!roomid:example.org");
321352
assert_eq!(parsed.display_text(), "!roomid:example.org");
322-
assert_eq!(parsed.kind(), &MentionKind::Room);
353+
assert_eq!(
354+
parsed.kind(),
355+
&MentionKind::Room(RoomIdentificationType::Id)
356+
);
323357
}
324358

325359
#[test]
@@ -347,7 +381,10 @@ mod test {
347381
assert_eq!(parsed.uri(), uri);
348382
assert_eq!(parsed.mx_id(), "!room:example.org");
349383
assert_eq!(parsed.display_text(), "!room:example.org"); // note the display_text is overridden
350-
assert_eq!(parsed.kind(), &MentionKind::Room);
384+
assert_eq!(
385+
parsed.kind(),
386+
&MentionKind::Room(RoomIdentificationType::Id)
387+
);
351388
}
352389

353390
#[test]
@@ -361,7 +398,10 @@ mod test {
361398
assert_eq!(parsed.uri(), uri);
362399
assert_eq!(parsed.mx_id(), "#room:example.org");
363400
assert_eq!(parsed.display_text(), "#room:example.org"); // note the display_text is overridden
364-
assert_eq!(parsed.kind(), &MentionKind::Room);
401+
assert_eq!(
402+
parsed.kind(),
403+
&MentionKind::Room(RoomIdentificationType::Alias)
404+
);
365405
}
366406

367407
#[test]

crates/wysiwyg/src/composer_model/mentions.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,52 @@
1313
// limitations under the License.
1414

1515
use crate::{
16-
dom::{nodes::MentionNode, DomLocation},
17-
ComposerModel, ComposerUpdate, DomNode, Location, SuggestionPattern,
18-
UnicodeString,
16+
dom::{
17+
nodes::{MentionNode, MentionNodeKind},
18+
DomLocation,
19+
},
20+
ComposerModel, ComposerUpdate, DomNode, Location, MentionsState,
21+
SuggestionPattern, UnicodeString,
1922
};
2023

2124
impl<S> ComposerModel<S>
2225
where
2326
S: UnicodeString,
2427
{
28+
/// Returns the current mentions state of the content of the RTE editor.
29+
pub fn get_mentions_state(&self) -> MentionsState {
30+
let mut mentions_state = MentionsState::default();
31+
for node in self.state.dom.iter_mentions() {
32+
match node.kind() {
33+
MentionNodeKind::AtRoom => {
34+
mentions_state.has_at_room_mention = true
35+
}
36+
MentionNodeKind::MatrixUri { mention } => match mention.kind() {
37+
matrix_mentions::MentionKind::Room(id_type) => {
38+
match id_type {
39+
matrix_mentions::RoomIdentificationType::Id => {
40+
mentions_state
41+
.room_ids
42+
.insert(mention.mx_id().to_string());
43+
}
44+
matrix_mentions::RoomIdentificationType::Alias => {
45+
mentions_state
46+
.room_aliases
47+
.insert(mention.mx_id().to_string());
48+
}
49+
}
50+
}
51+
matrix_mentions::MentionKind::User => {
52+
mentions_state
53+
.user_ids
54+
.insert(mention.mx_id().to_string());
55+
}
56+
},
57+
}
58+
}
59+
mentions_state
60+
}
61+
2562
/// Checks to see if the mention should be inserted and also if the mention can be created.
2663
/// If both of these checks are passed it will remove the suggestion and then insert a mention.
2764
pub fn insert_mention_at_suggestion(

crates/wysiwyg/src/dom/iter.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::{DomHandle, DomNode, UnicodeString};
2323
use std::collections::HashSet;
2424

2525
use super::{
26-
nodes::{ContainerNode, TextNode},
26+
nodes::{ContainerNode, MentionNode, TextNode},
2727
Dom,
2828
};
2929

@@ -48,6 +48,12 @@ where
4848
self.iter().filter_map(DomNode::as_container)
4949
}
5050

51+
/// Returns an iterator over all the mention nodes of this DOM, in depth-first
52+
/// order
53+
pub fn iter_mentions(&self) -> impl Iterator<Item = &MentionNode<S>> {
54+
self.iter().filter_map(DomNode::as_mention)
55+
}
56+
5157
/// Return an iterator over all nodes of the DOM from the passed node,
5258
/// depth-first order (including self).
5359
pub fn iter_from<'a>(&'a self, node: &'a DomNode<S>) -> DomNodeIterator<S> {

crates/wysiwyg/src/dom/nodes/dom_node.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,14 @@ where
245245
}
246246
}
247247

248+
pub(crate) fn as_mention(&self) -> Option<&MentionNode<S>> {
249+
if let Self::Mention(v) = self {
250+
Some(v)
251+
} else {
252+
None
253+
}
254+
}
255+
248256
pub fn kind(&self) -> DomNodeKind {
249257
match self {
250258
DomNode::Text(_) => DomNodeKind::Text,

crates/wysiwyg/src/dom/nodes/mention_node.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ impl<S: UnicodeString> MentionNode<S> {
165165
// this is now only required for us to attach a custom style attribute for web
166166
let mut attrs = self.attributes.clone();
167167
let data_mention_type = match mention.kind() {
168-
MentionKind::Room => "room",
168+
MentionKind::Room(_) => "room",
169169
MentionKind::User => "user",
170170
};
171171
attrs.push((
@@ -177,12 +177,11 @@ impl<S: UnicodeString> MentionNode<S> {
177177
attrs
178178
};
179179

180-
let display_text =
181-
if as_message && mention.kind() == &MentionKind::Room {
182-
S::from(mention.mx_id())
183-
} else {
184-
self.display_text()
185-
};
180+
let display_text = if as_message && mention.kind().is_room() {
181+
S::from(mention.mx_id())
182+
} else {
183+
self.display_text()
184+
};
186185

187186
self.fmt_tag_open(tag, formatter, &Some(attributes));
188187
formatter.push(display_text);
@@ -286,7 +285,7 @@ where
286285
// For a mention in a message, display the `mx_id` for a room mention, `display_text` otherwise
287286
let text = match this.kind() {
288287
MentionNodeKind::MatrixUri { mention }
289-
if mention.kind() == &MentionKind::Room =>
288+
if mention.kind().is_room() =>
290289
{
291290
S::from(mention.mx_id())
292291
}
@@ -305,7 +304,7 @@ where
305304
match this.kind() {
306305
MentionNodeKind::MatrixUri { mention } => {
307306
data_mention_type = match mention.kind() {
308-
MentionKind::Room => "room",
307+
MentionKind::Room(_) => "room",
309308
MentionKind::User => "user",
310309
};
311310
href = mention.uri();

crates/wysiwyg/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ mod format_type;
2323
mod link_action;
2424
mod list_type;
2525
mod location;
26+
mod mentions_state;
2627
mod menu_action;
2728
mod menu_state;
2829
mod pattern_key;
@@ -51,6 +52,7 @@ pub use crate::link_action::LinkAction;
5152
pub use crate::link_action::LinkActionUpdate;
5253
pub use crate::list_type::ListType;
5354
pub use crate::location::Location;
55+
pub use crate::mentions_state::MentionsState;
5456
pub use crate::menu_action::MenuAction;
5557
pub use crate::menu_action::MenuActionSuggestion;
5658
pub use crate::menu_state::MenuState;

0 commit comments

Comments
 (0)