Skip to content

Fix/25455 merge 2 - #20

Closed
antobinary wants to merge 166 commits into
v4.0.x-developfrom
fix/25455-merge-2
Closed

antobinary wants to merge 166 commits into
v4.0.x-developfrom
fix/25455-merge-2

Conversation

@antobinary

Copy link
Copy Markdown
Owner

What does this PR do?

Closes Issue(s)

Closes #

Motivation

How to test

More

  • Added/updated documentation

blaniel and others added 30 commits June 12, 2026 11:05
…o links

In the BlockNote shared notes editor, y-prosemirror renders the remote
collaboration cursor as a ProseMirror widget decoration with `side: 10` and
no `marks`, so ProseMirror wraps the widget in the marks of the node that
follows the caret. When a remote user's caret sits inside a link, that node
carries the `link` mark, so the cursor — including the user's name and the
U+2060 word-joiner separators around it — was rendered inside the <a>,
leaking the name into the link's visible text (issue bigbluebutton#25225).

Render the cursor through BlockNote's supported `renderCursor` hook so the
element carries no document text: the collaborator's name is held in a
`data-cursor-name` attribute and shown as CSS `::after` pseudo-content
(never part of `textContent`/`href`), and the U+2060 separators are dropped.
Presence rendering (caret + name label, including the activity/hover label)
is preserved.

Adds a two-user Playwright regression test that places one user's cursor
inside a link and asserts the other user's view of that link contains no
collaborator name and no word-joiner separators in its text or href.

Co-authored-by: Tainan Felipe <tainanfelipe214@gmail.com>
The reply intention preview and the quote inside sent replies extract
the first visible line of the original message with
getFirstVisibleLineHtml. The function treated the inline tags <a> and
<code> as block-level, walked the root children in reverse order and
removed every node that precedes the last "block" found - so a message
like "Hello https://example.com" was previewed as just the link.

Rewrite the extraction to walk the DOM in document order and truncate
at the first visual line break (newline in a non-whitespace-only text
node, <br>, or the end of the first nested block element), keeping
inline content of the first line intact. Lists now preview their first
item instead of the last one.

Add an e2e scenario covering both previews when replying to a message
with text followed by a link.

Co-authored-by: Tainan Felipe <tainanfelipe214@gmail.com>
…view

- Assert the remote cursor is positioned inside the link (the precondition
  that proves the bug condition is actually exercised — guards against a
  false pass on a clean-but-cursorless link).
- Poll for the remote cursor instead of a fixed sleep (robust; still reads
  via page.evaluate so the cursor owner's editor keeps focus and keeps
  broadcasting its cursor).
- Count only `.bn-collaboration-cursor__base` (one per cursor) and drop the
  unused `hasAnchor` field.
- Add a TODO pointing at the upstream y-prosemirror `marks: []` fix.

Co-authored-by: Tainan Felipe <tainanfelipe214@gmail.com>
…ministic

The click-based caret positioning was flaky: clicking the link opens
BlockNote's link toolbar, which steals editor focus and stops y-prosemirror
from broadcasting the moderator's cursor — so the attendee sometimes saw the
cursor at the link's end (outside the <a>) and the test failed on the
precondition instead of reaching the bug assertion.

Place the caret inside the link by keyboard only, and fold the presence
guard + inside-link precondition + sync wait into a single
expect.poll(cursorWidgetInsideLink).toBe(true).

