send-receive-message #36

Merged
flaxeneel2 merged 59 commits from send-receive-message into master 2026-08-21 01:33:00 +02:00
Owner

yes yes i know this PR is freaking huge.

Changes made by this PR:

  • Space resolution reworked.
    • Spaces are now no longer a flat map. Space hierarchies now represented by nested SpaceNodes.
    • Spaces are now returned as a BTreeMap
      • This will be replaced when issue #33 is implemented
    • Now only actual spaces are returned for the server list. Rooms are not returned for now
    • Autoselect first room on opening space
  • Receiving of messages is now shown in UI
    • Earlier receive message event fired nothing other than just a debug log, now it shows up in the UI.
    • Currently, it only supports plain text and not html/markdown (proposed solution in issue #34 )
    • Fixed timestamps to follow local timezone.
    • Introduce a unified state for rooms that handles all edits, redactions and incoming messages.
    • Add edited flag for edited messages (to render a (edited) tag for messages that have been edited)
    • Autoscroll on new messages
    • Resolve user ids to the user's displayname/nickname for that room
  • Sending messages
    • Users can now send messages from the UI.
    • This currently does not support attachments for now.
    • This also currently only supports plain text. ( See Issue #34 )
    • Grey out unsent messages
  • Handling incoming attachments
    • Added a fetching + lightbox for images
    • Implemented an LRU cache to evict older attachments when the cap is hit
    • Added download buttons for attachments (in lightbox for image and in the attachment card for unsupported attachments)
      • Videos are currently unsupported, see issue #35
    • Added a decode limit to prevent the client from attempting to decode huge payloads.
    • Seperate branch for image preview vs full image so the client does not attempt loading full images as the user is scrolling past, but still allowing the user to see the original quality (if the decode limit allows) by opening the image in the lightbox
  • UI changes
    • New states for messages/attachments/toasts
    • Message list, lightbox and attachments UI.
    • Download attachment button now opens a dialogue requesting the user for a place to store the file (using rfd)
    • Switched from ScrollView to ListView for the messages view as ListView provided better control for me for pagination
    • Added a debug menu with all the current commands for easier debugging
  • Misc
    • deprecated and then removed with_active_client() call since it would cause lifetime issues with async closures.
    • License entry added for the download SVG.
    • Applied some of the clippy fixes
    • Added heaptrack for memory profiling
    • Reword how client_events are handled
    • Smaller changes to app_state for how the state of the app is handled.
    • Added a small (hopeful) extension suggestion for files that the user is trying to save. It will look at the mimetype and add an extension based on that if the file does not already have an extension.

This PR is massive. There was a lot of scope creep. I did not realize just how much I would need to rework for spaces to actually make this functional.

As a result of all the ongoing changes. The lib.rs has grown massively. I think the next thing to do would need to be decouple all the UI glue from lib.rs and split it into its own module.

Good luck in reviewing this, I do not envy you.

yes yes i know this PR is freaking huge. Changes made by this PR: - Space resolution reworked. - Spaces are now no longer a flat map. Space hierarchies now represented by nested `SpaceNode`s. - Spaces are now returned as a `BTreeMap` - This will be replaced when issue https://git.flaxeneel2.net/streigen/echelon/issues/33 is implemented - Now only actual spaces are returned for the server list. Rooms are not returned for now - Autoselect first room on opening space - Receiving of messages is now shown in UI - Earlier receive message event fired nothing other than just a debug log, now it shows up in the UI. - Currently, it only supports plain text and not html/markdown (proposed solution in issue https://git.flaxeneel2.net/streigen/echelon/issues/34 ) - Fixed timestamps to follow local timezone. - Introduce a unified state for rooms that handles all edits, redactions and incoming messages. - Add edited flag for edited messages (to render a `(edited)` tag for messages that have been edited) - Autoscroll on new messages - Resolve user ids to the user's displayname/nickname for that room - Sending messages - Users can now send messages from the UI. - This currently does not support attachments for now. - This also currently only supports plain text. ( See Issue https://git.flaxeneel2.net/streigen/echelon/issues/34 ) - Grey out unsent messages - Handling incoming attachments - Added a fetching + lightbox for images - Implemented an LRU cache to evict older attachments when the cap is hit - Added download buttons for attachments (in lightbox for image and in the attachment card for unsupported attachments) - Videos are currently unsupported, see issue https://git.flaxeneel2.net/streigen/echelon/issues/35 - Added a decode limit to prevent the client from attempting to decode huge payloads. - Seperate branch for image preview vs full image so the client does not attempt loading full images as the user is scrolling past, but still allowing the user to see the original quality (if the decode limit allows) by opening the image in the lightbox - UI changes - New states for messages/attachments/toasts - Message list, lightbox and attachments UI. - Download attachment button now opens a dialogue requesting the user for a place to store the file (using [rfd](https://docs.rs/rfd/)) - Switched from `ScrollView` to `ListView` for the messages view as `ListView` provided better control for me for pagination - Added a debug menu with all the current commands for easier debugging - Misc - deprecated and then removed `with_active_client()` call since it would cause lifetime issues with async closures. - License entry added for the download SVG. - Applied some of the clippy fixes - Added heaptrack for memory profiling - Reword how client_events are handled - Smaller changes to app_state for how the state of the app is handled. - Added a small (hopeful) extension suggestion for files that the user is trying to save. It will look at the mimetype and add an extension based on that if the file does not already have an extension. This PR is massive. There was a lot of scope creep. I did not realize just how much I would need to rework for spaces to actually make this functional. As a result of all the ongoing changes. The `lib.rs` has grown massively. I think the next thing to do would need to be decouple all the UI glue from `lib.rs` and split it into its own module. Good luck in reviewing this, I do not envy you.
make it autoselect first room when opening a space (will change it to remember last opened room later). added autoscroll on new messages too
Some checks failed
build-test / build-windows (push) Successful in 3m19s
build-test / build-linux (push) Successful in 3m0s
build-test / build-android (push) Failing after 1m55s
7bc59d40dd
fix android build
All checks were successful
build-test / build-windows (push) Successful in 3m21s
build-test / build-linux (push) Successful in 3m1s
build-test / build-android (push) Successful in 4m39s
00429a9a2b
fix timestamps being bound to UTC ; fix scrolling not loading more messages
All checks were successful
build-test / build-windows (push) Successful in 3m22s
build-test / build-linux (push) Successful in 3m3s
build-test / build-android (push) Successful in 4m38s
945fd313b7
add lru to evict oldest attachments from attachment cache
All checks were successful
build-test / build-windows (push) Successful in 3m45s
build-test / build-linux (push) Successful in 3m1s
build-test / build-android (push) Successful in 5m7s
3db8b3bec8
switch to single attachment per message
All checks were successful
build-test / build-windows (push) Successful in 3m21s
build-test / build-linux (push) Successful in 3m8s
build-test / build-android (push) Successful in 4m41s
26721d0aa6
fix download button positioning
All checks were successful
build-test / build-windows (push) Successful in 3m20s
build-test / build-linux (push) Successful in 3m7s
build-test / build-android (push) Successful in 4m45s
22f255b55c
use displaynames in chat for users
All checks were successful
build-test / build-windows (push) Successful in 3m21s
build-test / build-linux (push) Successful in 2m59s
build-test / build-android (push) Successful in 4m38s
b2e7ddf748
remove mimalloc since base did better
Some checks failed
build-test / build-linux (push) Has been cancelled
build-test / build-android (push) Has been cancelled
build-test / build-windows (push) Has been cancelled
5a26ac7684
remove mimalloc since base did better
All checks were successful
build-test / build-windows (push) Successful in 7m4s
build-test / build-linux (push) Successful in 5m43s
build-test / build-android (push) Successful in 9m0s
a76df79074
resolve nicknames properly and grey unsent messages
All checks were successful
build-test / build-windows (push) Successful in 6m53s
build-test / build-linux (push) Successful in 5m51s
build-test / build-android (push) Successful in 9m6s
284a280a71
use Arc<str> instead of OwnedUserIds for chat view
All checks were successful
build-test / build-windows (push) Successful in 7m12s
build-test / build-linux (push) Successful in 5m57s
build-test / build-android (push) Successful in 8m54s
793b88404c
get rid of deprecated with_active_client closure function
All checks were successful
build-test / build-windows (push) Successful in 6m40s
build-test / build-linux (push) Successful in 5m43s
build-test / build-android (push) Successful in 8m58s
c41e9af22e
fix scroll
All checks were successful
build-test / build-windows (push) Successful in 3m25s
build-test / build-linux (push) Successful in 3m0s
build-test / build-android (push) Successful in 4m40s
bfa6fc023a
change store shape ; add list_accounts debug cmd ; add auto resolution of homeserver based on user id + .well-known
All checks were successful
build-test / build-windows (push) Successful in 3m24s
build-test / build-linux (push) Successful in 3m1s
build-test / build-android (push) Successful in 4m41s
acd1e7fa51
shorten/remove more comments that were unnecessary
All checks were successful
build-test / build-windows (push) Successful in 3m24s
build-test / build-linux (push) Successful in 2m59s
build-test / build-android (push) Successful in 4m40s
ba0b96a4a6
message store now deleted ; slint MESSAGES is now source of truth
All checks were successful
build-test / build-windows (push) Successful in 3m24s
build-test / build-linux (push) Successful in 3m2s
build-test / build-android (push) Successful in 4m41s
f9ff42889b
comment cleanup
All checks were successful
build-test / build-windows (push) Successful in 3m25s
build-test / build-linux (push) Successful in 3m1s
build-test / build-android (push) Successful in 4m42s
11088f9b5a
add license for download svg
All checks were successful
build-test / build-windows (push) Successful in 3m20s
build-test / build-linux (push) Successful in 3m0s
build-test / build-android (push) Successful in 4m41s
build-test / build-windows (pull_request) Successful in 3m23s
build-test / build-linux (pull_request) Successful in 3m3s
build-test / build-android (pull_request) Successful in 4m39s
d295791113
rayyan requested review from rayyan 2026-08-20 02:48:51 +02:00
rayyan requested changes 2026-08-20 18:55:15 +02:00
Dismissed
rayyan left a comment

Thank you for torturing me. Do not fix the issues, everything else should be relatively simple to fix.

Thank you for torturing me. Do not fix the issues, everything else should be relatively simple to fix.
Cargo.toml Outdated
@ -33,10 +34,13 @@ futures-core = "0.3.31"
blake3 = "1.8.3"
url = "2"
open = "5"
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
Owner

I would advise against using chrono, we can use jiff, see more here:

https://github.com/chronotope/chrono/issues/1768

I would advise against using chrono, we can use jiff, see more here: https://github.com/chronotope/chrono/issues/1768
Author
Owner

oops i forgot i wasnt supposed to fix ones with issues. resolved

oops i forgot i wasnt supposed to fix ones with issues. resolved
flaxeneel2 marked this conversation as resolved
Cargo.toml Outdated
@ -71,1 +75,4 @@
[profile.release]
debug = true
Owner

remove 77 and 78

remove 77 and 78
flaxeneel2 marked this conversation as resolved
@ -0,0 +82,4 @@
let bytes = client
.media()
.get_media_content(&request, true)
Owner

We have discussed this already, but just wanted to document it here, opened an issue about it too:
#37

We have discussed this already, but just wanted to document it here, opened an issue about it too: #37
Author
Owner

as there is already an issue for it. ill mark this as resolved

as there is already an issue for it. ill mark this as resolved
flaxeneel2 marked this conversation as resolved
@ -0,0 +110,4 @@
format!("Attachment is {bytes} bytes, over the {limit} byte limit")
}
/// Download an attachment's original bytes, undecoded. Used for saving to disk, where the file
Owner

undecoded? 😭

You can just say download an attachment's raw bytes.

undecoded? 😭 You can just say download an attachment's raw bytes.
Author
Owner

undecoded -> coded. yesyes.

fr tho ima just rename it to RAW instead

undecoded -> coded. yesyes. fr tho ima just rename it to RAW instead
flaxeneel2 marked this conversation as resolved
@ -0,0 +368,4 @@
"audio/opus" => "opus",
"audio/wav" | "audio/x-wav" => "wav",
"audio/flac" | "audio/x-flac" => "flac",
"audio/mp4" | "audio/aac" => "m4a",
Owner

Why are we converting mp4 or aac to m4a again? It would make sense to just have:

"audio/aac" => "aac",
Why are we converting mp4 or aac to m4a again? It would make sense to just have: ```rust "audio/aac" => "aac", ```
flaxeneel2 marked this conversation as resolved
@ -103,2 +66,2 @@
Ok(root_map)
}
let mut hierarchy = Vec::new();
let mut visited = HashSet::new();
Owner

