[WIP] threads. #74

Draft
Guzio wants to merge 147 commits from Guzio/out-of-your-element:mergable-fr-fr into main
Contributor
  • /thread command is more responsive to context such as replies
  • /thread prints usage if used without commands
  • All threads started are noted as Matrix threads so they can be accessed from the threads menu of supporting clients (but you still have to click the link to go to a thread room)
  • Nags users if they create Matrix threads
- /thread command is more responsive to context such as replies - /thread prints usage if used without commands - All threads started are noted as Matrix threads so they can be accessed from the threads menu of supporting clients (but you still have to click the link to go to a thread room) - Nags users if they create Matrix threads
* The guard() function in m2d/event-dispatcher.js no longer takes (any, any), but a string and a function.

* m2d/send-event.js no longer complains that res.body has some missing fields. It would appear as though those missing fields weren't revelant to the fromWeb() function (into which res.body is passed), given that this code worked before and still contunes to work, so I just @ts-ignore'd res.body

This commit's developer's off-topic personal comment, related to this commit: This has nothing to do with improving thread UX, even tho this is what I was supposed to work on. However, in my attempts to discover in what file should I start, I stumbled upon those errors from m2d/send-event.js, so I fixed them. And after establishing that m2d/event-dispatcher.js is the file that I'm looking for, I also noticed that guard()'s @parm definitions could be improved, so I did that. Now - back to thread work...
* To better reflect reality ("m.in_reply_to" will not always be present - it's not (always?) found on "rel_type":"m.replace" relation-events)

* To support "rel_type":"m.replace" relation-events (added "m.replace" option to existing key "rel_type" and a new "is_falling_back" key)

AFFECTED TYPES: M_Room_Message, M_Room_Message_File, M_Room_Message_Encrypted_File

BREAKS: Nothing, as .d.ts files don't affect buisness logic. In terms of lint errors: Marking "m.in_reply_to" as optional is indeed technically a "breaking change" (TypeScript may complain about „is probably undefined” in places where it didn't before), but from early "testing" (ie. looking at VSCode's errors tab), it doesn't seem like anything broke, as no file that imports any of those 3 types (Or their Outer_ counterparts) has „lit up” with errors (unless I missed something). There was one type error found in m2d/converters/event-to-message.js, at line 1009, but that seemed unrelated to types.d.ts - nevertheless, that error was also corrected in this commit, by adding proper type annotations somewhere else in the affected file.
/This is a squash-commit - the following is a rough summary of all sub-commits, written in style of commit messages (not necessarily those commits themselves), ie. short and in present tense./

* Document design choice to not bridge Discord threads as Matrix threads [by directly quoting Cadence]
* Alter thread-to-announcement, so that it replies in-thread [with this, Matrix users will get a list of almost all (exl. those that don't branch from anything) open threads on a given channel, whereas before it wasn't possible. Also features slight alterations to the text]
* Notify the user, whenever an in-thread message on Matrix is sent, that this isn't how they're supposed to do threads on OOYE
* Detect /thread being ran as a reply or in-thread to branch the thread from the relevant message
* Handle various /thread errors [notably being ran without args (infer the title if ran in the context above, simply show help if not)]
*  Whenever possible, direct the user to an already-existing thread-room [if /thread was ran as a reply or in-thread, or as part of the notification mentioned in point 3 (feat. a new utility method)]

AUXILIARY TYPE CHANGES (not always relevant to UX-improvement-related changes):
* Fix „boolean” being referred to as „bool” in types.d.ts
* Rename execute(event) in matrix-command-handler is now parseAndExecute(event) [and it is no longer of type CommandExecute, but has its own custom definition, because a) it has a different return now (returns what command was ran (needed for point 3 in section above) instead of always undefined and b) other params from CommandExecute (like ctx or words) weren't being used - quite the contrary, their values were only being created at that stage (as part of command parsing - hence the rename, too), so telling that they're values you pass into execute() was at least somewhat confusing]
* Further narrow-down the type of guard() in m2d event-dispatcher

TEST CHANGES:
* Create 7 new tests, all pass
* Update 4 existing threads, all pass
* Pass all other relevant tests [and almost all other tests, too - there are some issues with event2message for stickers, but given the fact that this commit does not touch the stickers subsystem in any way at all,  it does not seem like they are any way related to my changes and they must've been failing before]
* Do extensive manual testing and debugging
Co-authored-by: Guzio <guzekk@protonmail.com>
Co-committed-by: Guzio <guzekk@protonmail.com>
Contributor

@Guzio you can add the WIP: prefix to the PR which auto-flags it as work in progress :)

@Guzio you can add the `WIP: ` prefix to the PR which auto-flags it as work in progress :)
Guzio changed title from feat.: Thread improvements, round 1 to WIP: feat.: Thread improvements, round 1 2026-03-03 00:12:55 +00:00
Author
Contributor

