As of v2.0.0, Agora uses UI stores and containers to implement the features of Flexible Classroom on the desktop. A UI store represents a teaching scenario in Flexible Classroom and you can find all the UI stores in the agora-classroom-sdk/src/infra/stores
folder:
one-on-one
folder: Represents the One-to-one Classroom scenario.interactive
folder: Represents the Small Classroom scenario.lecture
folder: Represents the Lecture Hall scenario.Taking the One-to-one Classroom scenario as an example, Agora defines the Edu1v1ClassUIStore
class in one-on-one/index.ts
. This class extends the EduClassroomUIStore
class provided by Agora-edu-core
, which implements the features common to all teaching scenarios in Flexible Classroom. For exclusive features in the One-to-one Classroom scenario, Agora defines OneToOneStreamUIStore
, OneToOneToolbarUIStore
and OneToOneBoardUIStore
, which are used to rewrite the business logic and UI of stream-related features, toolbar, and whiteboard.
EduClassroomUIStore
provides all the basic capabilities in Flexible Classroom. It contains the following sub-stores:
Use BoardUIStore
together with WhiteboardContainer
in the agora-classroom-sdk
library to implement the whiteboard features, such as mounting and unmounting the whiteboard, managing the whiteboard connection, and adjusting the whiteboard size.
aspectRatio: number;
The ratio of the whiteboard width to the classroom viewport width.
heightRatio: number,
The ratio of the whiteboard height to the classroom viewport height.
get boardHeight(): number
The whiteboard height.
get connectionLost(): boolean
Whether the whiteboard connection is lost.
get readyToMount(): boolean
Whether the whiteboard is ready to be mounted on the DOM node.
set setCollectorContainer(collectorContainer: HTMLElement): void
Sets the DOM node to be displayed after the whiteboard is minimized.
Parameter | Description |
---|---|
collectorContainer |
The DOM node to be displayed when the whiteboard is minimized. Users can click this button to maximize the whiteboard. |
joinWhiteboard(): Promise<void>
Connects to Agora's whiteboard server.
joinWhiteboardWhenConfigReady(): void
Connects to Agora's whiteboard server after the whiteboard configuration is initialized.
leaveWhiteboard(): Promise<void>
Disconnects from Agora's whiteboard server.
mount(dom: HTMLDivElement): Promise<void>
Mounts the whiteboard on the DOM node.
Parameter | Description |
---|---|
dom |
The DOM node for mounting the whiteboard. |
rejoinWhiteboard(): Promise<void>
Reconnects to Agora's whiteboard sever.
unmount(): Promise<void>
Unmounts the whiteboard from the DOM node and destroys the whiteboard instance.
To change the whiteboard size, simply edit the board-ui.ts
file in the UI store directory of a teaching scenario. For example, to change the whiteboard size in the Lecture Hall scenario, you can override the uiOverrides
function in agora-classroom-sdk/src/infra/stores/interactive/board-ui.ts
. Sample code:
import { BoardUIStore } from 'agora-edu-core';
export class InteractiveBoardUIStore extends BoardUIStore {
protected get uiOverrides() {
return {
...super.uiOverrides,
// Change the whiteboard ratio
heightRatio: 0.819,
aspectRatio: 0.461,
};
}
}
Use CloudUIStore
together with PersonalResourcesContainer
and PublicResourcesContainer
in the agora-classroom-sdk
library to implement features in the cloud driver, such as getting the list of public and personal files, uploading, selecting, deleting, and opening a file.
currentPersonalResPage: number;
The page number of personal files.
isPersonalResSelectedAll: boolean;
Whether all personal files are selected.
pageSize: number;
The number of files in one page.
get hasSelectedPersonalRes(): boolean
Whether a personal file is selected.
get personalResources(): Map<string, CloudDriveResource>
The list of personal files.
get personalResourcesList(): { checked: boolean; resource: CloudDriveResource }[]
The list of personal files. This property is only for implementing the left selection box.
get personalResourcesTotalNum(): number
The total number of personal files.
get publicResources(): Map<string, CloudDriveResource>
Updates the public file list.
get uploadingProgresses(): UploadItem[]
The progress of uploading a file.
fetchPersonalResources(options: CloudDrivePagingOption): Promise<undefined | { list: never[]; total: number }>
Gets the list of personal files.
Parameter | Description |
---|---|
options |
For page configurations, see CloudDrivePagingOption. |
openResource(resource: CloudDriveResource): Promise<void>
Opens a file.
removePersonalResources(): Promise<void>
Deletes a personal file.
setAllPersonalResourceSelected(val: boolean): void
Selects all personal files.
Parameter | Description |
---|---|
val |
Whether to select all personal files. |
setPersonalResCurrentPage(num: number): void
Sets the page number of the personal file list.
Parameter | Description |
---|---|
num |
The page index. |
setPersonalResourceSelected(resourceUuid: string, val: boolean): void
Parameter | Description |
---|---|
resourceUuid |
The file ID. |
val |
Whether to select a personal file. |
uploadPersonalResource(file: File): Promise<undefined>
Uploads a file to the classroom.
EduShareUIStore
provides common and globally shared UI properties and methods. You can use this class to display prompts and dialogue boxes. Use EduShareUIStore
together with ToastContainer
in the agora-classroom-sdk
library to implement the toasts and with DialogContainer
in the agora-classroom-sdk
library to implement the dialogue boxes.
dialogQueue: DialogType[] = [];
The list of dialogue boxes, which is an array of DialogType objects.
classroomViewportSize = {
width: 0,
height: 0,
};
The size of the classroom viewport.
toastQueue: ToastType[] = [];
The list of toasts, which is an array of ToastType objects.
get navBarHeight()
The height of the navigation bar on the top of the classroom.
addToast(desc: string, type?: ToastTypeEnum)
Add a toast in the classroom.
Parameter | Description |
---|---|
desc |
The toast description. |
type |
The toast type. See ToastTypeEnum. |
removeToast(id: string)
Removes a toast.
Parameter | Description |
---|---|
id |
The toast ID. |
addDialog(category: DialogCategory, props?: any)
Adds a dialogue box to the classroom.
Parameter | Description |
---|---|
category |
The dialogue box type. See DialogCategory. |
removeDialog(id: string)
Removes a dialogue box.
Parameter | Description |
---|---|
id |
The dialogue box ID. |
Whatever the classroom type is, the upper limit on the number of notifications in a classroom is three. If you want to change the upper limit in Lecture Hall to five and leave the upper limit in other types of the classroom unchanged, take the following steps:
Create a share-ui.ts
file in the agora-classroom-sdk/src/infra/stores/lecture
folder.
Define the LectureShareUIStore
class in share-ui.ts
, which extends EduShareUIStore
in agora-edu-core
, and then override the addToast
method. Sample code:
import { EduShareUIStore, ToastTypeEnum } from 'agora-edu-core';
import { action } from 'mobx';
import { v4 as uuidv4 } from 'uuid';
export class LectureShareUIStore extends EduShareUIStore {
@action.bound
addToast(desc: string, type?: ToastTypeEnum) {
const id = uuidv4();
this.toastQueue.push({ id, desc, type });
// Do not show more than five toast messages
if (this.toastQueue.length > 5) {
this.toastQueue = this.toastQueue.splice(1, this.toastQueue.length);
}
return id;
}
}
If you want to change the lower limit on the toast width to 300 px, you need to edit the ToastContainer
in the agora-classroom-sdk
library, which uses the Toast
component in the agora-scenario-ui-kit
folder. Edit success prompt box
in agora-scenario-ui-kit/src/components/toast/index.css
.
Use HandUpUIStore
together with HandsUpContainer
in the agora-classroom-sdk
library to implement the hand-raising features, such as getting the list of who are raising their hands, whether there are users raising their hands, and students raising hands to apply for speak on the "stage".
get hasWaveArmUser(): boolean
Whether a user raises a hand to apply for speaking on the "stage".
get userWaveArmList(): UserWaveArmInfo[]
The list of users who raises a hand.
get waveArmCount(): number
The number of users who raises a hand.
cancelHandUp(): Promise<void>
The student puts down the hand to cancel the application for speaking.
offPodium(userUuid: string): void
The student steps off the "stage".
Parameter | Description |
---|---|
userUuid |
The user ID. |
onPodium(userUuid: string): void
The student goes onto the "stage".
Parameter | Description |
---|---|
userUuid |
The user ID. |
rejectHandUp(userUuid: string): void
The teacher rejects a student's application for speaking on the "stage".
Parameter | Description |
---|---|
userUuid |
The student ID. |
waveArm(teacherUuid: string, duration: -1 | 3): void
A student raises a hand to apply for speaking on the "stage".
Parameter | Description |
---|---|
teacherUuid |
The ID of the teacher. |
duration |
How long the hand is to be raised, in seconds. Sets this parameter as -1 to keep raising the hand. |
Use navigationBarUIStore
to implement the top navigation bar, such as getting class time, classroom status, network quality status, and a list of buttons on the navigation bar.
isRecording: boolean;
Whether the class is being recorded.
get classState(): undefined | ClassState
The class state. See ClassState.
get classStatusText(): string
The text describing the class status.
get classStatusTextColor(): undefined | "#677386" | "#F04C36"
The color of the class status.
get classTimeDuration(): number
The class duration.
get cpuLabel(): string
The percentage of CPU usage.
get cpuValue(): undefined | number
The CPU usage.
get delay(): string
The network delay.
get isBeforeClass(): boolean
Whether the class has been started.
get navigationTitle(): string
The title of the navigation bar.
get packetLoss(): string
The network packet loss rate.
startClass(): Promise<void>
Starts the class.
To change the color and text of the classroom status, use the following code:
export class NavigationBarUIStore extends EduUIStoreBase {
/**
* Change the text that shows on top center of navigation bar
* @returns
*/
@computed
get classStatusText() {
const duration = this.classTimeDuration || 0;
if (duration < 0) {
return `-- : --`;
}
switch (this.classState) {
case ClassState.beforeClass:
return `${transI18n('nav.to_start_in')}${this.formatCountDown(
duration,
TimeFormatType.Timeboard,
)}`;
case ClassState.ongoing:
return `${transI18n('nav.started_elapse')}${this.formatCountDown(
duration,
TimeFormatType.Timeboard,
)}`;
case ClassState.afterClass:
return `${transI18n('nav.ended_elapse')}${this.formatCountDown(
duration,
TimeFormatType.Timeboard,
)}`;
default:
return `-- : --`;
}
}
/**
* Change the color of status text
* @returns
*/
@computed
get classStatusTextColor() {
switch (this.classState) {
case ClassState.beforeClass:
return '#677386';
case ClassState.ongoing:
return '#677386';
case ClassState.afterClass:
return '#F04C36';
default:
return undefined;
}
}
}
export interface DialogType {
id: string;
category: DialogCategory;
props?: any;
}
The dialogue information.
Parameter | Description |
---|---|
id |
The dialogue box ID. |
category |
The dialogue box type. See DialogCategory. |
export interface ToastType {
id: string;
desc: string;
type?: ToastTypeEnum;
}
Parameter | Description |
---|---|
id |
The toast ID. |
desc |
The tip. |
type |
The toast type. See ToastTypeEnum. |
export enum DialogCategory {
CloudDriver,
Roster,
KickOut,
ErrorGeneric,
Confirm,
DeviceSetting,
ScreenPicker,
}
The dialogue box type
Parameter | Description |
---|---|
CloudDriver |
The dialogue box for class files. |
Roster |
The dialogue box for the user list. |
KickOut |
The dialogue box for kicking out users out of the room. |
ErrorGeneric |
The dialogue box for errors. |
Confirm |
The dialogue box for confirmation. |
DeviceSetting |
The dialogue box for device settings. |
ScreenPicker |
The dialogue box for screen selection. |
export type ToastTypeEnum = 'success' | 'error' | 'warning';
The toast type.
Parameter | Description |
---|---|
'success' |
The toast for displaying a success message. |
'error' |
The toast for displaying an error. |
'warning' |
The toast for displaying a warning message. |
export enum ClassState {
beforeClass = 0,
ongoing = 1,
afterClass = 2,
close = 3,
}
The classroom state.
Parameter | Description |
---|---|
beforeClass |
The class has not been started. |
ongoing |
The class is in progress. |
afterClass |
The class is over. |
close |
The room is closed. |
export interface CloudDrivePagingOption {
resourceName?: string;
pageNo: number;
pageSize?: number;
}
The page configuration.
Parameter | Description |
---|---|
resourceName |
The file name. |
pageNo |
The page index. |
pageSize |
The number of files on this page. |