FcrUIScene SDK

Updated

Easily update the look and feel of your classrooms.

FcrUIScene SDK is supported only on the Web platform.

Introduction to UI components

The UI components in Flexible Classroom can be divided into three types: function components, business components, and scenario components.

Function components

Function components are the most basic UI components in Flexible Classroom and are not bound to any business logic. A function component maintains the internal state and logic of a function, such as Button, Modal, Select, or Tree.

Functional components are located in packages/fcr-ui-kit/src/components. The technologies used are react, ts, and storybook. Each functional component folder contains the following files:

  • .tsx: Implements the functionality of the component.
  • .css: Implements the style of the component.
  • .stories.tsx: Enables previewing and debugging the component in Storybook. Developers can run the project through the yarn dev:ui-kit:scene or npm run dev:ui-kit:scene command and preview the function components in Storybook.

The following table lists the function components used in Flexible Classroom:

FolderFunction components
/avatarThe username avatar.
/buttonThe button component.
/checkboxThe checkbox component.
/dialogThe dialog box.
/dropdownThe dropdown selection box.
/inputThe input box.
/input-numberThe number input box.
/paginationThe pagination component is used for displaying long lists. It loads only one page of the data.
/popoverThe pop-up box is used to display more content when the mouse clicks or moves in.
/progressThe progress bar.
/radioThe radio buttons allow users to select one option from a set.
/sliderThe component to drag the progress bar.
/sound-playerThe component for playing audio files.
/svg-imgSVG images.
/tableThe table displays rows of data.
/tabsThe component for switching tabs.
/textareaMulti-line text input box.
/toastThe component for global prompts.
/tooltipThe pop-up box for simple text tips.
/volumeThe component for displaying the volume.

Business components

Business components are the UI components bound to business logic in Flexible Classroom. Most of the business components are composed of multiple function components. Depending on the observable objects and functions from the UI Store, the UI of business components can be automatically changed as the data updates. Taking the hand-raising feature as an example, this business component provides a button for users to raise their hands and ask for permission to speak, and then displays the list of users who have raised their hands.

You can find the business components in packages/fcr-ui-scene/src/containers.

The following table lists the business components used in Flexible Classroom:

Education Scene

FolderBusiness components
/action-barThe bottom function button bar.
/breakout-roomThe Group discussion function.
/cloudThe cloud drive component implements businesses such as uploading or deleting files.
/device-pretestThe device pre-check component implements device pre-check business before entering the classroom, including functions such as obtaining device list information and switching devices.
/device-settingThe component for device settings, such as displaying the list of cameras, microphones, and speakers.
/dialogPop-up windows during the class.
/layoutThe scene UI layout.
/loadingThe loading component and the loading handling logic.
/participantsThe roster component implements services such as viewing student information, processing platform requests, and issuing rewards.
/status-barThe top status bar.
/stream-windowThe window container component responsible for rendering video and video toolbar.
/toastThe toast prompt component.
/widgetThe Widget container component that is responsible for handling logic such as rendering and movement trajectory synchronization of custom Widgets.

Scenario components

A scenario component is composed of multiple business components. Scenario components are located in packages/fcr-ui-scene/src/scenarios. If you want to change the layout of a certain scene, just find the corresponding scenario component and modify it.

FolderScenario components
/classroomGeneral education scene

Relationship between the three types of UI components

The following figure illustrates the relationship between the three types of UI components:

Custom functional components

Add a functional component

To add a new functional component and use it in Flexible Classroom, follow these steps. The following is an example of a Flexible Classroom education scenario:

  1. Create a folder in the packages/fcr-ui-kit/src/components directory for the new functional component that you want to add. This folder should contain the following three files:
    • index.tsx: Implements the functionality of the UI component.
    • index.css: Implements the style of the UI component.
    • index.stories.tsx: Enables previewing and debugging the UI component in Storybook.
  2. After adding the functional component, export this component in packages/fcr-ui-kit/src/components/index.ts. Then you can import this component into your project.