@beanie wrote in #74 (comment):

@Guzio you can add the WIP: prefix to the PR which auto-flags it as work in progress :)

I know - GitDab told me. I just decided it wouldn't be necessary because „surely, I'll finish that message in a few minutes; noone will ever even notice that this was WIP for a short while”.

...Cue-in me returning from uni, taking multiple-hour-long nap, and also taking much longer then anticipated to write the message. 😅

Marked this as WIP for now, will hopefully un-mark it over the course of the next 15 minutes.

@beanie wrote in https://gitdab.com/cadence/out-of-your-element/pulls/74#issuecomment-9082: > @Guzio you can add the `WIP: ` prefix to the PR which auto-flags it as work in progress :) I know - GitDab told me. I just decided it wouldn't be necessary because „surely, I'll finish that message in a few minutes; noone will ever even notice that this was WIP for a short while”. ...Cue-in me returning from uni, taking multiple-hour-long nap, and also taking much longer then anticipated to write the message. 😅 Marked this as WIP for now, will *hopefully* un-mark it over the course of the next 15 minutes.
Guzio changed title from WIP: feat.: Thread improvements, round 1 to feature: Thread improvements, round 1 2026-03-03 12:12:11 +00:00
Author
Contributor

over the course of the next 15 minutes

took a tiny-bit longer than anticipated lol

But I'm done here, yaaayyy! Now awaiting feedback...

> over the course of the next 15 minutes took a tiny-bit longer than anticipated lol But I'm done here, yaaayyy! Now awaiting feedback...
Contributor

I might test this in the next few days, need a solution to bridge a few threads to rooms before Discord accounts expire

I might test this in the next few days, need a solution to bridge a few threads to rooms before Discord accounts expire
Guzio changed title from feature: Thread improvements, round 1 to WIP: feature: Thread improvements, round 1 2026-03-11 10:48:36 +00:00
Author
Contributor

Marked the PR as WIP again, to work on changes proposed in the Matrix discussion.

Marked the PR as WIP again, to work on changes proposed in the Matrix discussion.
At least final-until-we-make-it-so-that-new-rooms-are-autogenerated-when-a-thread-is-opened. Then we'd need to include the link to it instead of a command-help.
It's 23:42; I'm going just purely based on vibes at this point.

vibecoding but no AI, just eepy
Also, that message in thread-to-announcement was misleading, as now there's no guarantee that a thread was newly created (it could be very old, but freshly /thread-ed). So I changed that, too.

Also, while updating messages, I decided to slightly alter the „may not have been bridged to Discord in the way you thought it was gonna be”-warning in event-dispatcher.
In other news: Made /thread work without args (in SOME cases).

I'm pretty sure this is the final patch before we go PR.
So the code-key DOES exist. HuuuHhhhhh???
and yea, ofc it was a string......
As a part of that:
* rewrote the tests to support my changed behaviors
* added a missing case
* Made my „threads get attached to” wording more consistent with the test cases („threads branch from”), as I always felt that there was something off about my phrasing, but I couldn't quite tell what was it. OOYE's „branch” term seems much more fitting there
* slightly cooked the testing data (changed the „Hey.” thread from „floating” to being a branch of a message, to accommodate...)
* 3 NEW TESTS: of the function created in my previous commit (I'm not sure if this *REALLY* needed testing, given how braindead-simple that function is, but everything else in utils.js is covered, so I figured it's only fair to test this, too)

