Fix widgets getting stuck in loading states#31314
Fix widgets getting stuck in loading states#31314Half-Shot merged 22 commits intoelement-hq:developfrom
Conversation
(Rather than storing just the raw ClientWidgetApi objects.)
|
This is failing the test coverage check at the moment because SonarCloud thinks the renamed files are entirely new code. This probably could benefit from a new test or two anyway targeting the actual regression, but I'm out of time until next week and would like this to at least gather review feedback in the meantime, please :) Edit: regression test added in #31354 |
BillCarsonFr
left a comment
There was a problem hiding this comment.
Great work catching this!
I find the renaming great, and thanks for documenting existing code 🙏
I just have a few comments.
| // we register listeners for both cases. Note that due to React strict | ||
| // mode, the messaging could even be aborted and replaced by an entirely | ||
| // new messaging while we are waiting here! | ||
| while (!messaging?.widgetApi) { |
There was a problem hiding this comment.
I am a bit lost, if messaging is undefined this is then a while(true) what is breaking the loop?
There was a problem hiding this comment.
...nothing, I think this needs a different check.
There was a problem hiding this comment.
There were two things that could break the loop in this case:
- A new messaging object is emitted by the store. The
onStoreMessagingcallback runs themessaging = m;statement which would cause the next iteration of the loop to check the newly stored messaging object. - The timeout is hit. This rejects the promise and causes the whole
Call.startmethod to throw.
By breaking it up into two loops this method became vulnerable to races seen in React strict mode, which in my testing today were causing the app to not know that the call was ever started & therefore also not be able to close on hangup. So I added a test demonstrating the race in 12bda78 and fixed it in 20fc397 by restoring the single loop approach (with more exhaustive comments this time). Sound good?
| * set of callbacks. | ||
| */ | ||
| // TODO: Consider alternative designs for matrix-widget-api? | ||
| // Replace with matrix-rust-sdk? |
There was a problem hiding this comment.
Should we add another comment that we would need to add thread support to the rust sdk for this but it would highly reduce maintenance burden.
There was a problem hiding this comment.
Imo, we should probably be putting these thoughts into an issue rather than in here. Code comments don't really allow for discussion and just rot :/
There was a problem hiding this comment.
Yeah, I just wanted to leave something small here in the code as a reminder though, and to replace the previously less helpful "TODO: Destroy all this code".
I don't see how threads are related.
There was a problem hiding this comment.
Imo, we should probably be putting these thoughts into an issue rather than in here. Code comments don't really allow for discussion and just rot :/
It's helpful to have both. One doesn't always think to go and look in an issue tracker when looking at code (and if you do, you don't know what you're looking for), and issues are just as capable of rotting as comments.
In short: if you're going to have an issue, remember to link to it from a code comment.
| } | ||
|
|
||
| /** | ||
| * A running instance of a widget, associated with an iframe and a messaging transport. |
There was a problem hiding this comment.
Can this get a bit more verbose. Especially the realtion between the widgetDriver and the WidgetMessaging is sth that might be hard to grasp for ppl trying to learn this code?
I feel like a complete list of the resposibilites of this class would be very nice.
- generate url (via template)
- allocate driver (delegate class required for the matrix-widget-api class to do cs api and client navigation tasks. (for widget-> element client communication)
- feed information into the widget (manually do all element client -> widget communication) (
updateTheme,setViewedRoomId, ...)
^ this summary also documents that the two classes WidgetDriver WidgetMessaging are doing very similar things just split by direction. It makes it easier to reason about unifying this seperation.
It would make a lot of sense, that the driver is a bidirectional interface (containing functions that do things on behave of the widget AND set up listeners on the client and call functions on the widget api (or emit) on specific actions.)
There was a problem hiding this comment.
8127687 Better?
If there's still anything you feel could be added, feel free to commit it.
StopGapWidget-test.ts was removed in `widgets` and updated in https://github.com/element-hq/element-web/pull/31398/files#diff-887d4a94e755a1c4b0658acd9b1ced9d2348602847a83685df6abb1926e9d596 All the updates done in the commit were moved over to WidgetMessaging-test.ts
Changes in [1.12.7](https://github.com/element-hq/element-web/releases/tag/v1.12.7) (2025-12-16) ================================================================================================ ✨ Features ----------- * Replace legacy icons with compound ([#31424](element-hq/element-web#31424)). Contributed by @t3chguy. * Update polls UX to match EX Mobile and improve accessibility ([#31245](element-hq/element-web#31245)). Contributed by @langleyd. * Add option to enable read receipt and marker when user interact with UI ([#31353](element-hq/element-web#31353)). Contributed by @florianduros. * Introduce a hook to auto dispose view models ([#31178](element-hq/element-web#31178)). Contributed by @MidhunSureshR. * Update settings toggles to use consistent design across app. ([#30169](element-hq/element-web#30169)). Contributed by @Half-Shot. * Add ability to the room view to hide widgets ([#31400](element-hq/element-web#31400)). Contributed by @langleyd. * call: Pass the echo cancellation and noise suppression settings to EC ([#31317](element-hq/element-web#31317)). Contributed by @BillCarsonFr. * Tweak rendering of icons for a11y ([#31358](element-hq/element-web#31358)). Contributed by @t3chguy. * Implement new `renderNotificationDecoration` from module API ([#31389](element-hq/element-web#31389)). Contributed by @MidhunSureshR. * Replace more icons with compound ([#31381](element-hq/element-web#31381)). Contributed by @t3chguy. * Replace more icons with compound ([#31378](element-hq/element-web#31378)). Contributed by @t3chguy. * `<Banner/>`: Hide `Dismiss` button if `onClose` handler is not provided. ([#31362](element-hq/element-web#31362)). Contributed by @kaylendog. * Replace batch of legacy icons with compound design tokens ([#31360](element-hq/element-web#31360)). Contributed by @t3chguy. * MSC4380: Invite blocking ([#31268](element-hq/element-web#31268)). Contributed by @richvdh. * Tweak rendering of icons for accessibility ([#31346](element-hq/element-web#31346)). Contributed by @t3chguy. * Implement a shared `Banner` component. ([#31266](element-hq/element-web#31266)). Contributed by @kaylendog. * Allow the Login screen to use the dark theme ([#31293](element-hq/element-web#31293)). Contributed by @richvdh. 🐛 Bug Fixes ------------ * [Backport staging] Amend e2e normal icon from lock-solid to info ([#31559](element-hq/element-web#31559)). Contributed by @t3chguy. * [Backport staging] Fix CSS specificity causing icon issues in e2e verification ([#31548](element-hq/element-web#31548)). Contributed by @RiotRobot. * [Backport staging] Fix e2e icons in CompleteSecurity \& SetupEncryptionBody ([#31522](element-hq/element-web#31522)). Contributed by @RiotRobot. * [Backport staging] Remove an extra paragraph in advanced room settings ([#31511](element-hq/element-web#31511)). Contributed by @RiotRobot. * [Backport staging] Don't show the key storage out of sync toast when backup disabled ([#31507](element-hq/element-web#31507)). Contributed by @RiotRobot. * Fix composer button visibility in contrast colour mode ([#31255](element-hq/element-web#31255)). Contributed by @t3chguy. * Ensure correct room version is used and permissions are appropriately sert when creating rooms ([#31464](element-hq/element-web#31464)). Contributed by @Half-Shot. * Fix e2e icon rendering ([#31454](element-hq/element-web#31454)). Contributed by @t3chguy. * EventIndexer: ensure we add initial checkpoints when the db is first opened ([#31448](element-hq/element-web#31448)). Contributed by @richvdh. * Fix `/join <alias>` command failing due to race condition ([#31433](element-hq/element-web#31433)). Contributed by @MidhunSureshR. * MessageEventIndexDialog: distinguish indexed rooms ([#31436](element-hq/element-web#31436)). Contributed by @richvdh. * Move `EditInPlace` out of `Form` (Fixes: reloading EW on EC url update) ([#31434](element-hq/element-web#31434)). Contributed by @toger5. * Fixes issue where cursor would jump to the beginning of the input field after converting Japanese text and pressing Tab ([#31432](element-hq/element-web#31432)). Contributed by @shinaoka. * Fix widgets getting stuck in loading states ([#31314](element-hq/element-web#31314)). Contributed by @robintown. * Room list: fix room options remaining on room item after mouse leaving ([#31414](element-hq/element-web#31414)). Contributed by @florianduros. * Make `RoomList.showMessagePreview` configurable by `config.json` ([#31419](element-hq/element-web#31419)). Contributed by @florianduros. * Fix bug which caused app not to load correctly when `force_verification` is enabled ([#31265](element-hq/element-web#31265)). Contributed by @richvdh. * Room list: display the menu option on the room list item when clicked/opened ([#31380](element-hq/element-web#31380)). Contributed by @florianduros. * Fix handling of SVGs ([#31359](element-hq/element-web#31359)). Contributed by @t3chguy. * Fix word wrapping in expanded left panel buttons ([#31377](element-hq/element-web#31377)). Contributed by @t3chguy. * Fix aspect ratio on error view background ([#31361](element-hq/element-web#31361)). Contributed by @t3chguy. * Fix failure to request persistent storage perms ([#31299](element-hq/element-web#31299)). Contributed by @richvdh. * Fix calls sometimes not knowing that they're presented ([#31313](element-hq/element-web#31313)). Contributed by @robintown. Changes in [1.12.6](https://github.com/element-hq/element-web/releases/tag/v1.12.6) (2025-12-03) ================================================================================================ This release fixes a bug where 1:1 calling was incorrectly not available if no Element Call focus was set. 🐛 Bug Fixes ------------ * Add option to pick call options for voice calls. ([#31413](element-hq/element-web#31413)). Changes in [1.12.5](https://github.com/element-hq/element-web/releases/tag/v1.12.5) (2025-12-02) ================================================================================================ ✨ Features ----------- * Update Emojibase to v17 ([#31307](element-hq/element-web#31307)). Contributed by @t3chguy. * Adds tooltip for compose menu ([#31122](element-hq/element-web#31122)). Contributed by @byteplow. * Add option to hide pinned message banner in room view ([#31296](element-hq/element-web#31296)). Contributed by @florianduros. * update twemoji to not monochromise emoji with BLACK in their name ([#31281](element-hq/element-web#31281)). Contributed by @ara4n. * upgrade to twemoji 17.0.2 and fix #14695 ([#31267](element-hq/element-web#31267)). Contributed by @ara4n. * Add options to hide right panel in room view ([#31252](element-hq/element-web#31252)). Contributed by @florianduros. * Delayed event management: split endpoints, no auth ([#31183](element-hq/element-web#31183)). Contributed by @AndrewFerr. * Support using Element Call for voice calls in DMs ([#30817](element-hq/element-web#30817)). Contributed by @Half-Shot. * Improve screen reader accessibility of auth pages ([#31236](element-hq/element-web#31236)). Contributed by @t3chguy. * Add posthog tracking for key backup toasts ([#31195](element-hq/element-web#31195)). Contributed by @Half-Shot. 🐛 Bug Fixes ------------ * Return to using Fira Code as the default monospace font ([#31302](element-hq/element-web#31302)). Contributed by @ara4n. * Fix case of home screen being displayed erroneously ([#31301](element-hq/element-web#31301)). Contributed by @langleyd. * Fix message edition and reply when multiple rooms at displayed the same moment ([#31280](element-hq/element-web#31280)). Contributed by @florianduros. * Key storage out of sync: reset key backup when needed ([#31279](element-hq/element-web#31279)). Contributed by @uhoreg. * Fix invalid events crashing entire room rather than just their tile ([#31256](element-hq/element-web#31256)). Contributed by @t3chguy. * Fix expand button of space panel getting cut off at the edges ([#31259](element-hq/element-web#31259)). Contributed by @MidhunSureshR. * Fix pill buttons in dialogs ([#31246](element-hq/element-web#31246)). Contributed by @dbkr. * Fix blank sections at the top and bottom of the member list when scrolling ([#31198](element-hq/element-web#31198)). Contributed by @langleyd. * Fix emoji category selection with keyboard ([#31162](element-hq/element-web#31162)). Contributed by @langleyd. Changes in [1.12.4](https://github.com/element-hq/element-web/releases/tag/v1.12.4) (2025-11-18) ================================================================================================ ✨ Features ----------- * Apply aria-hidden to emoji in SAS verification ([#31204](element-hq/element-web#31204)). Contributed by @t3chguy. * Add options to hide header and composer of room view for the module api ([#31095](element-hq/element-web#31095)). Contributed by @florianduros. * Experimental Module API Additions ([#30863](element-hq/element-web#30863)). Contributed by @dbkr. * Change polls to use fieldset/legend markup ([#31160](element-hq/element-web#31160)). Contributed by @langleyd. * Use compound Button styles for Jitsi button ([#31159](element-hq/element-web#31159)). Contributed by @Half-Shot. * Add FocusLock to emoji picker ([#31146](element-hq/element-web#31146)). Contributed by @langleyd. * Move room name, avatar, and topic to IOpts. ([#30981](element-hq/element-web#30981)). Contributed by @kaylendog. * Add a devtool for looking at users and their devices ([#30983](element-hq/element-web#30983)). Contributed by @uhoreg. 🐛 Bug Fixes ------------ * Fix room list handling of membership changes ([#31197](element-hq/element-web#31197)). Contributed by @t3chguy. * Fix room list unable to be resized when displayed after a module ([#31186](element-hq/element-web#31186)). Contributed by @florianduros. * Inhibit keyboard highlights in dialogs when effector is not in focus ([#31181](element-hq/element-web#31181)). Contributed by @t3chguy. * Strip mentions from forwarded messages ([#30884](element-hq/element-web#30884)). Contributed by @twassman. * Don't allow pin or edit of messages with a send status ([#31158](element-hq/element-web#31158)). Contributed by @langleyd. * Hide room header buttons if the room hasn't been created yet. ([#31092](element-hq/element-web#31092)). Contributed by @Half-Shot. * Fix screen readers not indicating the emoji picker search field is focused. ([#31128](element-hq/element-web#31128)). Contributed by @langleyd. * Fix emoji picker highlight missing when not active element ([#31148](element-hq/element-web#31148)). Contributed by @t3chguy. * Add relevant aria attribute for selected emoji in the emoji picker ([#31125](element-hq/element-web#31125)). Contributed by @t3chguy. * Fix tooltips within context menu portals being unreliable ([#31129](element-hq/element-web#31129)). Contributed by @t3chguy. * Avoid excessive re-render of room list and member list ([#31131](element-hq/element-web#31131)). Contributed by @florianduros. * Make emoji picker height responsive. ([#31130](element-hq/element-web#31130)). Contributed by @langleyd. * Emoji Picker: Focused emoji does not move with the arrow keys ([#30893](element-hq/element-web#30893)). Contributed by @langleyd. * Fix audio player seek bar position ([#31127](element-hq/element-web#31127)). Contributed by @florianduros. * Add aria label to emoji picker search ([#31126](element-hq/element-web#31126)). Contributed by @langleyd. Changes in [1.12.3](https://github.com/element-hq/element-web/releases/tag/v1.12.3) (2025-11-04) ================================================================================================ 🦖 Deprecations --------------- * Remove allowVoipWithNoMedia feature flag ([#31087](element-hq/element-web#31087)). Contributed by @Half-Shot. ✨ Features ----------- * Change module API to be an instance getter ([#31025](element-hq/element-web#31025)). Contributed by @dbkr. 🐛 Bug Fixes ------------ * Show hover elements when keyboard focus is within an event tile ([#31078](element-hq/element-web#31078)). Contributed by @t3chguy. * Ensure toolbar navigation pattern works in MessageActionBar ([#31080](element-hq/element-web#31080)). Contributed by @t3chguy. * Ensure sent markers are hidden when showing thread summary. ([#31076](element-hq/element-web#31076)). Contributed by @Half-Shot. * Fix translation in dev mode ([#31045](element-hq/element-web#31045)). Contributed by @florianduros. * Fix sort order in space hierarchy ([#30975](element-hq/element-web#30975)). Contributed by @t3chguy. * New Room list: don't display message preview of thread ([#31043](element-hq/element-web#31043)). Contributed by @florianduros. * Revert "A11y: move focus to right panel when opened" ([#30999](element-hq/element-web#30999)). Contributed by @florianduros. * Fix highlights in messages (or search results) breaking links ([#30264](element-hq/element-web#30264)). Contributed by @bojidar-bg. * Add prepare script ([#31030](element-hq/element-web#31030)). Contributed by @dbkr. * Fix html exports by adding SDKContext ([#30987](element-hq/element-web#30987)). Contributed by @t3chguy.
Depends on #31354
We allow widgets to remain "always on screen" by moving between a PiP view and an AppTile view as you switch rooms. But apparently the lifecycle of a StopGapWidget object was such that it would be disposed of and reconstructed every time the AppTile component was remounted, even while presenting the very same widget. This meant that whenever you switched rooms, causing a widget to move into a PiP, the client would forget some of the widget's state (like which iframe it was associated with, and whether the postmessage API had been started).
As far as I can tell, EW's widget code has always been brittle in this way, but the forgotten state didn't cause any visible impact until the upgrade to React 19 and some related fixes that I made. After those changes, switching rooms would cause the client to forget state that would prevent it from stopping widgets properly, causing issues for when you later try to launch the same widget again.
I believe the right way to fix this situation is to make StopGapWidget persist between React components, just as we persist the iframe element. In other words, put it in a store. But it felt really redundant to create a StopGapWidgetStore on top of all the other widget stores that we have knocking around…
So, the proposed solution: Rename the StopGapWidget class to WidgetMessaging, and store these objects in the WidgetMessagingStore. (Today that store holds ClientWidgetApi objects, but if WidgetMessaging objects are persistent, then they can just hold their own ClientWidgetApi without any help.) I used this renaming opportunity to also give the driver class a more proper name and add some much-needed doc comments to things.
Closes #30838
Closes #31065