The following example shows how to add a functional component agora-demo:

  1. A new folder is created under the packages/agora-classroom-sdk/src/ui-kit/components directory containing the corresponding files:

     // index.css
        .agora-demo {
            color: red
        }
        // index.tsx
        import React from 'react'
        import './index.css'
    
        export const AgoraDemo = () => {
          return (
            <div className="agora-demo">AgoraDemo</div>
          )
        }
        // index.stories.tsx
        import React from 'react';
        import { Meta } from '@storybook/react';
        import { AgoraDemo } from './index';
    
        const meta: Meta = {
            title: 'Components/AgoraDemo',
            component: AgoraDemo,
        };
        export default meta;
    
        export const Docs = () => (
            <AgoraDemo />
        )

You can see this function component in Storybook, as follows:

Edit an existing functional component

If you want to modify the function and style of an existing functional component, just find the component folder and edit the code to suit your needs. The following examples are provided for your reference.

Change the placeholder color of the input component

To change the color of the placeholder text in the input component, edit the packages/fcr-ui-kit/src/components/input/index.css file as follows:

Before

.fcr-input input::placeholder {
  @apply fcr-text-3;

After

.fcr-input input::placeholder {
    color: skyblue;
    font-size: 14px;
}

Customize business components

Add a business component

To add a new business component and use it in Flexible Classroom, create a folder in packages/fcr-ui-scene/src/containers. The folder should contain the following files:

  • index.tsx: Combines functional components and implements the business logic.
  • index.css: Implements the style of the business component.

After adding the corresponding folder, you can directly import this business component and run the project to see how it looks in Flexible Classroom.

The following example shows how to add a business component that displays the class and network status:

  1. Create a new folder agora-demo under packages/fcr-ui-scene/src/containers, containing the index.tsx and index.css files.

    // index.css
    .agora-demo {
        width: 50%;
        height: 50%;
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        margin: auto;
        border: 1px solid black;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        z-index: 99999999;
        background: #fff;
    }
    .agora-demo-title {
        color: red;
    }
    // index.tsx
    import React from 'react';
    import { observer } from 'mobx-react';
    import './index.css';
    import { useStore } from '@ui-scene/utils/hooks/use-store';
    
    export default observer(function AgoraDemo() {
    const { statusBarUIStore } = useStore();
    return (
        <div className="agora-demo">
        <h1 className="agora-demo-title">This is our new business component</h1>
        <h2>This component is used to display the network status and class status</h2>
        <div>
            Network status: {statusBarUIStore.networkQuality} Network Delay: {statusBarUIStore.delay} Packet loss:
            {statusBarUIStore.packetLoss}
        </div>
        <div>Class status: {statusBarUIStore.classStatusText}</div>
        </div>
    );
    });
  2. Import this component in the interactive small class scene packages/fcr-ui-scene/src/scenarios/classroom.tsx file:

    ...
    import AgoraDemo from '@ui-scene/containers/agora-demo';
    
        const {
            join,
            layoutUIStore: { classroomViewportClassName },
        } = useStore();
        useEffect(() => {
            join();
        }, []);
        return (
            <div className={classroomViewportClassName}>
                ...
                <AgoraDemo />
            </div>
        );
    });

The effect of this business component in Flexible Classroom is as follows:

Change the UI stores

A business component is composed of multiple functional components and depends on UI stores. If you add or modify a business structure, you need to modify the UI Store. This section introduces how to edit the UI stores.

UI stores are located in packages/fcr-ui-scene/src/uistores:

FolderDescription
/cloudThe UI Store common to all scenarios.
/subscriptionThe UI Store customized for small classes.
/action-barThe UI Store customized for large classes.
/breakoutThe UI Store customized for H5 large classes.
/device-settingThe UI Store customized for one-on-one scenarios.
/gallery-viewThe UI Store customized for large classes.
/layoutThe UI Store customized for H5 large classes.
/notificationThe Store customized for one-on-one scenarios.
/participantsThe UI Store customized for large classes.
/presentation-viewThe UI Store customized for H5 large classes.
/status-barThe UI Store customized for one-on-one scenarios.
/streamThe UI Store customized for one-on-one scenarios.
/widgetThe UI Store customized for one-on-one scenarios.
/baseThe base class for all UI Stores.

All UI Stores need to integrate the EduUIStoreBase class in /base. This class provides the initialization method onInstall and the destruction method onDestroy, which are called when the classroom is created and destroyed, respectively.

