[pull] master from jitsi:master - #838
Merged
Merged
Conversation
* feat(documentPiP): auto open on tab switch and trigger button (#17450) * feat(documentPiP): auto open on tab switch and trigger button * suggestions * lint:fix * file and class name updates * restore comment * suggestions * add: suggestions and webkit for safari auto open * add: comment * feat: document pip window content (#17576) * feat(config): gate browser pip behind config flag * fix(safari): PiP Video content * lint:fix * suggestions * comment * comment * remove key state * chore: add default fallback for browser pip config * chore: dev styling gap for make * hide * lint * fix: safari pip open with avatar show on video mute (#17721) * fix(pip): deliver canvas avatar frames on WebKit Safari never showed the PiP avatar (and refused to open PiP at all) when the stage participant had video off from the start of the meeting, because no frame was ever delivered to the hidden video element: - CanvasCaptureMediaStreamTrack.requestFrame() in WebKit only arms a one-shot capture that fires on the next canvas paint. The render always painted first and requested after, so on a static avatar canvas the armed capture waited forever for a repaint. Later state churn accidentally satisfied the previous cycle's request, which is why the avatar appeared to work once PiP had been shown before. - Frames published right after a srcObject assignment are silently dropped while Safari asynchronously wires the element to the stream. Streams never buffer for late sinks (W3C resolution in w3c/mediacapture-transform#114) and no readiness event exists, so a single publish at attach time cannot be reliable. publishFrame() now nudges the canvas with an imperceptible 1px paint after arming so an emission paint always follows (WebKit only), and attaching the canvas stream republishes every 50ms until the element reports data, bounded to 25 attempts (WebKit only). Chromium captures synchronously and redelivers the current frame to late sinks, so it needs neither. * fix(pip): honor an explicit disableBrowserPiP in isPiPEnabled External API consumers and the client answered "is PiP enabled" differently: isPiPEnabled() ignored disableBrowserPiP entirely, so an embedder passing disableBrowserPiP: true still got the iframe-visibility observer installed while the client refused every show-PiP request. The shared gate now honors an explicitly set flag. The opt-in default (absent flag counts as disabled) intentionally stays client-side in shouldShowPiP(): the external API evaluates isPiPEnabled() against only the embedder-provided config and cannot see the deployment's config.js, so defaulting to disabled there would silently break embedded auto-PiP for deployments that opt in server-side. An over-approximating embedder only costs a no-op show-PiP request that the client refuses. * refactor(pip): unexport copyStylesheets It is only called by initPiPWindow(); exporting it implied it is safe to call independently, bypassing the PiP-window reference tracking that initPiPWindow() enforces. * fix(pip): notify on user-initiated MediaSession PiP open failure Entering PiP through the browser's PiP icon (MediaSession 'useraction') is just as user-initiated as the toolbar button, but its failures produced no user-visible feedback because the handler never passed notifyOnFailure. Such failures now surface exactly like toolbar-button failures; automatic 'contentoccluded' entries stay silent (but still logged) to avoid nagging the user on every tab switch. The handler cannot leak rejections into the browser's fire-and-forget invocation because openDocumentPiP() reports every failure internally. * refactor(pip): drop no-op state rollback in openDocumentPiP error handler isPiPActive can only become true via the success path (handlePipEnterEvent), which the already-open and request-pending guards make unreachable before a failure, so resetting it when requestWindow() fails was dead code that read as a real rollback and obscured the actual invariant. * refactor(pip): move IOpenDocumentPiPOptions to types.ts All other PiP interfaces live in types.ts; keeping this one inside actions.ts made the feature's type surface inconsistent. * refactor(pip): terminate the middleware switch case with break The missing break only works while the switch has no default case; adding one later would silently run exitPiP for every action. This also matches the convention used by the other middlewares. * refactor(pip): name PiPVideoElement timing values and the WebKit dismissal flag The 25 x 50 ms canvas republish loop used magic numbers, and webKitPiPDismissedRef did not encode that it is set only when PiP is dismissed while the tab is still hidden - the invariant the automatic re-entry suppression relies on. FOCUS_CHECK_DELAY_MS also moves file-local since it is Electron-specific and used in one place. * refactor(pip): compute Document PiP support once at module load The result cannot change during the page lifetime, so a module-level constant makes that explicit instead of re-evaluating it on every render. * refactor(pip): rename disableBrowserPiP to opt-in enableBrowserPiP Enabling browser PiP required the double negative disableBrowserPiP: false, and a disableX flag defaulting to true inverts the expectation set by every other disableX config flag (they all default to false) - review found it easy to misread and suggested the positive polarity. The rename costs nothing now because the flag has not shipped on master yet; after the branch merges it would be a breaking config change forever. Semantics are unchanged: an absent flag still means disabled in the client and permissive on the external API side (which cannot see the deployment's config), and an explicitly set value is honored by both. * fix(pip): store the Document PiP window in Redux React cannot observe the module-level window reference, so a rapid close-and-reopen could leave DocumentPiPContent's memoized Emotion cache bound to the previous, already-closed window whenever isPiPActive did not observably change. Keeping the reference in the pip state makes every mutation observable by construction - the mutation is the dispatch - so the component re-renders and rebuilds the cache exactly when the window changes, and the module-level getStoredPiPWindow/clearPiPWindow/closeDocumentPiPWindow helpers disappear along with the invariant that every mutation must remember to pair itself with a dispatch. The pip feature is excluded from the native TypeScript check, but IPipState still reaches it through IReduxState while the native config has no DOM lib defining Window - hence the ts-ignore on the field, mirroring web-hid's HIDDevice. Types are erased at build time, so this affects the type check only. * fix(pip): reset PiP window body styles before stylesheets load The copied stylesheets load asynchronously, so until they land the PiP document keeps the UA default 8px body margin and overflow: auto. The 100vw/100vh container then overflows the body and scrollbars flash on every open. Resetting margin and overflow synchronously removes the flash, mirroring what multi-screen's buildWindow already does. * refactor(pip): register the tab-visibility PiP listener once Selecting pipWindow into the visibilitychange handler's closure put it in the effect dependencies, tearing down and re-registering the listener on every PiP open and close. Dispatching the existing hidePiP thunk instead moves the active-PiP check into the thunk, where it reads fresh state, so the handler needs no state in its closure and the listener registers once for the lifetime of the mount. --------- Co-authored-by: Bandhan Majumder <133476557+bandhan-majumder@users.noreply.github.com> Co-authored-by: Bandhan Majumder <bandhanmajumder16@gmail.com>
…ording visibility - Allow live streaming to start while transcription is active (#17732) - Show local recording option in Record & Transcribe dialog even when transcription is running (#17731) Transcription should be independent of live streaming; the Jibri-only disable guard now checks cloud recording only. Local recording is browser-side and has no dependency on whether JWT recording is enabled, so it is now always rendered in _renderSessionToggles.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )