updateVirtualBackgroundList does not immediately work


Description
When I call updateVirtualBackgroundList([]) for the first time, Zoom seems does not work, and then when I call the second time, it works.

Browser Console Error
No Error

Which Web Meeting SDK version?
2.17.0

Meeting SDK Code Snippets
The code snippets that are causing the error / issue so we can reproduce.

App.tsx

import { ChangeEvent, useRef, useState } from "react";
import ZoomMtgEmbedded, { EmbeddedClient, SuspensionViewType } from "@zoomus/websdk/embedded";
import { generateSignature } from "./utils";

enum ROLE {
  HOST = 1,
  PARTICIPANT = 0,
}

interface Form {
  userName: string;
  meetingNumber: string;
  password: string;
}

function App() {
  const meetingSDKElement = useRef<HTMLDivElement | null>(null);
  const HEIGHT = 500;
  const meetingNumber = "";
  const password = "";
  const [value, setValue] = useState<Form>({
    userName: "Le Minh Cuong",
    meetingNumber,
    password,
  });
  const [isMod, setIsMod] = useState(true);
  const [isEmptyVirtualBackground, setIsEmptyVirtualBackground] = useState(false);
  const clientRef = useRef<typeof EmbeddedClient>();
  const [, setZoomClient] = useState<typeof EmbeddedClient>();

  const loadZoom = async () => {
    const client = ZoomMtgEmbedded.createClient();

    clientRef.current = client;

    // expose zoom client to window
    window.zoomClient = client;

    await client.init({
      debug: true,
      maximumVideosInGalleryView: 5,
      zoomAppRoot: meetingSDKElement.current as unknown as HTMLElement,
      language: "en-US",
      customize: {
        meetingInfo: ["topic", "host", "mn", "pwd", "telPwd", "invite", "participant", "dc", "enctype"],
        video: {
          viewSizes: {
            default: {
              height: HEIGHT,
              width: Math.min(800, window.document.documentElement.clientWidth),
            },
          },
          isResizable: false,
          defaultViewType: "gallery" as SuspensionViewType,
        },
        toolbar: {
          buttons: [],
        },
        meeting: {
          popper: {
            modifiers: {
              class: "dasd",
            },
          },
        },
      },
    });

    await client.join({
      sdkKey: import.meta.env.VITE_ZOOM_SDK_KEY,
      signature: generateSignature(
        import.meta.env.VITE_ZOOM_SDK_KEY,
        import.meta.env.VITE_ZOOM_CLIENT_SECRET,
        value.meetingNumber,
        isMod ? ROLE.HOST : ROLE.PARTICIPANT,
      ),
      meetingNumber: value.meetingNumber,
      password: value.password,
      userName: value.userName,
    });

    setZoomClient(client);
  };

  const handleChangeValue = (e: ChangeEvent<HTMLInputElement>) => {
    setValue({
      ...value,
      [e.target.name]: e.target.value,
    });
  };

  const updateVideoOptions = () => {
    clientRef.current?.updateVirtualBackgroundList([]).then(() => {
      alert("Done");
    });
  };

  return (
    <>
      <div id="zoom-app" className="zoom-app" ref={meetingSDKElement}></div>
      <pre>{JSON.stringify(value, null, 4)}</pre>
      <form action="">
        <div className="form-item">
          <label htmlFor="meetingNumber">Meeting number</label>
          <input
            name="meetingNumber"
            id="meetingNumber"
            placeholder="Meeting number"
            type="text"
            value={value.meetingNumber}
            onChange={handleChangeValue}
          />
        </div>
        <div className="form-item">
          <label htmlFor="password">Password</label>
          <input
            name="password"
            id="password"
            placeholder="Password"
            type="text"
            value={value.password}
            onChange={handleChangeValue}
          />
        </div>
        <div className="form-item">
          <label htmlFor="userName">Username</label>
          <input
            name="userName"
            id="userName"
            placeholder="Username"
            type="text"
            value={value.userName}
            onChange={handleChangeValue}
          />
        </div>
        <div className="form-item">
          <label htmlFor="userName">Is Moderator</label>
          <input checked={isMod} onChange={() => setIsMod((pre) => !pre)} type="checkbox" />
        </div>
        <div className="form-item">
          <label htmlFor="userName">Only allow blur/none virtual background</label>
          <input
            checked={isEmptyVirtualBackground}
            onChange={() => setIsEmptyVirtualBackground((pre) => !pre)}
            type="checkbox"
          />
        </div>
        <button type="button" onClick={loadZoom}>
          load zoom
          <a href="#"></a>
        </button>

        <button type="button" onClick={updateVideoOptions}>
          updateVideoOptions
          <a href="#"></a>
        </button>
      </form>

      <div className="controls"></div>
    </>
  );
}

export default App;

generateSignature.ts

import { KJUR } from "jsrsasign";

export const generateSignature = (key: string, secret: string, meetingNumber: string, role: number) => {
  const iat = Math.round(new Date().getTime() / 1000) - 30;
  const exp = iat + 60 * 60 * 2;
  const oHeader = { alg: "HS256", typ: "JWT" };

  const oPayload = {
    sdkKey: key,
    appKey: key,
    mn: meetingNumber,
    role: role,
    iat: iat,
    exp: exp,
    tokenExp: exp,
  };

  const sHeader = JSON.stringify(oHeader);
  const sPayload = JSON.stringify(oPayload);
  const sdkJWT = KJUR.jws.JWS.sign("HS256", sHeader, sPayload, secret);
  return sdkJWT;
};

To Reproduce(If applicable)
Here is the layout

  • Fill out the meeting number
  • Fill out Password
  • Click on a load zoom button
  • Click on updateVideoOptions button and wait until it alerts done
  • Click on Settings > Background
  • Confirm that Zoom still shows the full list of virtual background
  • Close Settings
  • Click on updateVideoOptions button and wait until it alerts done (Retry)
  • Click on Settings > Background
  • Confirm that Zoom only shows None and Blur options

Screenshots

Troubleshooting Routes
The troubleshooting attempt types you’ve already exhausted, including testing with the appropriate sample app (found on Zoom · GitHub).

Device (please complete the following information):

  • Device: Macbook Pro
  • OS: macOS Ventura 13.4
  • Browser: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36’
  • Browser Version: 117.0.5938.62 (Official Build) (arm64)

Additional context
NONE

Hi @cuongle-hdwebsoft
Thanks for reaching out to us!
Are you still experiencing this behavior?

Yep, I’ve tried it and still got that issue

Thanks for confirming this with me @cuongle-hdwebsoft
Let me try and replicate this on my end and will get back to you with an update
Just to confirm, are you using the Component view?

Yes exactly @elisa.zoom

Hi @cuongle-hdwebsoft
I am not able to replicate this on my end with the sample app
Could you try adding your logic into the sample app and confirm if this happens as well?

Hi @elisa.zoom, I’ve tested your Sample again and there is no issue. This could be really weird because I actually just call updateVirtualBackgroundList. I published my demonstration and you can check it on this link

https://meet-zoom-r3rhmqshw-leminhcuong2988.vercel.app/meeting

Step:

  • Wait for Zoom to load
  • Click settings and confirm that it is full of virtual background
  • Click on the Update virtual background button
  • Confirm that it still shows full list of virtual background

Here is my code and you can check the full source.