If you need to modify or expand the functional logic of a business component, you can find the UI Store corresponding to the component and modify it according to the above functional description.

Monitor classroom events

The SDK provides EduEventCenter with the ability to monitor certain events that occur in the classroom. The event monitoring code is generally written in the UI Store onInstall method. The onDestory event monitoring is canceled in the method.

For example, when receiving a reward prompt, displaying a prompt through Toast can be achieved through the following code:

onInstall(): void {
    ...
    // Add a classroom event handler
    EduEventCenter.shared.onClassroomEvents(this._handleClassroomEvent);
}
onDestroy(): void {
    ...
    // Remove a classroom event handler
    EduEventCenter.shared.offClassroomEvents(this._handleClassroomEvent);
}

Add an event handling method for _handleClassroomEvent to NotiticationUIStore:

// Introduce a decorator and bind the This pointer
import { bound } from 'agora-rte-sdk';

...
@bound
private _handleClassroomEvent(event: AgoraEduClassroomEvent, param: any) {
    if (
    event === AgoraEduClassroomEvent.RewardReceived
    ) {
    // An array of recipients and quantities
    const users: { userUuid: string; userName: string }[] = param;
    const userNames = users.map((user) => user.userName);
        // Use ToastApi to pop up prompt box
        ToastApi.open({
        toastProps: {
            type: 'info',
            content: "congratulate" + userNames.join(',') + "Earn rewards",
        },
        });
    }
}

EduEventCenter provides the following classroom events:

Event typeDescription
Ready1 Entered the classroom successfully
Destroyed2 The classroom has been destroyed.
FailedToJoin3 Failed to enter the classroom.
KickOut101 Being kicked out of the room.
TeacherTurnOnMyMic102 Audio streaming permission is enabled.
TeacherTurnOffMyMic103 Audio streaming permission is turned off.
UserAcceptToStage106 Get on the podium.
UserLeaveStage107 Leave the podium.
RewardReceived108 Reward received.
TeacherTurnOnMyCam109 The video streaming permission is enabled.
TeacherTurnOffMyCam110 The video streaming permission has been turned off.
CurrentCamUnplugged111 The current camera device is unplugged
CurrentMicUnplugged112 The current microphone device is unplugged.
CurrentSpeakerUnplugged113 The current speaker is unplugged.
CaptureScreenPermissionDenied 114 No screen capture permission.
BatchRewardReceived117 Receive bulk rewards.
InvitedToGroup118 Receive invitation to join group.
MoveToOtherGroup119 Moved to other groups.
JoinSubRoom120 Join a group.
LeaveSubRoom121 Leave the group.
AcceptedToGroup122 The user accepts to join the group.
UserJoinGroup123 Other users join the group.
UserLeaveGroup124 Other users leave the group.
RejectedToGroup125 The user refuses to join the group.
RTCStateChanged201 RTC connection status change.
ClassStateChanged202 Classroom status changes.

Internationalization

Flexible Classroom has two built-in languages: English en and Chinese zh. If you need to support other languages, such as Spanish, you can do so by modifying the code:

  1. Modify the packages/fcr-ui-scene/src/type.ts file to add Spanish to the Language type:

    // Add Spanish es
    export type Language = 'en' | 'zh' | 'es';
  2. Create a esAr.ts language pack file in packages/fcr-ui-scene/src/resources/translations with the following content:

    // You can copy the content from the enUs.ts file here and modify the corresponding language text
    
        // Language pack Key: Value
        ...
    }
  3. Load the language pack corresponding to the language when the launch method is called:

    // Introduce language pack
    import { esAr } from './resources/translations/esAr.ts';
    ...
    
    static launch(dom: HTMLElement, launchOptions: LaunchOptions) {
        ...
        // Load the language pack corresponding to es
        Promise.all([addResourceBundle('zh', zhCn), addResourceBundle('en', enUs), addResourceBundle('es', esAr)])
        ...
    }
  4. Pass in the corresponding language when calling the launch method:

    FcrUIScene.launch(document.querySelector('#root'), {
        ...
        language: 'es',
        ...
    });