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

Integrate mention parsing #719

Merged
merged 56 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
df6b832
add new mention node types
Jun 13, 2023
93c97c8
add TODOs to clear match errors
Jun 13, 2023
1e2b95f
bit more type manipulation
Jun 13, 2023
437feee
handle invalid URIs early in `insert*` methods
Jun 14, 2023
5fb76eb
move at-room logic check to dom node layer
Jun 14, 2023
64de4f6
export MentionKind
Jun 14, 2023
d60112f
move to `Room` and `User` mention types
Jun 14, 2023
2d2cdad
fix most tests
Jun 14, 2023
6e16114
get all tests passing
Jun 14, 2023
4a56495
make `new` Mention return a `Result`, fix all tests/uses
Jun 14, 2023
3a82ef8
tidy up the logic
Jun 14, 2023
65bfbaf
rename function
Jun 14, 2023
8712fc1
update comment
Jun 14, 2023
8e159f8
update comments, strip out unused code
Jun 14, 2023
8e7c42d
make the message output use mx_id for room mentions
Jun 14, 2023
e0d2f1c
tidy up parsing
Jun 14, 2023
834e5cc
tidy up match branches and functions
Jun 14, 2023
1b0568b
tidy
Jun 14, 2023
1cd484a
fix clippy errors
Jun 14, 2023
d011a5b
fix typo
Jun 14, 2023
d3a0b74
extract `@room` checking/setting
Jun 14, 2023
d2f0edf
add import
Jun 14, 2023
1108eca
add test
Jun 14, 2023
e018d42
try to fix wasm error
Jun 14, 2023
b6d86e6
put import in correct place
Jun 14, 2023
7a6bf6f
get solution for custom links working
Jun 15, 2023
09e6c5d
add test and get it passing
Jun 15, 2023
e28717c
tidy up code
Jun 15, 2023
dde0295
add more tests
Jun 15, 2023
e383123
fix clippy error
Jun 15, 2023
4c08a5f
reinstate removed comment
Jun 15, 2023
a2e3361
separate out user and room in markdown
Jun 15, 2023
cacc965
extract AT_ROOM to constant in other crate
Jun 15, 2023
66ede7e
extract at room utils to matrix mention crate
Jun 15, 2023
6e90343
first hack at splitting at-room behaviour
Jun 15, 2023
38dc7cc
split dom node methods apart
Jun 15, 2023
e46895e
fix broken tests
Jun 15, 2023
554c049
remove unused import
Jun 15, 2023
3720b6c
add special case for example app
Jun 15, 2023
c5802f4
change function call
Jun 15, 2023
c946c94
change function name
Jun 15, 2023
b6b07bd
read new functions across to mobile
Jun 15, 2023
ca571d7
add test
Jun 15, 2023
a1aaf8b
remove unused code
Jun 15, 2023
393d0d9
reduce repeated code
Jun 15, 2023
afd8efb
refactor
Jun 15, 2023
a5f4fd5
redo comments
Jun 15, 2023
4d55895
get all tests passing
Jun 15, 2023
24e03cb
move AT_ROOM back where it belongs
Jun 15, 2023
2b81075
reinstate whitespace
Jun 15, 2023
98bb0f3
correct bindings error, update udl
Jun 15, 2023
c7fc5ec
update comment
Jun 15, 2023
18910a0
add TODOs, fix issues from call
Jun 16, 2023
8417740
add the configuration for the matrix_mentions crate
Jun 16, 2023
4028efc
fix TODO
Jun 16, 2023
46f48cb
address comments
Jun 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions bindings/wysiwyg-ffi/src/ffi_composer_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,25 @@ impl ComposerModel {
))
}