Verified: RED on an unpatched 3.0 server (fails on the U+2060 assertion,
reproducing bigbluebutton#25225) and GREEN on the patched build.

Co-authored-by: Tainan Felipe <tainanfelipe214@gmail.com>
The raised hand indicator was only computed for GRID and STREAM tile
types, so audio-only tiles never displayed it even though the user data
(raiseHand) and the render path were already in place. Include the
AUDIO_ONLY tile type in the raiseHand condition.

Add a data-test hook to the indicator and an end-to-end test covering an
audio-only tile raising its hand.

Closes bigbluebutton#25169
Address review feedback (Arthurk12): the audio-only tile only appears when
public.kurento.cameraSortingModes.showAudioOnlyOnFirstPage is enabled. Expose
that setting in the playwright settings helper and skip the test (instead of
failing with an opaque "tile never appeared" error) when it is disabled,
mirroring the existing pattern already used for other client-setting-dependent
tests (e.g. emojiRainTest).

Ref: bigbluebutton#25169
Bumps [markdown-it](https://github.com/markdown-it/markdown-it) from 14.1.1 to 14.2.0.
- [Changelog](https://github.com/markdown-it/markdown-it/blob/master/CHANGELOG.md)
- [Commits](markdown-it/markdown-it@14.1.1...14.2.0)

---
updated-dependencies:
- dependency-name: markdown-it
  dependency-version: 14.2.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
fix(video-provider): show raised hand indicator on audio-only tiles
fix(chat): preserve text before links in reply message preview
Add client setting to not display guest lobby position
…test

Define WORD_JOINER once in util.ts and import it in blocknote.ts instead
of declaring the same value in both files. The util.ts copy lived inside a
page.evaluate (browser scope), so it is now passed into the evaluate as an
argument. Addresses review feedback on PR bigbluebutton#25285.
Bumps [form-data](https://github.com/form-data/form-data) from 4.0.5 to 4.0.6.
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](form-data/form-data@v4.0.5...v4.0.6)

---
updated-dependencies:
- dependency-name: form-data
  dependency-version: 4.0.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Ship MALLOC_ARENA_MAX=2 as a systemd drop-in via bbb-config for the
two JVM services (bbb-web, bbb-apps-akka). glibc's default arena pool
(8 x vCPU) causes 500-600MB+ of unnecessary off-heap RSS on bbb-web;
clamping to 2 arenas reduces RSS p95 by 37% with zero regressions
measured over 36h with three-host A/B controls.

Non-JVM services (graphql-server, graphql-middleware, html5, pads,
livekit) use their own allocators and are not affected.

Operators can override with a higher-priority drop-in in
/etc/systemd/system/<service>.service.d/.

Co-Authored-By: Tiago Jacobs <tiago.jacobs@gmail.com>
…a-max-jvm

Set MALLOC_ARENA_MAX=2 for bbb-web and bbb-apps-akka
…memory growth

The BigBlueButton source in bbb-graphql-server metadata keeps each
Postgres connection alive for 1 hour (connection_lifetime: 3600). While a
connection stays open, Postgres holds onto the memory it used and never
returns it to the system, so a 1-hour lifetime with up to 100 connections
lets several GB pile up across a workday and pushes hosts into swap.

Lowering it to 300 (the value validated in the investigation) recycles
connections while still under load, so per-connection memory stays
bounded. The cost is one reconnect per connection every 5 minutes,
negligible next to the graphql server's constant query polling.

Co-Authored-By: Tiago Jacobs <tiago.jacobs@gmail.com>
…-connection-lifetime

fix(bbb-graphql-server): lower connection_lifetime to limit Postgres memory growth
100% translated source file: 'en.json'
on 'fr'.
100% translated source file: 'en.json'
on 'fr'.
… one to prevent ODF export cropping (bigbluebutton#25303)

Exported ODF slides with an image rendered cropped into the top-left
corner. The background slide is loaded as an <image> sized to the slide,
but CairoSVG only rescales the referenced SVG to that box when the file
carries a viewBox. Slides converted without one keep their intrinsic
size and render cropped.

When the slide SVG lacks a viewBox, derive one from its own width and
height so the background scales to fill the slide. This is a no-op for
slides that already carry a viewBox, so current decks are unaffected.
antobinary and others added 27 commits July 15, 2026 23:57
…-notes-markdown

feat(shared-notes): markdown export, init-from-markdown, and import modal
…ting, not a /create param (bigbluebutton#25436)

`allowOverrideClientSettingsOnCreateCall` is read only from bbb-web.properties
(injected via Spring resources.xml) and consumed as a global in ApiController.
It is never read from the create request params (no ApiParams constant, and
processCreateParams never reads it), so passing it in a /create call has no
effect. The docs incorrectly presented it as a per-create parameter.

- api.md: drop the false "or as part of the CREATE call" enable path; state
  explicitly it is a server-side setting only; keep the checksum caveat and
  point to clientSettingsOverrideJsonUrl as the checksummed alternative.
- api.md: remove it from the create "Added parameters" changelog list and note
  it on the clientSettingsOverride POST module line instead.
- create.tsx: remove the /create parameter table entry (an entry here asserts
  the value is settable per meeting, which is the reported bug).

Fixes bigbluebutton#23051

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The BlockNote revision path (BNSharedNotesUpdatedEvtMsg ->
SharedNotesRevDAO.insertNextRev) never filled sharedNotes_rev.createdAt,
so v_sharedNotes.lastUpdatedAt stayed NULL and the sidebar unread dot
never lit for BlockNote meetings. Fill createdAt with current_timestamp.

On the client, the BlockNote panel never marked the notes as read, so
the dot would not clear correctly once lit. Mirror the etherpad pad:
mark as read when the synced editor is shown and when it is hidden -
the panel stays mounted for NOTES_UNMOUNT_DELAY after closing, and
edits arriving in that window must stay unread.

Fixes the unread indicator regression reported in
bigbluebutton#25250

Co-authored-by: Tainan Felipe <tainanfelipe214@gmail.com>
New Playwright spec (sharednotes/blocknote) creating the meeting with
sharedNotesEditor=blockNote: the indicator appears for a user with the
panel closed, clears on open, stays hidden after reading, and lights
again on new edits.

Co-authored-by: Tainan Felipe <tainanfelipe214@gmail.com>
The recording e2e opened shared notes through the Etherpad util, which
waits for iframe[title="pad"]. Since BlockNote became the default editor
that iframe never appears, so recordMeeting() (run in beforeAll) timed
out on "should display the etherpad frame" and failed every Recording
test.

Switch the recording flow to the BlockNote util (startSharedNotesBlockNote
+ getBlockNoteEditorLocator, click + pressSequentially). The default editor
is already BlockNote, so no create-call override is needed. The recording
backend already archives BlockNote notes (archive.rb routes non-etherpad
editors to bn_notes_endpoint), so the playback notes assertions still hold.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bump the pinned tomcat-embed override from 10.1.55 to 10.1.56.
Bump the managed Spring Boot version from 3.5.14 to 3.5.16.
bbb-apps-akka and bbb-fsesl-akka:
- jackson 2.13.5 -> 2.18.9, aligned across the suite via dependencyOverrides
- pin netty to 4.1.135.Final via dependencyOverrides (transitive)
- logback 1.2.13 -> 1.5.38, with slf4j-api pinned to 2.0.17
- commons-lang3 3.12.0 -> 3.18.0
- postgresql 42.5.0 -> 42.7.13 (bbb-apps-akka only)
Updated versions of Netty, PostgreSQL, Spring Framework, Jackson BOM,
Logback, and Spring Data BOM.
…e2e-blocknote

test(recording): use BlockNote editor for shared-notes recording step
The private chats list rendered each item header immediately but gated the
message preview behind a separate per-item subscription (chat_message_private).
When that subscription resolved a moment later the preview row mounted and the
item grew in height, making the list jump (issue 25416).

Bring the last message into the chats subscription itself. v_chat now resolves
the last message with a LATERAL join (Index Scan Backward on the existing
idx_v_chat_message_unread / idx_v_chat_message_private, so no new index is
needed), plus the deleter display name so a soft-deleted last message
(message=NULL, deletedByUserId set) reuses the existing "deleted by {userName}"
label instead of showing an empty preview. The private chat item now reads
chat.lastMessage directly, so the preview is present on the first paint and the
per-item subscription and its layout shift are gone.

Add a Playwright regression test that delays only the chat_message_private
frames and asserts the preview is present at first paint, plus a soft-deleted
last message case.
* fix(shared-notes): show unread indicator for BlockNote notes

The BlockNote revision path (BNSharedNotesUpdatedEvtMsg ->
SharedNotesRevDAO.insertNextRev) never filled sharedNotes_rev.createdAt,
so v_sharedNotes.lastUpdatedAt stayed NULL and the sidebar unread dot
never lit for BlockNote meetings. Fill createdAt with current_timestamp.

On the client, the BlockNote panel never marked the notes as read, so
the dot would not clear correctly once lit. Mirror the etherpad pad:
mark as read when the synced editor is shown and when it is hidden -
the panel stays mounted for NOTES_UNMOUNT_DELAY after closing, and
edits arriving in that window must stay unread.

Fixes the unread indicator regression reported in
bigbluebutton#25250

Co-authored-by: Tainan Felipe <tainanfelipe214@gmail.com>

* test(shared-notes): cover BlockNote unread indicator lifecycle

New Playwright spec (sharednotes/blocknote) creating the meeting with
sharedNotesEditor=blockNote: the indicator appears for a user with the
panel closed, clears on open, stays hidden after reading, and lights
again on new edits.

Co-authored-by: Tainan Felipe <tainanfelipe214@gmail.com>

---------

Co-authored-by: Claudio Promptoso <claudiopromptoso@gmail.com>
[4.0 port] chore: Update bbb-web, akka- core dependencies
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…te-chat-preview-via-schema

fix(chat): render private chat previews from the chats subscription
… merge

The v3.0.x -> v4.0.x merge resolved
bigbluebutton-tests/playwright/sharednotes/blocknote/util.ts to the 4.0
side wholesale, dropping the 3.0-added helpers that the merged-in
markdown.spec.ts / blocknote.spec.ts still import
(startBlockNoteSharedNotes, enableMarkdownNotesOptions, WORD_JOINER,
getBlockNoteLinkLocator, readLinkAndCursorState). Every blocknote/markdown
test threw "... is not a function" at runtime (Playwright transpiles the
specs without type-checking, so this slipped past the post-merge tsc pass).

Restore them, adapted to 4.0 selectors: the shared-notes sidebar button is
sharedNotesSidebarButton (3.0's e.sharedNotes no longer exists) and the
editor root is e.blockNoteEditor (#bn-notes-scroll-container .bn-editor),
not 3.0's [data-test="notes"] .bn-editor.

Fixes the 8 markdown import/export, 1 collaboration-cursor and 4
markdown-seed Playwright tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.0 renamed the participant-bearing chat locale key: app.chat.titlePrivate
became the plain "Private Chat", and the "Private Chat with {participantName}"
variant moved to app.chat.titlePrivateToUser. The document-title manager
(merged from 3.0) still formatted app.chat.titlePrivate with a participantName
argument, so the document title for an open private chat silently dropped the
participant name.

Point the manager at app.chat.titlePrivateToUser.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e 4.0 UI

WIP. The new-from-3.0 document-title.spec.ts drives UI interactions that 4.0
restructured. Adapt the unambiguous ones so the specs get past them:
- shared notes: e.sharedNotes -> e.sharedNotesSidebarButton
- poll: open via e.pollSidebarButton (not the actions menu) and assert
  e.minimizePolling (3.0's e.hidePollDesc no longer exists)
- settings modal: dismiss via e.saveSettingsButton (3.0's modalDismissButton
  only exists on the fullscreen modal)
- breakout: e.createBreakoutRooms -> e.createBreakoutRoomsButton

The three tests still fail on further 4.0 differences not yet handled (the
presentation actions button after the poll panel, the manageUsers flow, and
a wait for the attendee to appear before openPrivateChat). The document-title
feature itself works; this is purely test-harness adaptation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…esentation title works

The 3.0 document-title feature reads the in-memory 'showUploadPresentationView'
key to surface the "Upload Presentation" view name, but the 3.0 setter lived in
the actions-dropdown, which the 4.0 merge replaced with the media-area menu. The
key was therefore read but never written, so the title never updated in 4.0.

Set the key from the media-sharing menu whenever its presentation-upload sub-view
is open (and clear it otherwise), mirroring the 3.0 behaviour.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nd route-modals

Adapt the remaining 3.0-era interactions to the 4.0 client so the specs drive the
real UI:
- presentation upload opens from the media-area button (e.mediaAreaButton), not
  the 3.0 actions "+" menu
- the poll panel opens from e.pollSidebarButton and is confirmed by e.minimizePolling
- breakout creation opens from e.breakoutRoomSidebarButton (4.0 has no
  manageUsers -> createBreakoutRooms menu path)

"active client views" and "route-like modals" now pass. The private-chat case is
left on the shared openPrivateChat helper: it is blocked by a pre-existing 4.0
issue (the standard chat.spec "Send private message" test fails identically on
this client), not by the merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🚨 Automated tests failed

@antobinary antobinary closed this Jul 22, 2026
@antobinary
antobinary deleted the fix/25455-merge-2 branch July 22, 2026 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.