EXTRA CHANGE: fixed that function's name (we're getting the thread from a (Matrix) Event, not a (Discord) Message) and description (I totally didn't copy-paste the JSDoc from above........)
I passed a completely wrong event ID and was confused as to why could it possibly be failing. (Btw, as part od fixing that - my new function from function is utils.js now supports blank values.)

Also - and that's unrelated to the bug I was debugging - I put a guard clause in my if (words.length < 2) backwards. If->return should canonically be above the logic, even if it technically doesn't break said logic in this case (all it was doing was creating an extra step that says „yea, name the newly-created thread /thread, even if this name is very stupid, and also pointless because no thread creation is about to take place”. And while fixing that, I also did some minor changes to error handling.
just a little bit

I like it.

But it's just a little bit annoying.
Reviewed-on: Guzio/out-of-your-element#8
So that I can squash-merge it all without leaving the trace of any extra unsolicited changes
Turns out that auto-create is ALWAYS on for threads (which creates some hilarious situations, where the channel gets duplicated if it ever got unbridged). Also, manual bridging isn't even possible. Uhh... Sure! Let's just say, then, that it's the admin's problem to auto-create it (given the duplication - this is probably a better idea to leave it to them).

A proper fix for this (and also to limit (tho not fix) the dupe-by-autocreate problem) would probably be to allow for manual bridging on threads, but I really don't have time for this before The Merge (my ADHD is kicking-in on this update, and I have a feeling that if I don't PR soon, I'm gonna not do it for another 3 months).
Reviewed-on: Guzio/out-of-your-element#9
of course I did
I was not supposed to do more pulling, but I started seeing some instability and I want to see if it's me or main.
Both sides of creation (M2D and D2M) use ensureRoom() instead of syncRoom() because it's impossible to know which one will fire first, and we wouldn't want a double-sync. At the same time, calling ensureRoom() as a way to CREATE a thread-room is perfectly safe because „Naturally, the newly created room is already up to date, so we can always skip syncing here.” and also thread-rooms aren't subject to manual-mode restrictions, so we can skip all „Does a channel_room entry exists or guild autocreate = 1?” checks (actually, the comment probably should reflect that - so I updated the comments, too.

Also, bridgeThread() is a separate function to make guard clauses possible instead of nesting 3 more layers of IFs like we were fkin YandereDev.
Notably:
* Don't do the unmarshalling and switch-cases, as Cadence asked
* Revert command handler returns to how they were before, now that we're not using the returned-command-name anymore.
* use "" instead of „” to comply with English Language Standards Recommendations On Quotation Marks [TM], as per Cadence's request
* reflect current bot behavior (ie. it no longer bridges-as-replies, but mercilessly rips the message away from your caring arms)
* add Ellie-Mode
I was stripping the ping before because I thought it just pings the thread-author (which I found kinda pointless). But I didn't actually remove the code that figures out who to ping (because I happened to reuse the „if” around it, and didn't remove the setting itself because I didn't pay enough attention to it and just assumed it has some side-effects). I just tried to remove it finally (because my thought was „Wait, WHY are we setting m.mentions only to remove it?”), only to realize that the code does something entirely different (it pings the one under whose message a thread is about to be created, which makes a lot of sense tbh), and actually shouldn't be removed at all and - on the contrary - I should stop removing m.mentions (and also fix Ellie-Mode so that it won't prevent m.mentions from being set even if it's enabled).
I also noticed that my previous wiping code wasn't even doing anything at all. lmfao
Why did I make it this way???

Guzio/out-of-your-element#13
also, switched to working on this branch for now; I think that's the easiest option for the time being
🎵Give up free will forever - their voices won't be heard at all!🎶
🎶Display obedience...🎵

Where was I, again? Ah, right. I'm supposed to make the judgment call (I am the unenlightened masses) ((Someone tries to link their, fkin, smart-bidet smart-home-controller-room to a Stage or something and imma be cooked))
I'm 99% sure I need to do {...channel, flags:(channel.flags^DiscordTypes.ChannelFlags.RequireTag)} but TypeScript won't let me
2 caveats remain (and neither has anything to do with not passing ...channel):
* ugly-error with permissions (fixed)
* no auto-reset (maybe fixed??? - it's either because I DID pass channel (ironic) or because of no await, testing option 1 now)

Also, improved comment consistency
Guzio changed title from WIP: feature: Thread improvements, round 1 to WIP: feature: forums. 2026-04-17 21:41:31 +00:00
Guzio changed title from WIP: feature: forums. to WIP: feature: threads'n'forums 2026-04-17 21:41:49 +00:00
Author
Contributor

I just managed to scope-creep my way into turning this from a „threads QoL” PR to a „forum support (and threads come naturally as part of this, ig)” PR...

I just managed to scope-creep my way into turning this from a „threads QoL” PR to a „forum support (and threads come naturally as part of this, ig)” PR...
Apparently, the context["m.relates_to"] = {"m.in_reply_to": {event_id: event.event_id}} has always been there... The more you know!

I forgot I didn't, apparently, add it myself.

Also, while fixing the regression, I may as well introduce the note to EM, too.
Guzio changed title from WIP: feature: threads'n'forums to WIP: i dont even know what this PR is supposed to be about anymore, everyone lost the plot somewhere in the middle of act 2 2026-04-25 09:55:52 +00:00
Wrong IF xD

This is getting nuked soon, but I still find if funny that I got it wrong.
This code runs in a loop. And it always starts with the root space. So it always finds a space. And it then never clears it out.

Also, it was after the break;, so EVEN IF it somehow reached our room as false, and then was gonna update it to true because it was a space - it now would not have done that because the loop will had been ended.

Fixed by moving the code to where it made any sense.
Author
Contributor

Somehow, Git thinks I rewrote THE ENTIRETY of guild.pug in that last commit. I obviously did NOT do that (only minor changes near the end of the file), nor do I know how and why it arrived at that conclusion. I also don't know how to fix it. :/

Somehow, Git thinks I rewrote THE ENTIRETY of `guild.pug` in that last commit. I obviously did NOT do that (only minor changes near the end of the file), nor do I know how and why it arrived at that conclusion. I also don't know how to fix it. :/
TECHNICALLY, I was asked to remove it. But now that I know that @template is a thing that exists in JSDoc (which was the one missing ingredient the last time), I think I can get this to be good enough that removal won't even be necessary, and now it just looks like regular, sane documentation (not the any-schizopost like last time).
Guzio changed title from WIP: i dont even know what this PR is supposed to be about anymore, everyone lost the plot somewhere in the middle of act 2 to i dont even know what this PR is supposed to be about anymore, everyone lost the plot somewhere in the middle of act 2 2026-04-26 15:24:04 +00:00
Author
Contributor

I can say with 97.8% confidence that this is complete, as far as code goes.

I'll definitely need to write a bit of a description for this, to explain both what this PR actually does at this stage (because it ventured so far beyond its original goal that it's almost comical), as well as to justify certain technical choices made, but the content of the PR is complete.

_I can say with 97.8% confidence that **this is complete**, as far as code goes._ I'll definitely need to write a bit of a description for this, to explain both what this PR *actually does* at this stage (because it ventured so far beyond its original goal that it's almost comical), as well as to justify certain technical choices made, but the content of the PR is complete.
Author
Contributor

I have no idea how come this still haven't been closed for going stale, but I'm glad it wasn't. Anyway... Given how I just reared my ugly head in a discussion on OOYE's Matrix, I suppose I should probably do something about this monstrosity as well, else it's gonna hover over me like a spectre that won't let go (literally the reason why I was dead on OOYE for months (and why I stopped eg. contributing to the Room Gating proposal), was because I kept thinking „Nah, can't let myself be distracted with other OOYE matters; gotta complete this first” and of course that led to me doing neither lol).

I have no idea how come this still haven't been closed for going stale, but I'm glad it wasn't. Anyway... Given how I just reared my ugly head in a discussion on OOYE's Matrix, I suppose I should probably do *something* about this monstrosity as well, else it's gonna hover over me like a spectre that won't let go ~~(literally the reason why I was dead on OOYE for months (and why I stopped eg. contributing to the Room Gating proposal), was because I kept thinking „Nah, can't let myself be distracted with other OOYE matters; gotta complete this first” and of course that led to me doing neither lol)~~.
I mean... The tests pass *almost* fine (the 3 that fail seem unrelated, but I gotta make double-sure), but I'm sure I didn't cover all of my changes with test, soooo...

Anyway, looking forward to getting crucified ny my friends, when the bot inevitably implodes, and spams all over our double-bridged Messenger group again.

SOLVED CONFLICTS WERE:
* src/m2d/event-dispatcher.js (I think we both had the same idea and both added the same thing? Something about retrigger.)
* src/web/pug/guild.pug (the whole file, somehow, but the Conflict Editor on the other hand said that they looked the same, so idk)
*  test/ooye-test-data.sql (we both added a line at the end of the big block of Snowfalke pairs, near line 100)

OTHER CHANGES THAT GOT „AUTO-MERGED” (oh no...):
* src/d2m/actions/create-room.js
* src/d2m/event-dispatcher.js
* src/m2d/actions/send-event.js
* src/m2d/converters/event-to-message.js
* src/matrix/matrix-command-handler.js
* src/matrix/utils.js
* src/types.d.ts
* src/web/routes/guild.js
Guzio changed title from i dont even know what this PR is supposed to be about anymore, everyone lost the plot somewhere in the middle of act 2 to [WIP] threads. 2026-10-12 12:39:28 +00:00
Author
Contributor

I'm getting some failed automated tests, but they seem to also be present upstream (as can be seen by the shell prompt, I'm on [HEAD], and that's the HEAD of the main OOYE, not my fork):

out-of-your-element on  HEAD (a503277) [?] is 📦 v3.7.0 via  v26.10.0 
❯ npm ci --include=dev

added 209 packages, and audited 211 packages in 6s

37 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm warn install-scripts 1 package had install scripts blocked because they are not covered by allowScripts:
npm warn install-scripts   better-sqlite3@13.0.3 (install: node-gyp rebuild)
npm warn install-scripts
npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow.

out-of-your-element on  HEAD (a503277) [?] is 📦 v3.7.0 via  v26.10.0 took 5s 
❯ npm test
npm notice run out-of-your-element@3.7.0 test
npm notice run cross-env FORCE_COLOR=true supertape --no-check-assertions-count --format tap --no-worker test/test.js | tap-dot

..............  ............................................................................................................................................................................................................................................................................................................................................................................................................................................................xxx................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................  


  message2event: irl invite event renders embed - should deep equal
    operator: deepEqual
      diff: |-
        [
          {
            "$type": "m.room.message",
            "body": "https://discord.gg/placeholder?event=1381190945646710824",
            "format": "org.matrix.custom.html",
            "formatted_body": "<a href=\"https://discord.gg/placeholder?event=1381190945646710824\">https://discord.gg/placeholder?event=1381190945646710824</a>",
            "m.mentions": {},
            "msgtype": "m.text",
          },
          {
            "$type": "m.room.message",
      -     "body": "| Scheduled Event - 8 June at 10:00 pm NZT – 9 June at 12:00 am NZT
      +     "body": "| Scheduled Event - 8 June at 10:00 pm NZT – 9 June at 12:00 am NZT
        | ## forest exploration
        | 
        | 📍 the dark forest",
            "format": "org.matrix.custom.html",
      -     "formatted_body": "<blockquote><p>Scheduled Event - 8 June at 10:00 pm NZT – 9 June at 12:00 am NZT</p><strong>forest exploration</strong><p>📍 the dark forest</p></blockquote>",
      +     "formatted_body": "<blockquote><p>Scheduled Event - <a href=\"https://bridge.example.org/time/1749376800/F\">8 June at 10:00 pm NZT – 9 June at 12:00 am NZT</a></p><strong>forest exploration</strong><p>📍 the dark forest</p></blockquote>",
            "m.mentions": {},
            "msgtype": "m.notice",
          },
        ]
    at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1580:4
    Error: should deep equal
      at run (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:271:33)
      at Object.deepEqual (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:206:9)
      at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1580:4
      at async tryToCatch (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/try-to-catch/lib/try-to-catch.js:7:23)
  
  message2event: vc invite event renders embed - should deep equal
    operator: deepEqual
      diff: |-
        [
          {
            "$type": "m.room.message",
            "body": "https://discord.gg/placeholder?event=1381174024801095751",
            "format": "org.matrix.custom.html",
            "formatted_body": "<a href=\"https://discord.gg/placeholder?event=1381174024801095751\">https://discord.gg/placeholder?event=1381174024801095751</a>",
            "m.mentions": {},
            "msgtype": "m.text",
          },
          {
            "$type": "m.room.message",
      -     "body": "| Scheduled Event - 9 June at 3:00 pm NZT
      +     "body": "| Scheduled Event - Monday, 9 June 2025 at 3:00 am (UTC)
        | ## Cooking (Netrunners)
        | Short circuited brain interfaces actually just means your brain is medium rare, yum.
        | 
        | 🔊 Cooking",
            "format": "org.matrix.custom.html",
      -     "formatted_body": "<blockquote><p>Scheduled Event - 9 June at 3:00 pm NZT</p><strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.<p>🔊 Cooking</p></blockquote>",
      +     "formatted_body": "<blockquote><p>Scheduled Event - <a href=\"https://bridge.example.org/time/1749438000/F\">Monday, 9 June 2025 at 3:00 am (UTC)</a></p><strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.<p>🔊 Cooking</p></blockquote>",
            "m.mentions": {},
            "msgtype": "m.notice",
          },
        ]
    at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1613:4
    Error: should deep equal
      at run (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:271:33)
      at Object.deepEqual (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:206:9)
      at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1613:4
      at async tryToCatch (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/try-to-catch/lib/try-to-catch.js:7:23)
  
  message2event: vc invite event renders embed with room link - should deep equal
    operator: deepEqual
      diff: |-
        [
          {
            "$type": "m.room.message",
            "body": "https://discord.gg/placeholder?event=1381174024801095751",
            "format": "org.matrix.custom.html",
            "formatted_body": "<a href=\"https://discord.gg/placeholder?event=1381174024801095751\">https://discord.gg/placeholder?event=1381174024801095751</a>",
            "m.mentions": {},
            "msgtype": "m.text",
          },
          {
            "$type": "m.room.message",
      -     "body": "| Scheduled Event - 9 June at 3:00 pm NZT
      +     "body": "| Scheduled Event - Monday, 9 June 2025 at 3:00 am (UTC)
        | ## Cooking (Netrunners)
        | Short circuited brain interfaces actually just means your brain is medium rare, yum.
        | 
        | 🔊 Hey. - https://matrix.to/#/!FuDZhlOAtqswlyxzeR:cadence.moe?via=cadence.moe",
            "format": "org.matrix.custom.html",
      -     "formatted_body": "<blockquote><p>Scheduled Event - 9 June at 3:00 pm NZT</p><strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.<p>🔊 Hey. - <a href=\"https://matrix.to/#/!FuDZhlOAtqswlyxzeR:cadence.moe?via=cadence.moe\">Hey.</a></p></blockquote>",
      +     "formatted_body": "<blockquote><p>Scheduled Event - <a href=\"https://bridge.example.org/time/1749438000/F\">Monday, 9 June 2025 at 3:00 am (UTC)</a></p><strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.<p>🔊 Hey. - <a href=\"https://matrix.to/#/!FuDZhlOAtqswlyxzeR:cadence.moe?via=cadence.moe\">Hey.</a></p></blockquote>",
            "m.mentions": {},
            "msgtype": "m.notice",
          },
        ]
    at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1655:4
    Error: should deep equal
      at run (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:271:33)
      at Object.deepEqual (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:206:9)
      at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1655:4
      at async tryToCatch (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/try-to-catch/lib/try-to-catch.js:7:23)
  

  

  583 tests
  1164 passed
  3 failed  

  Failed Tests:  There were 3 failures

    x message2event: irl invite event renders embed - should deep equal
    x message2event: vc invite event renders embed - should deep equal
    x message2event: vc invite event renders embed with room link - should deep equal

...So I'm not gonna be touching those. Maybe they're broken tests or maybe my own regional settings messed something up (it is related to time, after all, so it can vary region-by-region - tho in that case, I'd still call that a broken test to some extent, as I don't think the dev's own locale should be breaking a test, but either way, I'm not messing with this) or maybe it's something else entirely.

Now, it's time for manual tests; lord have mercy...

I'm getting some failed automated tests, but they seem to also be present upstream (as can be seen by the shell prompt, I'm on `[HEAD]`, and that's the HEAD of the main OOYE, not my fork): ``` out-of-your-element on  HEAD (a503277) [?] is 📦 v3.7.0 via  v26.10.0 ❯ npm ci --include=dev added 209 packages, and audited 211 packages in 6s 37 packages are looking for funding run `npm fund` for details found 0 vulnerabilities npm warn install-scripts 1 package had install scripts blocked because they are not covered by allowScripts: npm warn install-scripts better-sqlite3@13.0.3 (install: node-gyp rebuild) npm warn install-scripts npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow. out-of-your-element on  HEAD (a503277) [?] is 📦 v3.7.0 via  v26.10.0 took 5s ❯ npm test npm notice run out-of-your-element@3.7.0 test npm notice run cross-env FORCE_COLOR=true supertape --no-check-assertions-count --format tap --no-worker test/test.js | tap-dot .............. ............................................................................................................................................................................................................................................................................................................................................................................................................................................................xxx................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ message2event: irl invite event renders embed - should deep equal operator: deepEqual diff: |- [ { "$type": "m.room.message", "body": "https://discord.gg/placeholder?event=1381190945646710824", "format": "org.matrix.custom.html", "formatted_body": "<a href=\"https://discord.gg/placeholder?event=1381190945646710824\">https://discord.gg/placeholder?event=1381190945646710824</a>", "m.mentions": {}, "msgtype": "m.text", }, { "$type": "m.room.message", - "body": "| Scheduled Event - 8 June at 10:00 pm NZT – 9 June at 12:00 am NZT + "body": "| Scheduled Event - 8 June at 10:00 pm NZT – 9 June at 12:00 am NZT | ## forest exploration | | 📍 the dark forest", "format": "org.matrix.custom.html", - "formatted_body": "<blockquote><p>Scheduled Event - 8 June at 10:00 pm NZT – 9 June at 12:00 am NZT</p><strong>forest exploration</strong><p>📍 the dark forest</p></blockquote>", + "formatted_body": "<blockquote><p>Scheduled Event - <a href=\"https://bridge.example.org/time/1749376800/F\">8 June at 10:00 pm NZT – 9 June at 12:00 am NZT</a></p><strong>forest exploration</strong><p>📍 the dark forest</p></blockquote>", "m.mentions": {}, "msgtype": "m.notice", }, ] at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1580:4 Error: should deep equal at run (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:271:33) at Object.deepEqual (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:206:9) at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1580:4 at async tryToCatch (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/try-to-catch/lib/try-to-catch.js:7:23) message2event: vc invite event renders embed - should deep equal operator: deepEqual diff: |- [ { "$type": "m.room.message", "body": "https://discord.gg/placeholder?event=1381174024801095751", "format": "org.matrix.custom.html", "formatted_body": "<a href=\"https://discord.gg/placeholder?event=1381174024801095751\">https://discord.gg/placeholder?event=1381174024801095751</a>", "m.mentions": {}, "msgtype": "m.text", }, { "$type": "m.room.message", - "body": "| Scheduled Event - 9 June at 3:00 pm NZT + "body": "| Scheduled Event - Monday, 9 June 2025 at 3:00 am (UTC) | ## Cooking (Netrunners) | Short circuited brain interfaces actually just means your brain is medium rare, yum. | | 🔊 Cooking", "format": "org.matrix.custom.html", - "formatted_body": "<blockquote><p>Scheduled Event - 9 June at 3:00 pm NZT</p><strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.<p>🔊 Cooking</p></blockquote>", + "formatted_body": "<blockquote><p>Scheduled Event - <a href=\"https://bridge.example.org/time/1749438000/F\">Monday, 9 June 2025 at 3:00 am (UTC)</a></p><strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.<p>🔊 Cooking</p></blockquote>", "m.mentions": {}, "msgtype": "m.notice", }, ] at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1613:4 Error: should deep equal at run (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:271:33) at Object.deepEqual (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:206:9) at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1613:4 at async tryToCatch (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/try-to-catch/lib/try-to-catch.js:7:23) message2event: vc invite event renders embed with room link - should deep equal operator: deepEqual diff: |- [ { "$type": "m.room.message", "body": "https://discord.gg/placeholder?event=1381174024801095751", "format": "org.matrix.custom.html", "formatted_body": "<a href=\"https://discord.gg/placeholder?event=1381174024801095751\">https://discord.gg/placeholder?event=1381174024801095751</a>", "m.mentions": {}, "msgtype": "m.text", }, { "$type": "m.room.message", - "body": "| Scheduled Event - 9 June at 3:00 pm NZT + "body": "| Scheduled Event - Monday, 9 June 2025 at 3:00 am (UTC) | ## Cooking (Netrunners) | Short circuited brain interfaces actually just means your brain is medium rare, yum. | | 🔊 Hey. - https://matrix.to/#/!FuDZhlOAtqswlyxzeR:cadence.moe?via=cadence.moe", "format": "org.matrix.custom.html", - "formatted_body": "<blockquote><p>Scheduled Event - 9 June at 3:00 pm NZT</p><strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.<p>🔊 Hey. - <a href=\"https://matrix.to/#/!FuDZhlOAtqswlyxzeR:cadence.moe?via=cadence.moe\">Hey.</a></p></blockquote>", + "formatted_body": "<blockquote><p>Scheduled Event - <a href=\"https://bridge.example.org/time/1749438000/F\">Monday, 9 June 2025 at 3:00 am (UTC)</a></p><strong>Cooking (Netrunners)</strong><br>Short circuited brain interfaces actually just means your brain is medium rare, yum.<p>🔊 Hey. - <a href=\"https://matrix.to/#/!FuDZhlOAtqswlyxzeR:cadence.moe?via=cadence.moe\">Hey.</a></p></blockquote>", "m.mentions": {}, "msgtype": "m.notice", }, ] at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1655:4 Error: should deep equal at run (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:271:33) at Object.deepEqual (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/supertape/lib/operators.js:206:9) at /home/guzio/Dokumenty/Projekty/out-of-your-element/src/d2m/converters/message-to-event.test.js:1655:4 at async tryToCatch (file:///home/guzio/Dokumenty/Projekty/out-of-your-element/node_modules/try-to-catch/lib/try-to-catch.js:7:23) 583 tests 1164 passed 3 failed Failed Tests: There were 3 failures x message2event: irl invite event renders embed - should deep equal x message2event: vc invite event renders embed - should deep equal x message2event: vc invite event renders embed with room link - should deep equal ``` ...So I'm not gonna be touching those. Maybe they're broken tests or maybe my own regional settings messed something up (it *is* related to time, after all, so it can vary region-by-region - tho in that case, I'd still call that a broken test to some extent, as I don't think the dev's own locale should be breaking a test, but either way, I'm not messing with this) or maybe it's something else entirely. *Now, it's time for manual tests; lord have mercy...*
it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache it was the goddamnit build cache
The whole reason this woke branch up again, is that Cadence said she wants to use Matrix threads for discoverability of Discord threads. So RIP Ellie Mode (the one that eradicates threads fully).
It refuses to render the 1st message of a thread, whether it's an emote, or anything else. COMMET, *WHY?*

Anyway, I don't think it makes sense to add extra accommodation to what's clearly a client-level bug. So emotes are back, yay!
I've come to fix conflicts, and then pretend you don't exist, again.
This pull request is marked as a work in progress.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u mergable-fr-fr:Guzio-mergable-fr-fr
git switch Guzio-mergable-fr-fr

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff Guzio-mergable-fr-fr
git switch Guzio-mergable-fr-fr
git rebase main
git switch main
git merge --ff-only Guzio-mergable-fr-fr
git switch Guzio-mergable-fr-fr
git rebase main
git switch main
git merge --no-ff Guzio-mergable-fr-fr
git switch main
git merge --squash Guzio-mergable-fr-fr
git switch main
git merge --ff-only Guzio-mergable-fr-fr
git switch main
git merge Guzio-mergable-fr-fr
git push origin main
Sign in to join this conversation.
No description provided.