/// Creates an at-room mention node and inserts it into the composer at the current selection
pub fn insert_at_room_mention(
self: &Arc<Self>,
attributes: Vec<Attribute>,
) -> Arc<ComposerUpdate> {
let attrs = attributes
.iter()
.map(|attr| {
(
Utf16String::from_str(&attr.key),
Utf16String::from_str(&attr.value),
)
})
.collect();
Arc::new(ComposerUpdate::from(
self.inner.lock().unwrap().insert_at_room_mention(attrs),
))
}

/// Creates a mention node and inserts it into the composer at the current selection
pub fn insert_mention(
self: &Arc<Self>,
Expand All @@ -281,6 +300,31 @@ impl ComposerModel {
))
}

/// Creates an at-room mention node and inserts it into the composer, replacing the
/// text content defined by the suggestion
pub fn insert_at_room_mention_at_suggestion(
self: &Arc<Self>,
suggestion: SuggestionPattern,
attributes: Vec<Attribute>,
) -> Arc<ComposerUpdate> {
let suggestion = wysiwyg::SuggestionPattern::from(suggestion);
let attrs = attributes
.iter()
.map(|attr| {
(
Utf16String::from_str(&attr.key),
Utf16String::from_str(&attr.value),
)
})
.collect();
Arc::new(ComposerUpdate::from(
self.inner
.lock()
.unwrap()
.insert_at_room_mention_at_suggestion(suggestion, attrs),
))
}

/// Creates a mention node and inserts it into the composer, replacing the
/// text content defined by the suggestion
pub fn insert_mention_at_suggestion(
Expand Down
2 changes: 2 additions & 0 deletions bindings/wysiwyg-ffi/src/wysiwyg_composer.udl
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ interface ComposerModel {
ComposerUpdate set_link(string url, sequence<Attribute> attributes);
ComposerUpdate set_link_with_text(string url, string text, sequence<Attribute> attributes);
ComposerUpdate remove_links();
ComposerUpdate insert_at_room_mention(sequence<Attribute> attributes);
ComposerUpdate insert_mention(string url, string text, sequence<Attribute> attributes);
ComposerUpdate insert_at_room_mention_at_suggestion(SuggestionPattern suggestion, sequence<Attribute> attributes);
ComposerUpdate insert_mention_at_suggestion(string url, string text, SuggestionPattern suggestion, sequence<Attribute> attributes);
ComposerUpdate code_block();
ComposerUpdate quote();
Expand Down
23 changes: 23 additions & 0 deletions bindings/wysiwyg-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,16 @@ impl ComposerModel {
))
}

/// Creates an at-room mention node and inserts it into the composer at the current selection
pub fn insert_at_room_mention(
&mut self,
attributes: js_sys::Map,
) -> ComposerUpdate {
ComposerUpdate::from(
self.inner.insert_at_room_mention(attributes.into_vec()),
)
}

/// Creates a mention node and inserts it into the composer at the current selection
pub fn insert_mention(
&mut self,
Expand All @@ -326,6 +336,19 @@ impl ComposerModel {
))
}

/// Creates an at-room mention node and inserts it into the composer, replacing the
/// text content defined by the suggestion
pub fn insert_at_room_mention_at_suggestion(
&mut self,
suggestion: &SuggestionPattern,
attributes: js_sys::Map,
) -> ComposerUpdate {
ComposerUpdate::from(self.inner.insert_at_room_mention_at_suggestion(
wysiwyg::SuggestionPattern::from(suggestion.clone()),
attributes.into_vec(),
))
}