Also, small bug where if a room is nested inside two root spaces, it will only appear inside the space that is processed first, it gets skipped in the other space since it's already inside visited.

Also, small bug where if a room is nested inside two root spaces, it will only appear inside the space that is processed first, it gets skipped in the other space since it's already inside visited.
flaxeneel2 marked this conversation as resolved
@ -133,3 +69,1 @@
};
if !room.is_space() {
return Err("Given space ID does not correspond to a space room".to_string());
for root_id in roots {
Owner

See #38, will implement in next PR when I do QOL

See #38, will implement in next PR when I do QOL
Author
Owner

marking as resolved for now since this has an issue dedicated to it

marking as resolved for now since this has an issue dedicated to it
flaxeneel2 marked this conversation as resolved
src/lib.rs Outdated
@ -45,0 +275,4 @@
const MESSAGE_PAGE: u32 = 50;
/// Maximum number of message rows held in the UI model.
const MAX_MESSAGE_ROWS: usize = MESSAGE_PAGE as usize * 20;
Owner

maybe make this 2...
😍

maybe make this 2... 😍
Author
Owner

how about.... 10?

how about.... 10?
Author
Owner

set to 10 for now since max previews caps image previews to 24. the rest of the rows arent that expensive memory wise

set to 10 for now since max previews caps image previews to 24. the rest of the rows arent that expensive memory wise
flaxeneel2 marked this conversation as resolved
@ -45,0 +285,4 @@
return;
}
let mut dropped = Vec::with_capacity(overflow);
Owner

Make this a hashset, for better efficiency.

Make this a hashset, for better efficiency.
Author
Owner

your wish is my command sire

your wish is my command sire
flaxeneel2 marked this conversation as resolved
@ -0,0 +43,4 @@
/// A media attachment, carrying just enough to fetch and render it later.
/// One shape covers every kind, so a new kind needs no new field here.
#[derive(Debug, Clone)]
pub struct Attachment {
Owner

Comments for this struct are a bit too descriptive, shorten them down a little, some of the information is useful, but we would benefit from not having comments be too large.

Comments for this struct are a *bit* too descriptive, shorten them down a little, some of the information is useful, but we would benefit from not having comments be *too* large.
Author
Owner

yessir fixed

yessir fixed
flaxeneel2 marked this conversation as resolved
@ -0,0 +90,4 @@
/// Pick the source that answers a request at `size`.
///
/// The one definition of which of an attachment's two sources is used and
/// what it weighs. Both the fetch that pulls the bytes down and the check
Owner

???

Like this...?

image

Make the comments a bit clearer, and shorter, thanks!

??? Like this...? ![image](/attachments/989f2e84-44ba-4f62-98f7-02d6803ad783) Make the comments a bit clearer, and shorter, thanks!
564 KiB
Author
Owner

exactly this. i did wanna start hitting the gym soon.

exactly this. i did wanna start hitting the gym soon.
Author
Owner

what better way to start than by using my chat attachments as weights? i mean, surely thousands of attachments will surely be enough to function as weights right?

what better way to start than by using my chat attachments as weights? i mean, surely thousands of attachments will surely be enough to function as weights right?
flaxeneel2 marked this conversation as resolved
@ -0,0 +260,4 @@
/// redaction is, and each applies the answer to the message model itself
/// rather than to a copy of it.
#[derive(Debug, Clone)]
pub enum EventEffect {
Owner

Found a bug here, for SOME REASON, on some clients if you edit a media payload (WHY CAN YOU DO THIS????), it needs to be redacted and have the new media replace it. For example fluffychat lets you replace it with text, instead of more media, but Matrix does technically allow you to replace media with other media.

Found a bug here, for SOME REASON, on some clients if you edit a media payload (WHY CAN YOU DO THIS????), it needs to be redacted and have the new media replace it. For example fluffychat lets you replace it with text, instead of more media, but Matrix does technically allow you to replace media with other media.
Author
Owner

...why

...why
Author
Owner

welp fixed

welp fixed
flaxeneel2 marked this conversation as resolved
@ -161,2 +215,4 @@
}
}
#[cfg(test)]
Owner

Remove the tests from here

Remove the tests from here
flaxeneel2 marked this conversation as resolved
@ -3,18 +3,137 @@
// eliminating deep two-way binding chains that cause
// "long callback/instantiation chain" warnings.
// Mirrors `rooms::messages::AttachmentKind`, converted in lib.rs, plus
Owner

not again, pleaaaseeee reduce your UI comments, they are SO LONG.

not again, pleaaaseeee reduce your UI comments, they are SO LONG.
Author
Owner

hehe suffer

hehe suffer
flaxeneel2 marked this conversation as resolved
@ -8,12 +8,175 @@ import { MessageRow } from "./message-row.slint";
export component ChatMain inherits Rectangle {
background: #000000;
// How close to the bottom (in px, roughly 5 message rows) counts as "still
Owner

MY EYES, PLEASE REDUCE THE COMMENTS ;-; .

MY EYES, PLEASE REDUCE THE COMMENTS ;-; .
flaxeneel2 marked this conversation as resolved
@ -67,3 +96,3 @@
}
Text { text: msg.text; color: rgba(255, 255, 255, 0.85); font-size: 15px; wrap: word-wrap; }
// The body and the "(edited)" marker sit in one row so the marker trails
Owner

Please reduce comment size length, my eyes, they burn.

Please reduce comment size length, my eyes, they burn.
flaxeneel2 marked this conversation as resolved
Owner

One more thing I forgot to mention @flaxeneel2, bump up the version number too, we can discuss what we want to bump it to as well if needed.

One more thing I forgot to mention @flaxeneel2, bump up the version number too, we can discuss what we want to bump it to as well if needed.
shorten UI comments
Some checks failed
build-test / build-linux (push) Has been cancelled
build-test / build-android (push) Has been cancelled
build-test / build-windows (push) Has been cancelled
build-test / build-windows (pull_request) Has been cancelled
build-test / build-linux (pull_request) Has been cancelled
build-test / build-android (pull_request) Has been cancelled
f53c7630fb
Bump version number
All checks were successful
build-test / build-windows (push) Successful in 3m29s
build-test / build-android (push) Successful in 4m44s
build-test / build-linux (pull_request) Successful in 3m1s
build-test / build-android (pull_request) Successful in 4m42s
build-test / build-linux (push) Successful in 3m3s
build-test / build-windows (pull_request) Successful in 3m28s
b4c1240c96
Author
Owner

@rayyan wrote in #36 (comment):

One more thing I forgot to mention @flaxeneel2, bump up the version number too, we can discuss what we want to bump it to as well if needed.

Yep. bumped to 0.1.1 (was 0.1.0).

I have gone through all the suggested changes and have made them. Pls lmk if anything else still needs changing.

@rayyan wrote in https://git.flaxeneel2.net/streigen/echelon/pulls/36#issuecomment-170: > One more thing I forgot to mention @flaxeneel2, bump up the version number too, we can discuss what we want to bump it to as well if needed. Yep. bumped to `0.1.1` (was `0.1.0`). I have gone through all the suggested changes and have made them. Pls lmk if anything else still needs changing.
Bump version number to 0.1.5 and fmt
All checks were successful
build-test / build-windows (push) Successful in 3m29s
build-test / build-linux (push) Successful in 3m1s
build-test / build-android (push) Successful in 4m45s
build-test / build-linux (pull_request) Successful in 3m2s
build-test / build-windows (pull_request) Successful in 3m27s
build-test / build-android (pull_request) Successful in 4m43s
0e865230e8
Owner

Alright looks good, merge after all checks pass.

Alright looks good, merge after all checks pass.
rayyan approved these changes 2026-08-21 01:16:56 +02:00
Author
Owner

@rayyan wrote in #36 (comment):

Alright looks good, merge after all checks pass.

nvm tenor gifs dont work. sad. <insert happy cat here>

@rayyan wrote in https://git.flaxeneel2.net/streigen/echelon/pulls/36#issuecomment-188: > Alright looks good, merge after all checks pass. nvm tenor gifs dont work. sad. \<insert happy cat here\>
flaxeneel2 deleted branch send-receive-message 2026-08-21 01:33:00 +02:00
Sign in to join this conversation.
No description provided.