- The Vite transform wrapper takes Vite's own types, with no cast.
- The pipeline's options are compared with deepCompare, not as JSON.
- Renames `attached` to `enable` and shortens the pipeline's doc comment.
- Drops a comment that blamed an ended track on the pipeline's queue.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The menu asked the browser; the pipeline asked the browser and for a
desktop. On a phone whose browser can run them, blur was offered and
then refused: the toggle moved and the video did not change.
- Both now ask one function, and it asks the browser alone. The platform
was the wrong measure: a phone on the fast route held 99% of its frame
rate and was refused, a desktop on the slow one held 73% and was
allowed.
- The in-call device switcher is still withheld on a phone; that is the
device menu's own rule and is unchanged.
- The provider tests run as a phone, and fail with the desktop test back.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- One pipeline, shared by the pre-join preview and the call, attached the
first time an effect is wanted and never detached after; turning blur
off switches it to a disabled mode in place. Main dropped the processor
whenever blur went off, and a pipeline taken off the camera is destroyed
and re-primed, so each time blur came back one unprocessed frame went
out. Built once, the priming frame is spent once.
- Still driven by the existing blur setting: nothing a user sees changes.
- Its logic is BackgroundEffects in src/state/, which the provider only
builds, so the tests drive it without rendering anything.
- Disabled drops the blur radius too. The SDK's disabled mode keeps it,
and with a radius every frame is still segmented and thrown away; with
neither a radius nor a picture, frames pass untouched.
- Switches run one at a time and skip any overtaken, so an earlier,
slower switch can't land after a later choice.
- Builds, rebuilds and teardowns of the pipeline run one at a time
(OneStepPipeline). The preview's and the call's tracks attach and stop
it independently, and the SDK's wrapper holds one track's streams: two
builds at once overwrite each other's, and a stop during a build does
nothing.
- Every camera track starts with the pipeline on: the room's capture
defaults follow it, and a camera turned off before the first effect is
replaced on turning it on, since a stopped track can't take one. One
attached after publishing lets the room through while it is built.
- BlurBackgroundTransformer becomes BackgroundEffectTransformer: it also
sits disabled, and its init applies that state as the SDK's would.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- nodePolyfills rewrites any module that mentions process, and MediaPipe's
WASM loader does. The loader is a classic script that sets
self.ModuleFactory; as a module it sets nothing, so under pnpm dev the
segmenter failed with "ModuleFactory not set". Blur on main fails the
same way there. Production is unaffected: the loader ships as a static
asset.
- The plugin's transform now skips that loader. Checked with main's own
BlurBackgroundTransformer: it initialises with this and fails without.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Compound 10.3.0 bounds a menu by the space it has and scrolls what
doesn't fit, within a boundary the app passes. The menus pass the call
area, 16px in from its sides, rather than measuring its width.
- The 296px width is the menu's own style. Compound gives that style only
to the dropdown, so menuIsDrawer, which copied its phone rule, goes.
- Compound draws the menu's frame over its content, so nothing that
scrolls can hide it in Safari: the list, headings and meter no longer
keep a border width clear of it, and the checks that they did go.
- The device list is Compound's scroll area, so it fades out at the
foot with Compound's chevron while there is more below.
- The microphone menu's meter sticks at that foot, with rows scrolling
under it as before, so the list has no fade above it: Compound's is a
mask fixed to the list's edge, while a bounce at the top carries the
meter with the rows. The band under the meter is filled, or rows would
show there. The edge fades from where the chevron starts, so a bounce
fades the meter out before it reaches the chevron. A row reached by
keyboard stays above the meter.
- The list's height is still its share of the call.
- The component harness leaves the host's stylesheets unscoped, Compound's
among them, as a host does: scoped, they never reached the menu, which is
portalled out of Element Call's root.
- Its specs check only Element Call's own document styles on the host
page, and find the device list within Compound's scroll area.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The camera and microphone menus were as wide as their longest device
name, so a long one widened the menu over more of the call: 340px for a
long speaker name. Both are now 296px, as design sets them, and a long
name wraps.
- Narrower only where the call area is, so the menu still fits inside it:
268px in a 300px call. Taken from the observation of the call area that
already bounds the list's height.
- Held only for the dropdown. On Android and iOS Compound renders the menu
as a drawer as wide as the screen; menuIsDrawer follows its rule.
- Once the list is long enough to scroll, Safari paints it above the
outline the menu is framed with, and the frame vanished down both sides
of it: 384px of it on the many-devices microphone menu, in WebKit. The
list now keeps a border width clear of the frame, so the headings and
the meter inside it no longer need their own.
- Guarded with a long speaker name, which fails at 340px on main's sizing;
a unit test run as a phone, which fails with the width held there; and
the many-devices story's inset, which fails on the old stylesheet, since
the stories run in Chromium, which never showed the Safari bug.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
I learned that makeKeyDelay has been deprecated in matrix-js-sdk ever since the switch to the new encryption manager, so this config option has no effect.
Compound's Tooltip floats its bubble through floating-ui's FloatingPortal,
into the body: outside the element the component build confines its
stylesheet to, so a label tooltip shows as bare text at all times. An
enclosing FloatingPortal rooted at the container makes the nested portals
land inside it instead.
The call goes in an isolating wrapper there, standing in for the standalone
page's #root, so that its footer layer no longer paints above the modals.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>