/// Creates a mention node and inserts it into the composer, replacing the
/// text content defined by the suggestion
pub fn insert_mention_at_suggestion(
Expand Down
6 changes: 5 additions & 1 deletion crates/matrix_mentions/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ name = "matrix_mentions"
version = "0.1.0"
edition = "2021"

[dependencies]
[features]
default = ["custom-matrix-urls"]
custom-matrix-urls = []

[dependencies]
cfg-if = "1.0.0"
ruma-common = "0.11.3"
2 changes: 1 addition & 1 deletion crates/matrix_mentions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@

mod mention;

pub use crate::mention::Mention;
pub use crate::mention::{Mention, MentionKind};
77 changes: 72 additions & 5 deletions crates/matrix_mentions/src/mention.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use ruma_common::{matrix_uri::MatrixId, MatrixToUri, MatrixUri};
use ruma_common::{matrix_uri::MatrixId, IdParseError, MatrixToUri, MatrixUri};

const MATRIX_TO_BASE_URL: &str = "https://matrix.to/#/";

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Mention {
Expand Down Expand Up @@ -59,6 +61,11 @@ impl Mention {
&self.kind
}

/// Determine if a uri is a valid matrix uri
pub fn is_valid_uri(uri: &str) -> bool {
parse_matrix_id(uri).is_some()
}

/// Create a mention from a URI
///
/// If the URI is a valid room or user, it creates a mention using the
Expand Down Expand Up @@ -142,14 +149,51 @@ impl Mention {
}
}

/// Determines if a uri can be parsed for a matrix id. Attempts to treat the uri in three
/// ways when parsing:
/// 1 - As a matrix uri
/// 2 - As a matrix to uri
/// 3 - As a custom uri
///
/// If any of the above succeed, return Some<MatrixIdI. Else return None.
fn parse_matrix_id(uri: &str) -> Option<MatrixId> {
if let Ok(matrix_uri) = MatrixUri::parse(uri) {
Some(matrix_uri.id().to_owned())
return Some(matrix_uri.id().to_owned());
} else if let Ok(matrix_to_uri) = MatrixToUri::parse(uri) {
Some(matrix_to_uri.id().to_owned())
} else {
None
return Some(matrix_to_uri.id().to_owned());
}

cfg_if::cfg_if! {
if #[cfg(any(test, feature = "custom-matrix-urls"))] {
if let Ok(matrix_to_uri) = parse_external_id(uri) {
return Some(matrix_to_uri.id().to_owned());
}
}
}

None
}

/// Attempts to split an external id on `/#/`, rebuild as a matrix to style permalink then parse
/// using ruma.
///
/// Returns the result of calling `parse` in ruma.

#[cfg(any(test, feature = "custom-matrix-urls"))]
fn parse_external_id(uri: &str) -> Result<MatrixToUri, IdParseError> {
// first split the string into the parts we need
let parts: Vec<&str> = uri.split("/#/").collect();

// we expect this to split the uri into exactly two parts, if it's anything else, return early
if parts.len() != 2 {
return Err(IdParseError::Empty);
}
let after_hash = parts[1];

// now rebuild the string as if it were a matrix to type link, then use ruma to parse
let uri_for_ruma = format!("{}{}", MATRIX_TO_BASE_URL, after_hash);

MatrixToUri::parse(&uri_for_ruma)
}

#[cfg(test)]
Expand Down Expand Up @@ -255,6 +299,29 @@ mod test {
assert!(Mention::from_uri("hello").is_none());
}

#[test]
fn parse_uri_external_user() {
let uri = "https://custom.custom.com/?secretstuff/#/@alice:example.org";
let parsed = Mention::from_uri(uri).unwrap();

assert_eq!(parsed.uri(), uri);
assert_eq!(parsed.mx_id(), "@alice:example.org");
assert_eq!(parsed.display_text(), "@alice:example.org");
assert_eq!(parsed.kind(), &MentionKind::User);
}

#[test]
fn parse_uri_external_room() {
let uri =
"https://custom.custom.com/?secretstuff/#/!roomid:example.org";
let parsed = Mention::from_uri(uri).unwrap();

assert_eq!(parsed.uri(), uri);
assert_eq!(parsed.mx_id(), "!roomid:example.org");
assert_eq!(parsed.display_text(), "!roomid:example.org");
assert_eq!(parsed.kind(), &MentionKind::Room);
}

#[test]
fn parse_link_user_text() {
let uri = "https://matrix.to/#/@alice:example.org";
Expand Down
Loading