21 | {Array(maxLength)
22 | .fill('agora')
23 | .map((item, index) => (
24 |
= index + 1 ? 1 : 0.1})`,
30 | transition: 'all 0.3s ease-in'
31 | }}
32 | key={`${item}-${index}`}
33 | />
34 | ))}
35 |
36 | );
37 | };
38 |
39 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/root-box/index.tsx:
--------------------------------------------------------------------------------
1 | export { FixedAspectRatioRootBox, TrackArea } from './fixed-aspect-ratio';
2 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/roster/index.tsx:
--------------------------------------------------------------------------------
1 | export { MidRosterBtn, BigRosterBtn } from './button';
2 |
3 | export { RosterContainer } from './user-list';
4 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/roster/user-list.tsx:
--------------------------------------------------------------------------------
1 | import { FC } from 'react';
2 | import { observer } from 'mobx-react';
3 | import { useStore } from '@classroom/infra/hooks/ui-store';
4 | import { Roster, RosterTable } from '@classroom/ui-kit';
5 |
6 | export type RosterContainerProps = {
7 | onClose: () => void;
8 | };
9 |
10 | export const RosterContainer: FC
= observer(({ onClose }) => {
11 | const { rosterUIStore } = useStore();
12 | const {
13 | teacherName,
14 | searchKeyword,
15 | setSearchKeyword,
16 | rosterFunctions: functions,
17 | carouselProps,
18 | uiOverrides,
19 | } = rosterUIStore;
20 |
21 | const { width } = uiOverrides;
22 | return (
23 |
32 |
33 |
34 | );
35 | });
36 |
37 | const RosterTableContainer: FC = observer(() => {
38 | const { rosterUIStore } = useStore();
39 | const { rosterFunctions: functions, userList, clickRowAction } = rosterUIStore;
40 |
41 | return ;
42 | });
43 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/scene-switch/index.css:
--------------------------------------------------------------------------------
1 | .scene-switch-loading {
2 | @apply fcr-bg-background;
3 | display: flex;
4 | justify-content: center;
5 | align-items: center;
6 | flex: 1;
7 | height: 100%;
8 | position: fixed;
9 | width: 100%;
10 | z-index: 999999;
11 | left: 0;
12 | top: 0;
13 | }
14 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/scenes-controller/index.css:
--------------------------------------------------------------------------------
1 | .scenes-controller-container {
2 | position: absolute;
3 | min-width: 170px;
4 | height: 34px !important;
5 | left: 10px;
6 | bottom: 18px;
7 | z-index: 2;
8 | width: auto !important;
9 | border-radius: 20px;
10 | @apply fcr-bg-component;
11 | }
12 |
13 | .scenes-controller-line {
14 | width: 1px;
15 | height: 16px;
16 | border-right: 1px solid #e5e5f0;
17 | margin-left: 6px;
18 | margin-right: 9px;
19 | }
20 |
21 | .scenes-controller-btn-list {
22 | display: flex;
23 | width: 100%;
24 | height: 100%;
25 | box-sizing: border-box;
26 | align-items: center;
27 | padding: 0 10px 0 16px;
28 | }
29 |
30 | .scenes-controller-info {
31 | @apply fcr-text-level2;
32 | font-size: 14px;
33 | user-select: none;
34 | margin: 0 6px;
35 | }
36 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/screen-share/index.css:
--------------------------------------------------------------------------------
1 | .remote-screen-share-container {
2 | position: absolute;
3 | width: 100%;
4 | }
5 |
6 | .local-screen-share-container {
7 | display: flex;
8 | justify-content: center;
9 | position: absolute;
10 | width: 100%;
11 | top: 5px;
12 | z-index: 2;
13 | pointer-events: none;
14 | }
15 |
16 | .local-screen-share-container .stop-button {
17 | font-size: 12px;
18 | width: 100%;
19 | height: 100%;
20 | display: flex;
21 | border-radius: 5px;
22 | color: #357bf6;
23 | background: white;
24 | box-shadow: 0px 2px 8px 0px rgb(47 65 146 / 15%);
25 | align-items: center;
26 | justify-content: center;
27 | outline: none;
28 | pointer-events: all;
29 | }
30 |
31 | .local-screen-share-container .stop-button:hover {
32 | color: white;
33 | background: #357bf6;
34 | }
35 |
36 | .local-screen-share-container .stop-button > span {
37 | display: flex;
38 | margin-left: 2px;
39 | }
40 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/screen-share/index.mobile.tsx:
--------------------------------------------------------------------------------
1 | import { useLectureH5UIStores } from '@classroom/infra/hooks/ui-store';
2 | import classnames from 'classnames';
3 | import { observer } from 'mobx-react';
4 | import './index.css';
5 | import { ScreenShareRemoteTrackPlayer } from '.';
6 |
7 | export const ScreenShareContainerMobile = observer(() => {
8 | const {
9 | boardUIStore: { boardContainerHeight },
10 | streamUIStore: { screenShareStream },
11 | } = useLectureH5UIStores();
12 |
13 | const remotecls = classnames('remote-screen-share-container', 'fcr-absolute', 'fcr-top-0');
14 |
15 | return screenShareStream ? (
16 |
17 |
18 |
19 | ) : null;
20 | });
21 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/stream-window/index.css:
--------------------------------------------------------------------------------
1 | .stream-window {
2 | pointer-events: all;
3 | }
4 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/stream/assets/audio/reward.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/infra/capabilities/containers/stream/assets/audio/reward.mp3
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/stream/assets/room-placholder-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/infra/capabilities/containers/stream/assets/room-placholder-bg.jpg
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/stream/assets/svga/hands-up.svga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/infra/capabilities/containers/stream/assets/svga/hands-up.svga
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/stream/assets/svga/reward.svga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/infra/capabilities/containers/stream/assets/svga/reward.svga
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/stream/assets/svga/video-loadings.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/infra/capabilities/containers/stream/assets/svga/video-loadings.gif
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/stream/assets/svga/video-play.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/stream/assets/svga/wave-arm.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/infra/capabilities/containers/stream/assets/svga/wave-arm.gif
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/toast/index.css:
--------------------------------------------------------------------------------
1 | .toast-animation-exit {
2 | opacity: 0;
3 | }
4 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/toast/index.mobile.css:
--------------------------------------------------------------------------------
1 | .fcr-mobile-toast-container {
2 | position: absolute;
3 |
4 | bottom: 130px;
5 | left: 0;
6 | right: 0;
7 | margin: auto;
8 | transition: all 0.2s;
9 | pointer-events: none;
10 | text-align: center;
11 | }
12 | .fcr-mobile-toast-container.fcr-mobile-toast-container-landscape {
13 | bottom: 60px;
14 | }
15 | .fcr-mobile-toast-container > div {
16 | padding: 0 14px;
17 | font-weight: 500;
18 | font-size: 14px;
19 | box-shadow: 0px 0px 20px -8px rgba(0, 0, 0, 0.14);
20 | border-radius: 50px;
21 | min-height: 36px;
22 | color: #fff;
23 | display: inline-flex;
24 | align-items: center;
25 | }
26 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/toast/index.mobile.tsx:
--------------------------------------------------------------------------------
1 | import { useStore } from '@classroom/infra/hooks/ui-store';
2 | import { Scheduler } from 'agora-rte-sdk';
3 | import { observer } from 'mobx-react';
4 | import { useEffect, useRef, useState } from 'react';
5 | import { ComponentLevelRulesMobile } from '../../config';
6 | import './index.mobile.css';
7 | export const ToastContainerMobile = observer(() => {
8 | const {
9 | shareUIStore: { toastQueue, isLandscape },
10 | } = useStore();
11 | const currToast = toastQueue[Math.max(toastQueue.length - 1, 0)];
12 |
13 | const [visible, setVisible] = useState(false);
14 | const delayTaskRef = useRef(null);
15 | useEffect(() => {
16 | if (currToast) {
17 | delayTaskRef.current?.stop();
18 | setVisible(true);
19 | delayTaskRef.current = Scheduler.shared.addDelayTask(() => {
20 | setVisible(false);
21 | }, 3000);
22 | }
23 | }, [toastQueue, currToast]);
24 | return (
25 |
33 |
34 | {currToast?.desc}
35 |
36 |
37 | );
38 | });
39 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/toast/index.tsx:
--------------------------------------------------------------------------------
1 | import { observer } from 'mobx-react';
2 | import { Toast } from '@classroom/ui-kit';
3 | import { useStore } from '@classroom/infra/hooks/ui-store';
4 | import { TransitionGroup, CSSTransition } from 'react-transition-group';
5 | import './index.css';
6 | import { ToastType } from '@classroom/infra/stores/common/share';
7 |
8 | export const ToastContainer = observer(() => {
9 | const { shareUIStore } = useStore();
10 | const { toastQueue, removeToast } = shareUIStore;
11 |
12 | return (
13 |
14 | {toastQueue.map((value: ToastType, idx: number) => (
15 |
16 | {
20 | removeToast(value.id);
21 | }}>
22 | {value.desc}
23 |
24 |
25 | ))}
26 |
27 | );
28 | });
29 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/toolbar/board-cleaners/index.tsx:
--------------------------------------------------------------------------------
1 | import { observer } from 'mobx-react';
2 | import { useStore } from '@classroom/infra/hooks/ui-store';
3 | import { SvgImg, BoardCleaners, SvgIconEnum } from '@classroom/ui-kit';
4 | import { useI18n } from 'agora-common-libs';
5 | import { InteractionStateColors } from '@classroom/ui-kit/utilities/state-color';
6 |
7 | export const BoardCleanersContainer = observer(() => {
8 | const { toolbarUIStore } = useStore();
9 | const t = useI18n();
10 | const { boardCleanerItems, handleBoradCleaner, activeTool } = toolbarUIStore;
11 |
12 | const mappedItems = boardCleanerItems.map((item) => {
13 | const { id, iconType, name } = item;
14 | const isActive = activeTool === id;
15 |
16 | return {
17 | id,
18 | icon: iconType ? (
19 |
24 | ) : (
25 |
26 | ),
27 | name,
28 | };
29 | });
30 |
31 | return (
32 |
41 | );
42 | });
43 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/toolbar/slice/index.tsx:
--------------------------------------------------------------------------------
1 | import { observer } from 'mobx-react';
2 | import { useStore } from '@classroom/infra/hooks/ui-store';
3 | import { SvgImg, Slice, SvgIconEnum } from '@classroom/ui-kit';
4 | import { useI18n } from 'agora-common-libs';
5 |
6 | export const SliceContainer = observer(() => {
7 | const { toolbarUIStore } = useStore();
8 | const t = useI18n();
9 | const { sliceItems, handleSliceItem } = toolbarUIStore;
10 |
11 | const mappedItems = sliceItems.map((item) => {
12 | const { id, iconType, name } = item;
13 | return {
14 | id,
15 | icon: iconType ? : ,
16 | name,
17 | };
18 | });
19 |
20 | return (
21 |
28 | );
29 | });
30 |
--------------------------------------------------------------------------------
/src/infra/capabilities/containers/widget/index.css:
--------------------------------------------------------------------------------
1 | .widget-container {
2 | top: 0;
3 | left: 0;
4 | width: 100%;
5 | height: 100%;
6 | position: absolute;
7 | pointer-events: none;
8 | }
9 | .widget-container * {
10 | pointer-events: all;
11 | }
12 |
13 | .widget-slot-chat {
14 | /* @apply bg-background; */
15 | }
16 |
17 | .fcr-countdown-mobile-widget {
18 | position: relative;
19 | }
20 | .whiteboard-mobile-container .netless-whiteboard-wrapper {
21 | background-color: #fff;
22 |
23 | border-color: #fff;
24 | pointer-events: none;
25 | }
26 |
--------------------------------------------------------------------------------
/src/infra/capabilities/scenarios/big-class-mobile/after-class.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/infra/capabilities/scenarios/big-class-mobile/after-class.png
--------------------------------------------------------------------------------
/src/infra/capabilities/scenarios/big-class-mobile/generic-error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/infra/capabilities/scenarios/big-class-mobile/generic-error.png
--------------------------------------------------------------------------------
/src/infra/capabilities/scenarios/room/index.tsx:
--------------------------------------------------------------------------------
1 | import { useStore } from '@classroom/infra/hooks/ui-store';
2 | import { useEffectOnce } from '@classroom/infra/hooks/utilites';
3 | import { observer } from 'mobx-react';
4 | import React, { FC } from 'react';
5 |
6 | type Props = {
7 | children?: React.ReactNode;
8 | };
9 |
10 | const Room: FC = observer(({ children }) => {
11 | const { join } = useStore();
12 |
13 | useEffectOnce(() => {
14 | join();
15 | });
16 |
17 | return {children};
18 | });
19 |
20 | export default Room;
21 |
--------------------------------------------------------------------------------
/src/infra/contexts/ui-store-factory.ts:
--------------------------------------------------------------------------------
1 | import { EduClassroomStore, EduRoomTypeEnum } from 'agora-edu-core';
2 | import { EduClassroomUIStore } from '../stores/common';
3 | import { EduInteractiveUIClassStore } from '../stores/interactive';
4 | import { EduLectureUIStore } from '../stores/lecture';
5 | import { EduLectureH5UIStore } from '../stores/lecture-mobile';
6 | import { Edu1v1ClassUIStore } from '../stores/one-on-one';
7 |
8 | export class EduUIStoreFactory {
9 | static createWithType(roomType: EduRoomTypeEnum, store: EduClassroomStore): EduClassroomUIStore {
10 | switch (roomType) {
11 | case EduRoomTypeEnum.Room1v1Class:
12 | return new Edu1v1ClassUIStore(store);
13 | case EduRoomTypeEnum.RoomSmallClass:
14 | return new EduInteractiveUIClassStore(store);
15 | case EduRoomTypeEnum.RoomBigClass:
16 | return new EduLectureUIStore(store);
17 | default:
18 | throw new Error(`No supported UIStore for room type: ${roomType}`);
19 | }
20 | }
21 | static createWithTypeH5(
22 | roomType: EduRoomTypeEnum,
23 | store: EduClassroomStore,
24 | ): EduClassroomUIStore {
25 | switch (roomType) {
26 | case EduRoomTypeEnum.RoomBigClass:
27 | return new EduLectureH5UIStore(store);
28 | default:
29 | throw new Error(`No supported UIStore for room type: ${roomType}`);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/infra/hooks/cabinet.ts:
--------------------------------------------------------------------------------
1 | import { useCallback } from 'react';
2 | import { useStore } from './ui-store';
3 |
4 | export const useExtensionCabinets = () => {
5 | const { widgetUIStore, classroomStore } = useStore();
6 |
7 | const openExtensionCabinet = useCallback((id: string, remote = true) => {
8 | const nextZIndex =
9 | classroomStore.widgetStore.widgetController?.zIndexController.incrementZIndex();
10 |
11 | const trackProps = { position: { xaxis: 0.5, yaxis: 0.5 }, zIndex: nextZIndex };
12 | widgetUIStore.createWidget(id, {
13 | trackProperties: trackProps,
14 | userProperties: {},
15 | properties: {},
16 | });
17 |
18 | if (remote) {
19 | classroomStore.widgetStore.widgetController?.setWidegtActive(id, trackProps);
20 | }
21 | }, []);
22 |
23 | const isInstalled = useCallback((id: string) => {
24 | const names = widgetUIStore.registeredWidgetNames;
25 | return names.includes(id);
26 | }, []);
27 |
28 | return {
29 | openExtensionCabinet,
30 | isInstalled,
31 | };
32 | };
33 |
--------------------------------------------------------------------------------
/src/infra/hooks/index.ts:
--------------------------------------------------------------------------------
1 | import { DependencyList, useEffect, useMemo, useRef } from 'react';
2 | import { clickAnywhere } from '../utils';
3 | import { interactionThrottleHandler } from '../utils/interaction';
4 |
5 | export const useInteractionThrottleHandler = (
6 | func: T,
7 | options: { limitMs?: number; limitFunc?: () => void },
8 | deps: DependencyList,
9 | ) => {
10 | return useMemo(() => {
11 | return interactionThrottleHandler(func, options.limitFunc || (() => {}), {
12 | limitMs: options.limitMs,
13 | }) as T;
14 | }, deps);
15 | };
16 |
17 | export const useClickAnywhere = (cb: () => void) => {
18 | const ref = useRef(null);
19 |
20 | useEffect(() => {
21 | if (ref.current) {
22 | return clickAnywhere(ref.current, cb);
23 | }
24 | }, []);
25 |
26 | return ref;
27 | };
28 |
--------------------------------------------------------------------------------
/src/infra/hooks/utilites.ts:
--------------------------------------------------------------------------------
1 | import { useRef, useEffect } from 'react';
2 |
3 | export const useInterval = (fun: CallableFunction, delay: number, start: boolean) => {
4 | const myRef = useRef(null);
5 | useEffect(() => {
6 | myRef.current = fun;
7 | }, [fun]);
8 | useEffect(() => {
9 | const timer = setInterval(() => {
10 | myRef.current(timer);
11 | }, delay);
12 | return () => clearInterval(timer);
13 | }, [start, delay]);
14 | };
15 |
16 | export const useTimout = (fun: CallableFunction, delay: number, start: boolean) => {
17 | const myRef = useRef(null);
18 | useEffect(() => {
19 | myRef.current = fun;
20 | }, [fun]);
21 | useEffect(() => {
22 | let timer: null | ReturnType = null;
23 | if (start) {
24 | timer = setTimeout(() => {
25 | myRef.current(timer);
26 | }, delay);
27 | }
28 | return () => {
29 | timer && clearTimeout(timer);
30 | };
31 | }, [start, delay]);
32 | };
33 |
34 | export const useEffectOnce = (effect: any) => {
35 | useEffect(effect, []);
36 | };
37 |
--------------------------------------------------------------------------------
/src/infra/stores/common/cloud-drive/type.ts:
--------------------------------------------------------------------------------
1 | export interface CloudDriveResourceConvertProgress {
2 | prefix?: string;
3 | status: 'Waiting' | 'Converting' | 'Finished' | 'Fail';
4 | totalPageSize: number;
5 | convertedPageSize: number;
6 | convertedPercentage: number;
7 | convertedFileList: {
8 | name?: string;
9 | ppt: {
10 | preview?: string;
11 | src: string;
12 | width: number;
13 | height: number;
14 | };
15 | }[];
16 | currentStep: string;
17 | previews: Record;
18 | images: Record<
19 | number,
20 | {
21 | width: number;
22 | height: number;
23 | url: string;
24 | }
25 | >;
26 | }
27 |
--------------------------------------------------------------------------------
/src/infra/stores/common/hand-up/type.ts:
--------------------------------------------------------------------------------
1 | export enum OnPodiumStateEnum {
2 | /**
3 | * 正在台上
4 | */
5 | onPodiuming = 1,
6 | /**
7 | * 正在挥手
8 | */
9 | waveArming = 2,
10 | /**
11 | * 正在被邀请
12 | */
13 | inviteding = 3,
14 | /**
15 | * 空闲中
16 | */
17 | idleing = 4,
18 | }
19 |
--------------------------------------------------------------------------------
/src/infra/stores/common/layout/helper.ts:
--------------------------------------------------------------------------------
1 | export const getRootDimensions = (containerNode: Window | HTMLElement) => {
2 | const height =
3 | containerNode instanceof Window ? containerNode.innerHeight : containerNode.clientHeight;
4 | const width =
5 | containerNode instanceof Window ? containerNode.innerWidth : containerNode.clientWidth;
6 | return { width, height };
7 | };
8 |
--------------------------------------------------------------------------------
/src/infra/stores/common/pretest/helper.ts:
--------------------------------------------------------------------------------
1 | const virtualSoundCardPatternList = [/BlackHole/i, /SoundFlower/i, /AgoraALD/i];
2 |
3 | export const matchVirtualSoundCardPattern = (deviceName: string) => {
4 | return virtualSoundCardPatternList.reduce((prev, pattern) => {
5 | pattern.test(deviceName) && (prev = true);
6 | return prev;
7 | }, false);
8 | };
9 |
--------------------------------------------------------------------------------
/src/infra/stores/common/pretest/type.ts:
--------------------------------------------------------------------------------
1 | export enum DeviceStateChangedReason {
2 | cameraFailed = 'pretest.device_not_working',
3 | micFailed = 'pretest.device_not_working',
4 | newDeviceDetected = 'new_device_detected',
5 | cameraUnplugged = 'pretest.camera_move_out',
6 | micUnplugged = 'pretest.mic_move_out',
7 | playbackUnplugged = 'pretest.playback_move_out',
8 | }
9 |
--------------------------------------------------------------------------------
/src/infra/stores/common/roster/type.ts:
--------------------------------------------------------------------------------
1 | import { EduRoleTypeEnum } from 'agora-edu-core';
2 |
3 | export enum DeviceState {
4 | // 设备开启
5 | enabled,
6 | // 设备关闭
7 | disabled,
8 | // 设备不可用
9 | unavailable,
10 | // 设备禁用
11 | unauthorized,
12 | }
13 |
14 | export type Operation =
15 | | 'podium'
16 | | 'grant-board'
17 | | 'camera'
18 | | 'microphone'
19 | | 'kick'
20 | | 'chat'
21 | | 'star'
22 | | 'supervise-student';
23 |
24 | export type Operations = Partial>;
25 |
26 | export type Profile = {
27 | uid: string | number;
28 | isOnPodium: boolean;
29 | cameraState: DeviceState;
30 | microphoneState: DeviceState;
31 | };
32 |
33 | /**
34 | * 分页查询用户参数
35 | */
36 | export interface FetchUserParam {
37 | /**
38 | * 下一页的ID
39 | */
40 | nextId: string | number | null | undefined;
41 | /**
42 | * 一页查询多少条
43 | */
44 | count: number;
45 | /**
46 | * 筛选类型 0:全部 1:禁言
47 | */
48 | type: FetchUserType;
49 | /**
50 | * 查询角色
51 | */
52 | role: EduRoleTypeEnum;
53 | /**
54 | * 查询的用户名称,模糊查询
55 | */
56 | userName?: string;
57 | }
58 |
59 | /**
60 | * 筛选用户类型 0:全部 1:禁言
61 | */
62 | export enum FetchUserType {
63 | /**
64 | * 筛选全部的用户
65 | */
66 | all = '0',
67 | /**
68 | * 筛选禁言的用户
69 | */
70 | mute = '1',
71 | }
72 |
--------------------------------------------------------------------------------
/src/infra/stores/common/stream-window/type.ts:
--------------------------------------------------------------------------------
1 | export interface StreamWindow {
2 | x: number;
3 | y: number;
4 | width: number;
5 | height: number;
6 | /**
7 | * view 层级关系
8 | */
9 | zIndex: number;
10 | /**
11 | * 是否填充到多视频区域
12 | */
13 | contain: boolean;
14 | }
15 |
16 | export type StreamWindowBounds = Omit;
17 |
18 | export interface WidgetTrackStruct {
19 | state: number;
20 | position: { xaxis: number; yaxis: number };
21 | size: { width: number; height: number };
22 | extra: {
23 | contain: boolean;
24 | zIndex: number;
25 | userUuid: string;
26 | [key: string]: any;
27 | };
28 | }
29 |
--------------------------------------------------------------------------------
/src/infra/stores/common/subscription/type.ts:
--------------------------------------------------------------------------------
1 | import {
2 | AgoraRteScene,
3 | AgoraRteVideoSourceType,
4 | AgoraStream,
5 | AGRtcConnectionType,
6 | } from 'agora-rte-sdk';
7 |
8 | export type RemoteStreamMuteStatus = {
9 | muteVideo?: boolean;
10 | muteAudio?: boolean;
11 | };
12 |
13 | export type LocalVideoStreamSubscribeOption = {
14 | mute: boolean;
15 | connectionType: AGRtcConnectionType;
16 | sourceType: AgoraRteVideoSourceType;
17 | };
18 |
--------------------------------------------------------------------------------
/src/infra/stores/common/type.ts:
--------------------------------------------------------------------------------
1 | export enum OrientationEnum {
2 | portrait = 'portrait',
3 | landscape = 'landscape',
4 | }
5 |
6 | export type ConfirmDialogAction = 'ok' | 'cancel';
7 |
8 | export enum LayoutMaskCode {
9 | None = 0,
10 | StageVisible = 1,
11 | VideoGalleryVisible = 2,
12 | }
13 |
--------------------------------------------------------------------------------
/src/infra/stores/interactive/board.ts:
--------------------------------------------------------------------------------
1 | import { BoardUIStore } from '../common/board';
2 |
3 | export class InteractiveBoardUIStore extends BoardUIStore {
4 | protected get uiOverrides() {
5 | return {
6 | ...super.uiOverrides,
7 | heightRatio: 0.84,
8 | };
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/infra/stores/interactive/index.ts:
--------------------------------------------------------------------------------
1 | import { EduClassroomStore } from 'agora-edu-core';
2 | import { EduClassroomUIStore } from '../common';
3 | import { InteractiveBoardUIStore } from './board';
4 | import { InteractiveRoomStreamUIStore } from './stream';
5 |
6 | export class EduInteractiveUIClassStore extends EduClassroomUIStore {
7 | constructor(store: EduClassroomStore) {
8 | super(store);
9 | this._streamUIStore = new InteractiveRoomStreamUIStore(store, this.shareUIStore, this._getters);
10 | this._boardUIStore = new InteractiveBoardUIStore(store, this.shareUIStore, this._getters);
11 | }
12 |
13 | get streamUIStore() {
14 | return this._streamUIStore as InteractiveRoomStreamUIStore;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/infra/stores/lecture-mobile/index.ts:
--------------------------------------------------------------------------------
1 | import { EduClassroomStore } from 'agora-edu-core';
2 | import { LectureH5BoardUIStore } from './board';
3 | import { LectureH5RoomStreamUIStore } from './stream';
4 | import { LectureH5LayoutUIStore } from './layout';
5 | import { EduClassroomUIStore } from '../common';
6 | import { LectureH5DeviceSettingUIStore } from './device-setting';
7 |
8 | export class EduLectureH5UIStore extends EduClassroomUIStore {
9 | constructor(store: EduClassroomStore) {
10 | super(store);
11 | this._streamUIStore = new LectureH5RoomStreamUIStore(store, this.shareUIStore, this._getters);
12 | this._boardUIStore = new LectureH5BoardUIStore(store, this.shareUIStore, this._getters);
13 | this._layoutUIStore = new LectureH5LayoutUIStore(store, this.shareUIStore, this._getters);
14 | this._deviceSettingUIStore = new LectureH5DeviceSettingUIStore(
15 | store,
16 | this.shareUIStore,
17 | this._getters,
18 | );
19 | }
20 |
21 | get streamUIStore() {
22 | return this._streamUIStore as LectureH5RoomStreamUIStore;
23 | }
24 |
25 | get boardUIStore() {
26 | return this._boardUIStore as LectureH5BoardUIStore;
27 | }
28 |
29 | get layoutUIStore() {
30 | return this._layoutUIStore as LectureH5LayoutUIStore;
31 | }
32 | get deviceSettingUIStore() {
33 | return this._deviceSettingUIStore as LectureH5DeviceSettingUIStore;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/infra/stores/lecture/board.ts:
--------------------------------------------------------------------------------
1 | import { EduClassroomConfig } from 'agora-edu-core';
2 | import { reaction } from 'mobx';
3 | import { BoardUIStore } from '../common/board';
4 |
5 | export class LectureBoardUIStore extends BoardUIStore {
6 | protected get uiOverrides() {
7 | return {
8 | ...super.uiOverrides,
9 | heightRatio: 1,
10 | };
11 | }
12 | onInstall(): void {
13 | super.onInstall();
14 | this._disposers.push(
15 | reaction(
16 | () => this.classroomStore.roomStore.acceptedList,
17 | (acceptedList) => {
18 | const { userUuid } = EduClassroomConfig.shared.sessionInfo;
19 | const isOnPodium = acceptedList.some((item) => item.userUuid === userUuid);
20 | const isGranted = this.boardApi.grantedUsers.has(userUuid);
21 |
22 | if (!isOnPodium && isGranted) {
23 | this.boardApi.grantPrivilege(userUuid, false);
24 | }
25 | },
26 | ),
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/infra/stores/lecture/index.ts:
--------------------------------------------------------------------------------
1 | import { EduClassroomStore } from 'agora-edu-core';
2 | import { EduClassroomUIStore } from '../common';
3 | import { LectureBoardUIStore } from './board';
4 | import { LectureRosterUIStore } from './roster';
5 | import { LectureRoomStreamUIStore } from './stream';
6 | import { LectrueToolbarUIStore } from './toolbar';
7 |
8 | export class EduLectureUIStore extends EduClassroomUIStore {
9 | constructor(store: EduClassroomStore) {
10 | super(store);
11 | this._streamUIStore = new LectureRoomStreamUIStore(store, this.shareUIStore, this._getters);
12 | this._rosterUIStore = new LectureRosterUIStore(store, this.shareUIStore, this._getters);
13 | this._boardUIStore = new LectureBoardUIStore(store, this.shareUIStore, this._getters);
14 | this._toolbarUIStore = new LectrueToolbarUIStore(store, this.shareUIStore, this._getters);
15 | }
16 |
17 | get streamUIStore() {
18 | return this._streamUIStore as LectureRoomStreamUIStore;
19 | }
20 |
21 | get rosterUIStore() {
22 | return this._rosterUIStore as LectureRosterUIStore;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/infra/stores/one-on-one/index.ts:
--------------------------------------------------------------------------------
1 | import { EduClassroomStore } from 'agora-edu-core';
2 | import { EduClassroomUIStore } from '../common';
3 | import { OneToOneStreamUIStore } from './stream';
4 | import { OneToOneToolbarUIStore } from './toolbar';
5 |
6 | export class Edu1v1ClassUIStore extends EduClassroomUIStore {
7 | constructor(store: EduClassroomStore) {
8 | super(store);
9 | this._streamUIStore = new OneToOneStreamUIStore(store, this.shareUIStore, this._getters);
10 | this._toolbarUIStore = new OneToOneToolbarUIStore(store, this.shareUIStore, this._getters);
11 | }
12 |
13 | get streamUIStore() {
14 | return this._streamUIStore as OneToOneStreamUIStore;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/infra/stores/one-on-one/stream.ts:
--------------------------------------------------------------------------------
1 | import { StreamUIStore } from '../common/stream';
2 |
3 | export class OneToOneStreamUIStore extends StreamUIStore {
4 | private _teacherWidthRatio = 0.217;
5 |
6 | get toolbarPlacement(): 'bottom' | 'left' {
7 | return 'left';
8 | }
9 |
10 | get toolbarOffset(): number[] {
11 | return [10, 0];
12 | }
13 |
14 | get fullScreenToolbarOffset(): number[] {
15 | return [0, -58];
16 | }
17 |
18 | get videoStreamSize() {
19 | const width = this.shareUIStore.classroomViewportSize.width * this._teacherWidthRatio;
20 |
21 | const height = (9 / 16) * width;
22 |
23 | return { width, height };
24 | }
25 |
26 | onInstall(): void {
27 | super.onInstall();
28 |
29 | this.classroomStore.mediaStore.setMirror(true);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/infra/utils/async-queue.ts:
--------------------------------------------------------------------------------
1 | import { bound, Log, Logger } from 'agora-rte-sdk';
2 | import sortBy from 'lodash/sortBy';
3 |
4 | export enum WorkPriority {
5 | high,
6 | normal,
7 | low,
8 | }
9 |
10 | type AsyncWork = {
11 | priority: WorkPriority;
12 | run: () => Promise;
13 | fail: (e: Error) => void;
14 | };
15 |
16 | @Log.attach()
17 | class AsyncQueue {
18 | logger!: Logger;
19 | private _handle?: NodeJS.Timeout;
20 | private _queue: AsyncWork[] = [];
21 |
22 | runNextTick(run: () => Promise, fail: (e: Error) => void, priority = WorkPriority.normal) {
23 | this._queue.push({ run, fail, priority });
24 |
25 | this.sortWorks();
26 |
27 | if (this._handle) {
28 | clearTimeout(this._handle);
29 | }
30 | this._handle = setTimeout(this._execute);
31 | }
32 |
33 | sortWorks() {
34 | this._queue = sortBy(this._queue, ['priority']);
35 | }
36 |
37 | @bound
38 | private async _execute() {
39 | const copy = [...this._queue];
40 | this._queue = [];
41 |
42 | for (let i = 0; i < copy.length; i++) {
43 | const { run, fail } = copy[i];
44 | try {
45 | await run();
46 | } catch (e) {
47 | fail(e as Error);
48 | break;
49 | }
50 | }
51 | this.logger.info('async works done');
52 | }
53 | }
54 |
55 | export default new AsyncQueue();
56 |
--------------------------------------------------------------------------------
/src/infra/utils/error.ts:
--------------------------------------------------------------------------------
1 | import { AGError } from 'agora-rte-sdk';
2 | import { transI18n } from 'agora-common-libs';
3 |
4 | /**
5 | * 返回错误提示信息
6 | * @param error
7 | * @returns
8 | */
9 | export const getEduErrorMessage = (error: Error) => {
10 | if (error instanceof AGError && error.codeList && error.codeList.length) {
11 | const code = error.codeList[error.codeList.length - 1];
12 |
13 | if (error.servCode && error.servCode !== -1) {
14 | return transI18n(`edu_serv_error.${error.servCode}`);
15 | } else {
16 | return transI18n(`edu_error.${code}`);
17 | }
18 | }
19 |
20 | return null;
21 | };
22 |
23 | /**
24 | * 如果Error中包含有服务端错误码,则返回服务端错误码
25 | * @param error
26 | * @returns
27 | */
28 | export const getErrorServCode = (error: Error) => {
29 | if (error instanceof AGError) {
30 | return error.servCode;
31 | }
32 | };
33 |
--------------------------------------------------------------------------------
/src/infra/utils/event-center.ts:
--------------------------------------------------------------------------------
1 | import { AGEventEmitter } from 'agora-rte-sdk';
2 |
3 | export const AgoraEduClassRoomUIType = 'classroom-ui-events';
4 |
5 | export enum AgoraEduClassroomUIEvent {
6 | offStreamWindow = 'off-stream-window',
7 | toggleTeacherStreamWindow = 'toggle-teacher-stream-window',
8 | toggleWhiteboard = 'toggle-whiteboard',
9 | dragFileOverBoard = 'drag-file-over-board',
10 | dropFileOnBoard = 'drop-file-on-board',
11 | }
12 |
13 | type EventCallback = (type: AgoraEduClassroomUIEvent, ...args: any[]) => void;
14 |
15 | export class EduEventUICenter extends AGEventEmitter {
16 | static shared: EduEventUICenter = new EduEventUICenter();
17 | private _callbacks: Set = new Set();
18 | constructor() {
19 | super();
20 | }
21 |
22 | emitClassroomUIEvents(type: AgoraEduClassroomUIEvent, ...args: any[]) {
23 | this.emit(AgoraEduClassRoomUIType, type, ...args);
24 | }
25 |
26 | onClassroomUIEvents(cb: EventCallback) {
27 | if (this._callbacks.has(cb)) {
28 | return;
29 | }
30 | this._callbacks.add(cb);
31 | this.on(AgoraEduClassRoomUIType, cb);
32 | }
33 |
34 | offClassroomUIEvents(cb: EventCallback) {
35 | this._callbacks.delete(cb);
36 | this.off(AgoraEduClassRoomUIType, cb);
37 | }
38 |
39 | cleanup() {
40 | this._callbacks.forEach((cb) => {
41 | this.offClassroomUIEvents(cb);
42 | });
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/infra/utils/extract.ts:
--------------------------------------------------------------------------------
1 | import { EduStream, EduUserStruct } from 'agora-edu-core';
2 | import { AgoraRteVideoSourceType } from 'agora-rte-sdk';
3 |
4 | /**
5 | * 提取流列表
6 | */
7 | export const extractUserStreams = (
8 | users: Map,
9 | streamByUserUuid: Map>,
10 | streamByStreamUuid: Map,
11 | sourceTypes: AgoraRteVideoSourceType[],
12 | ) => {
13 | const streams = new Set();
14 | for (const user of users.values()) {
15 | const streamUuids = streamByUserUuid.get(user.userUuid) || new Set();
16 | for (const streamUuid of streamUuids) {
17 | const stream = streamByStreamUuid.get(streamUuid);
18 |
19 | if (stream && sourceTypes.includes(stream.videoSourceType)) {
20 | streams.add(stream);
21 | }
22 | }
23 | }
24 | return streams;
25 | };
26 |
--------------------------------------------------------------------------------
/src/infra/utils/interaction.ts:
--------------------------------------------------------------------------------
1 | import { transI18n } from 'agora-common-libs';
2 |
3 | type Delegate = (message: string) => void;
4 |
5 | export const interactionThrottleHandler = (
6 | func: T,
7 | limitFunc: Delegate,
8 | options?: {
9 | limitMs?: number;
10 | message?: string;
11 | },
12 | ) => {
13 | const { limitMs = 200, message = transI18n('toast.interaction_too_frequent') } = options || {};
14 |
15 | let last = Date.now();
16 | // @ts-ignore
17 | return ((...args: unknown[]) => {
18 | if (Date.now() - last < limitMs) {
19 | limitFunc(message);
20 | } else {
21 | // @ts-ignore
22 | func(...args);
23 | last = Date.now();
24 | }
25 | }) as T;
26 | };
27 |
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.css';
2 | declare module '*.svga';
3 | declare module '*.svg';
4 | declare module '*.json';
5 | declare module '*.mp3';
6 | declare module '*.mp4';
7 | declare module '*.png';
8 | declare module '*.gif';
9 | declare module '*.jpg';
10 |
--------------------------------------------------------------------------------
/src/ui-kit/components/button/abutton.css:
--------------------------------------------------------------------------------
1 | .fcr-theme.ant-btn {
2 | border-radius: 8px;
3 | }
4 |
--------------------------------------------------------------------------------
/src/ui-kit/components/button/abutton.tsx:
--------------------------------------------------------------------------------
1 | import Button, { ButtonProps } from 'antd/lib/button';
2 | import { FC, PropsWithChildren } from 'react';
3 | import './abutton.css';
4 | type AButtonProps = Pick;
5 |
6 | export const AButton: FC> = ({ className = '', ...props }) => {
7 | return ;
8 | };
9 |
--------------------------------------------------------------------------------
/src/ui-kit/components/card/index.css:
--------------------------------------------------------------------------------
1 | .fcr-card {
2 | box-shadow: 0px 2px 6px 0px rgba(47, 65, 146, 0.15);
3 | @apply fcr-bg-component fcr-flex fcr-justify-center fcr-items-center;
4 | }
5 |
--------------------------------------------------------------------------------
/src/ui-kit/components/card/index.stories.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Meta } from '@storybook/react';
3 | import { Card } from '../card';
4 |
5 | const meta: Meta = {
6 | title: 'Components/Card',
7 | component: Card,
8 | };
9 |
10 | type DocsProps = {
11 | width: number;
12 | height: number;
13 | borderRadius: number;
14 | };
15 |
16 | export const Docs = ({ width, height, borderRadius }: DocsProps) => (
17 | <>
18 |
19 |
20 | Hello Card !
21 |
22 |
23 |
24 |
25 | 自定义圆角
26 |
27 |
28 | >
29 | );
30 |
31 | Docs.args = {
32 | width: 250,
33 | height: 200,
34 | borderRadius: 12,
35 | };
36 |
37 | export default meta;
38 |
--------------------------------------------------------------------------------
/src/ui-kit/components/card/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { FC, EventHandler } from 'react';
2 | import classnames from 'classnames';
3 | import { BaseProps } from '../../components/util/type';
4 | import './index.css';
5 |
6 | export interface CardProps extends BaseProps {
7 | width?: number;
8 | height?: number;
9 | borderRadius?: number | string;
10 | children?: React.ReactNode;
11 | onMouseDown?: EventHandler;
12 | onMouseUp?: EventHandler;
13 | onMouseLeave?: EventHandler;
14 | onScroll?: EventHandler;
15 | }
16 |
17 | export const Card: FC = ({
18 | width = 90,
19 | height = 90,
20 | borderRadius = 12,
21 | children,
22 | className,
23 | ...restProps
24 | }) => {
25 | const cls = classnames({
26 | [`fcr-card`]: 1,
27 | [`${className}`]: !!className,
28 | });
29 | return (
30 |
38 | {children}
39 |
40 | );
41 | };
42 |
--------------------------------------------------------------------------------
/src/ui-kit/components/checkbox/index.stories.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Meta } from '@storybook/react';
3 | import { CheckBox } from './';
4 |
5 | const meta: Meta = {
6 | title: 'Components/CheckBox',
7 | component: CheckBox,
8 | };
9 |
10 | export const Docs = () => {
11 | const [checked, setChecked] = useState(false);
12 |
13 | return (
14 | <>
15 |
16 | {
20 | setChecked(!checked);
21 | }}
22 | />
23 |
24 |
25 |
30 |
31 |
32 | {
36 | setChecked(!checked);
37 | }}
38 | />
39 |
40 | >
41 | );
42 | };
43 |
44 | export default meta;
45 |
--------------------------------------------------------------------------------
/src/ui-kit/components/float/index.tsx:
--------------------------------------------------------------------------------
1 | import classNames from 'classnames';
2 | import { FC, PropsWithChildren } from 'react';
3 | import { BaseProps } from '../util/type';
4 |
5 | export interface FloatProps extends BaseProps {
6 | top?: number;
7 | left?: number;
8 | bottom?: number;
9 | right?: number;
10 | direction?: 'row' | 'col';
11 | align?: 'flex-start' | 'flex-end';
12 | justify?: 'start' | 'end';
13 | gap: number;
14 | }
15 |
16 | export const Float: FC> = ({
17 | top,
18 | left,
19 | bottom,
20 | right,
21 | children,
22 | direction = 'row',
23 | align,
24 | justify,
25 | gap,
26 | }) => {
27 | const cls = classNames(
28 | 'fcr-absolute fcr-z-50 fcr-flex',
29 | direction === 'row' ? 'fcr-flex-row' : 'fcr-flex-col',
30 | `fcr-gap-${gap ?? 0}`,
31 | );
32 | return (
33 |
36 | {children}
37 |
38 | );
39 | };
40 |
--------------------------------------------------------------------------------
/src/ui-kit/components/index.ts:
--------------------------------------------------------------------------------
1 | export * from './button';
2 | export * from './card';
3 | export * from './checkbox';
4 | export * from './float';
5 | export * from './input';
6 | export * from './input-number';
7 | export * from './layout';
8 | export * from './loading';
9 | export * from './modal';
10 | export * from './overlay-wrap';
11 | export * from './pagination';
12 | export * from './placeholder';
13 | export * from './popover';
14 | export * from './progress';
15 | export * from './radio';
16 | export * from './root-box';
17 | export * from './roster';
18 | export * from './sound-player';
19 | export * from './svg-img';
20 | export * from './svga-player';
21 | export * from './table';
22 | export * from './tabs';
23 | export * from './toast';
24 | export * from './toolbar';
25 | export * from './tooltip';
26 | export * from './tree';
27 | export * from './volume';
28 |
--------------------------------------------------------------------------------
/src/ui-kit/components/input-number/index.css:
--------------------------------------------------------------------------------
1 | .fcr-input-number-wrapper {
2 | @apply fcr-text-level1 fcr-border fcr-border-solid fcr-border-divider;
3 | position: relative;
4 | width: 100%;
5 | height: 100%;
6 | min-width: 0;
7 | padding-left: 15px;
8 | font-size: 14px;
9 | line-height: 1.5715;
10 | border-radius: 4px;
11 | transition: all 0.3s;
12 | display: inline-flex;
13 | align-items: center;
14 | width: 150px;
15 | }
16 | .fcr-input-number-wrapper:hover,
17 | .fcr-input-number-focus {
18 | border-color: #357bf6;
19 | }
20 |
21 | .fcr-input-number-wrapper input {
22 | padding: 0;
23 | border: none;
24 | outline: none;
25 | background-color: transparent;
26 | width: 100%;
27 | }
28 |
29 | .fcr-input-number-wrapper input::-webkit-input-placeholder {
30 | /* WebKit browsers */
31 | color: #7b88a0;
32 | font-size: 14px;
33 | }
34 |
35 | .fcr-input-number-tail {
36 | padding-right: 6px;
37 | }
38 |
39 | .fcr-input-number-add:hover,
40 | .fcr-input-number-sub:hover {
41 | cursor: pointer;
42 | }
43 |
44 | .fcr-input-number-add.disabled polyline,
45 | .fcr-input-number-sub.disabled polyline {
46 | stroke: #a5adbb !important;
47 | }
48 |
--------------------------------------------------------------------------------
/src/ui-kit/components/input/ainput.css:
--------------------------------------------------------------------------------
1 | .fcr-theme.ant-input {
2 | border-radius: 12px;
3 | }
4 |
5 | .fcr-theme.ant-input:focus {
6 | border: 1px solid #030303 !important;
7 | }
8 |
9 | .fcr-theme.ant-input-affix-wrapper {
10 | border-radius: 12px;
11 | }
12 |
13 | .fcr-theme.ant-input-affix-wrapper > input.ant-input:focus {
14 | border: none !important;
15 | }
16 |
17 | .fcr-theme.ant-input-affix-wrapper:not(.ant-input-affix-wrapper-disabled):hover,
18 | .fcr-theme.ant-input-affix-wrapper:focus,
19 | .fcr-theme .ant-input-affix-wrapper-focused {
20 | border-color: #030303;
21 | box-shadow: 0 0 0 3px rgb(143 144 152 / 20%);
22 | }
23 |
--------------------------------------------------------------------------------
/src/ui-kit/components/input/ainput.tsx:
--------------------------------------------------------------------------------
1 | import Input, { InputProps } from 'antd/lib/input';
2 | import { FC } from 'react';
3 | import './ainput.css';
4 | type AInputProps = Pick<
5 | InputProps,
6 | | 'value'
7 | | 'className'
8 | | 'onChange'
9 | | 'placeholder'
10 | | 'allowClear'
11 | | 'maxLength'
12 | | 'showCount'
13 | | 'suffix'
14 | | 'prefix'
15 | | 'disabled'
16 | >;
17 | export const AInput: FC = ({ className = '', ...props }) => {
18 | return ;
19 | };
20 |
--------------------------------------------------------------------------------
/src/ui-kit/components/layout/index.css:
--------------------------------------------------------------------------------
1 | .fcr-layout {
2 | @apply fcr-flex;
3 | }
4 |
5 | .fcr-layout-row {
6 | @apply fcr-flex-row;
7 | }
8 |
9 | .fcr-layout-col {
10 | @apply fcr-flex-col;
11 | }
12 | .fcr-layout-col-reverse {
13 | @apply fcr-flex-col-reverse;
14 | }
15 |
16 | .fcr-layout-content {
17 | @apply fcr-flex fcr-flex-row fcr-flex-1 fcr-h-full;
18 | position: relative;
19 | width: 0;
20 | }
21 |
22 | .fcr-layout-header {
23 | @apply fcr-flex fcr-flex-row fcr-justify-center fcr-items-center fcr-w-full;
24 | flex: 0 0 27px;
25 | }
26 |
27 | .fcr-layout-aside {
28 | @apply fcr-flex fcr-flex-col fcr-border-l fcr-border-divider fcr-h-full fcr-overflow-hidden;
29 | /* width: 19rem; */
30 | border-left: none;
31 | gap: 4px;
32 | margin-left: 2px;
33 | position: relative;
34 | z-index: 3;
35 | flex-shrink: 0;
36 | }
37 |
--------------------------------------------------------------------------------
/src/ui-kit/components/loading/assets/circle-loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/loading/assets/circle-loading.gif
--------------------------------------------------------------------------------
/src/ui-kit/components/loading/assets/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/loading/assets/loading.gif
--------------------------------------------------------------------------------
/src/ui-kit/components/modal/index.stories.tsx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/react';
2 | import React, { useState } from 'react';
3 | import { Button } from '../button';
4 | import { Modal } from '../modal';
5 |
6 | const meta: Meta = {
7 | title: 'Components/Modal',
8 | component: Modal,
9 | };
10 |
11 | type DocsProps = {
12 | title: string;
13 | };
14 |
15 |
16 | export const Docs = ({ title }: DocsProps) => (
17 | <>
18 |
19 |
test, ]}>
20 | 你确定要下课吗?
21 |
22 |
23 |
24 |
test]}>
25 | 试用时间到,教室已解散!
26 |
27 |
28 |
29 |
test, ]}>
33 | 课件未能加载成功,您可以点击重新加载重试,或者从云盘中播放课件
34 |
35 |
36 | >
37 | );
38 |
39 | Docs.args = {
40 | title: 'Modal Title',
41 | };
42 |
43 |
44 | export default meta;
45 |
--------------------------------------------------------------------------------
/src/ui-kit/components/overlay-wrap/index.css:
--------------------------------------------------------------------------------
1 | .overlay-wrap {
2 | display: flex;
3 | justify-content: center;
4 | align-items: center;
5 | width: 100%;
6 | height: 100%;
7 | }
8 |
9 | .overlay-wrap-content-ltr {
10 | justify-content: flex-start;
11 | align-items: flex-start;
12 | }
13 |
14 | .overlay-wrap-enter {
15 | opacity: 0;
16 | transform: translateY(20px);
17 | }
18 | .overlay-wrap-enter-active {
19 | opacity: 1;
20 | transform: translateY(0px);
21 | transition: 300ms;
22 | }
23 | .overlay-wrap-exit {
24 | transform: translateY(0px);
25 | opacity: 1;
26 | }
27 | .overlay-wrap-exit-active {
28 | opacity: 0;
29 | transform: translateY(-20px);
30 | transition: 300ms;
31 | }
32 |
--------------------------------------------------------------------------------
/src/ui-kit/components/overlay-wrap/index.tsx:
--------------------------------------------------------------------------------
1 | import { FC, PropsWithChildren } from 'react';
2 | import classnames from 'classnames';
3 | import { BaseProps } from '../util/type';
4 | import { CSSTransition } from 'react-transition-group';
5 | import './index.css';
6 |
7 | interface OverlayWrapProps extends BaseProps {
8 | opened?: boolean;
9 | centered?: boolean;
10 | onExited?: (() => void) | undefined;
11 | }
12 |
13 | /**
14 | *
15 | * @param param0
16 | * @returns
17 | */
18 | export const OverlayWrap: FC> = ({
19 | opened = true,
20 | onExited,
21 | className,
22 | children,
23 | centered = true,
24 | }) => {
25 | const cls = classnames('overlay-wrap', {
26 | 'overlay-wrap-content-ltr': !centered,
27 | [`${className}`]: !!className,
28 | });
29 | return (
30 |
31 | {children}
32 |
33 | );
34 | };
35 |
--------------------------------------------------------------------------------
/src/ui-kit/components/pagination/index.css:
--------------------------------------------------------------------------------
1 | .agora-pagination .rc-pagination-prev,
2 | .rc-pagination-item,
3 | .rc-pagination-next {
4 | @apply fcr-bg-component;
5 | border-radius: 6px;
6 | }
7 |
8 | .agora-pagination .rc-pagination-prev .rc-pagination-item-link,
9 | .rc-pagination-next .rc-pagination-item-link {
10 | border-radius: 6px;
11 | @apply fcr-text-level2 fcr-bg-component;
12 | }
13 |
14 | .agora-pagination .rc-pagination-item a {
15 | @apply fcr-text-level2;
16 | }
17 |
18 | .agora-pagination .rc-pagination-item-active {
19 | @apply fcr-bg-brand;
20 | }
21 | .agora-pagination .rc-pagination-item-active a {
22 | color: white;
23 | }
24 |
--------------------------------------------------------------------------------
/src/ui-kit/components/pagination/index.tsx:
--------------------------------------------------------------------------------
1 | //@ts-nocheck
2 | import { FC } from 'react';
3 | import RcPagination, { PaginationProps } from 'rc-pagination';
4 | import 'rc-pagination/assets/index.css';
5 | import './index.css';
6 |
7 | export const Pagination: FC = (props) => {
8 | return ;
9 | };
10 |
--------------------------------------------------------------------------------
/src/ui-kit/components/placeholder/assets/board-disconnected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/placeholder/assets/board-disconnected.png
--------------------------------------------------------------------------------
/src/ui-kit/components/placeholder/assets/camera-broken.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/placeholder/assets/camera-broken.png
--------------------------------------------------------------------------------
/src/ui-kit/components/placeholder/assets/camera-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/placeholder/assets/camera-close.png
--------------------------------------------------------------------------------
/src/ui-kit/components/placeholder/assets/camera-disabled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/placeholder/assets/camera-disabled.png
--------------------------------------------------------------------------------
/src/ui-kit/components/placeholder/assets/empty-history.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/placeholder/assets/empty-history.png
--------------------------------------------------------------------------------
/src/ui-kit/components/placeholder/assets/no-body.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/placeholder/assets/no-body.png
--------------------------------------------------------------------------------
/src/ui-kit/components/placeholder/assets/no-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/placeholder/assets/no-file.png
--------------------------------------------------------------------------------
/src/ui-kit/components/placeholder/index.css:
--------------------------------------------------------------------------------
1 | .placeholder {
2 | @apply fcr-w-full fcr-h-full fcr-flex fcr-flex-col fcr-items-center fcr-justify-center;
3 | }
4 |
5 | .placeholder-desc {
6 | margin-top: 46px;
7 | font-size: 13px;
8 | font-weight: 400;
9 | color: #7d8798;
10 | }
11 |
12 | .camera-placeholder {
13 | @apply fcr-bg-background;
14 | overflow: hidden;
15 | position: relative;
16 | height: 100%;
17 | width: 100%;
18 | display: flex;
19 | justify-content: center;
20 | align-items: center;
21 | flex-direction: column;
22 | }
23 |
24 | .camera-placeholder span {
25 | color: #677386;
26 | font-size: 12px;
27 | }
28 |
29 | .pretest .camera-placeholder {
30 | position: absolute;
31 | }
32 |
33 | .maxiumn-wrap {
34 | position: relative;
35 | display: flex;
36 | justify-content: center;
37 | align-items: center;
38 | width: 100%;
39 | height: 100%;
40 | background: #000;
41 | font-size: 13px;
42 | font-weight: 400;
43 | color: #ffffff;
44 | }
45 |
46 | .board-placeholder {
47 | display: flex;
48 | flex-direction: column;
49 | justify-content: center;
50 | align-items: center;
51 | width: 100%;
52 | height: 100%;
53 | }
54 | .reconnect-btn {
55 | margin-top: 30px;
56 | font-size: 16px;
57 | width: 136px;
58 | height: 44px;
59 | }
60 |
--------------------------------------------------------------------------------
/src/ui-kit/components/placeholder/index.stories.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Meta } from '@storybook/react';
3 | import { Placeholder, CameraPlaceHolder } from '../placeholder';
4 |
5 | const meta: Meta = {
6 | title: 'Components/Placeholder',
7 | component: Placeholder,
8 | };
9 |
10 | type DocsProps = {
11 | placeholderDesc: string;
12 | };
13 |
14 | export const Docs = ({ placeholderDesc }: DocsProps) => (
15 | <>
16 |
19 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | >
38 | );
39 |
40 | Docs.args = {
41 | placeholderDesc: '',
42 | };
43 |
44 | export default meta;
45 |
--------------------------------------------------------------------------------
/src/ui-kit/components/popover/index.stories.tsx:
--------------------------------------------------------------------------------
1 | import React, { FC } from 'react';
2 | import { Meta } from '@storybook/react';
3 | import { Button } from '../button';
4 | import { Popover, PopoverProps } from '../popover';
5 |
6 | const meta: Meta = {
7 | title: 'Components/Popover',
8 | component: Popover,
9 | };
10 |
11 | export const Docs: FC = (props) => {
12 | return (
13 | <>
14 |
15 |
16 |
17 |
18 |
19 |
20 |
Hello world!}
25 | >
26 |
27 |
28 |
29 | >
30 | );
31 | };
32 |
33 | export default meta;
34 |
--------------------------------------------------------------------------------
/src/ui-kit/components/progress/index.css:
--------------------------------------------------------------------------------
1 | .bg-download-bg {
2 | background-color: #e3e3f0;
3 | }
4 |
5 | .bg-download-fg {
6 | background-color: #456dfd;
7 | }
8 |
9 | .progress-height {
10 | height: 0.5rem;
11 | border-radius: 0.25rem;
12 | display: flex;
13 | font-size: 0.75rem;
14 | line-height: 1rem;
15 | }
16 |
17 |
18 |
19 | .dialog-progress-container {
20 | box-sizing: border-box;
21 | margin: 0;
22 | padding: 8px;
23 | line-height: 1.5715;
24 | list-style: none;
25 | position: fixed;
26 | top: 45%;
27 | left: 0;
28 | z-index: 1010;
29 | width: 100%;
30 | pointer-events: none;
31 | text-align: center;
32 | }
33 | .dialog-progress-item {
34 | padding: 30px 25px;
35 | background: #ffffff;
36 | box-shadow: 0px 2px 6px 0px rgba(47, 65, 146, 0.15);
37 | border-radius: 12px;
38 | pointer-events: all;
39 | display: inline-block;
40 | }
41 |
42 | .dialog-progress-tip {
43 | font-size: 13px;
44 | font-weight: 400;
45 | color: #191919;
46 | margin-bottom: 20px;
47 | }
48 | .progress-percentage {
49 | font-size: 18px;
50 | color: #357bf6;
51 | line-height: 22px;
52 | }
53 |
--------------------------------------------------------------------------------
/src/ui-kit/components/progress/index.stories.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Progress } from '.';
3 |
4 | export default {
5 | title: 'Components/Progress',
6 | };
7 |
8 | export const ProgressShowCase = (props: any) => {
9 | return ;
10 | };
11 |
12 | ProgressShowCase.args = {
13 | width: 100,
14 | progress: 100,
15 | };
16 |
--------------------------------------------------------------------------------
/src/ui-kit/components/root-box/index.css:
--------------------------------------------------------------------------------
1 | .root-box {
2 | height: 100%;
3 | overflow: hidden;
4 | }
5 |
--------------------------------------------------------------------------------
/src/ui-kit/components/root-box/index.tsx:
--------------------------------------------------------------------------------
1 | import { FC, PropsWithChildren } from 'react';
2 | import classnames from 'classnames';
3 | import { BaseProps } from '../util/type';
4 | import './index.css';
5 |
6 | export type RootBoxProps = BaseProps;
7 |
8 | export const RootBox: FC> = ({
9 | children,
10 | className,
11 | ...restProps
12 | }) => {
13 | const cls = classnames({
14 | [`root-box`]: 1,
15 | [`${className}`]: !!className,
16 | });
17 | return (
18 |
19 | {children}
20 |
21 | );
22 | };
23 |
--------------------------------------------------------------------------------
/src/ui-kit/components/roster/assets/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/roster/assets/loading.gif
--------------------------------------------------------------------------------
/src/ui-kit/components/roster/hooks.tsx:
--------------------------------------------------------------------------------
1 | import { useMemo } from 'react';
2 | import {
3 | defaultColumns,
4 | kickOutColumn,
5 | podiumColumn,
6 | grantBoardColumn,
7 | starsColumn,
8 | superviseColumn,
9 | } from './columns';
10 | import { Column } from './';
11 | import { SupportedFunction } from '..';
12 | import { sortBy } from 'lodash';
13 |
14 | export const useColumns = (functions: SupportedFunction[]) => {
15 | const showKickOut = functions.includes('kick');
16 |
17 | const cols = useMemo(() => {
18 | const cols = ([] as Column[]).concat(defaultColumns);
19 | if (functions.includes('kick')) {
20 | cols.push(kickOutColumn);
21 | }
22 | if (functions.includes('podium')) {
23 | cols.push(podiumColumn);
24 | }
25 |
26 | if (functions.includes('grant-board')) {
27 | cols.push(grantBoardColumn);
28 | }
29 |
30 | if (functions.includes('stars')) {
31 | cols.push(starsColumn);
32 | }
33 |
34 | // if (functions.includes('supervise-student')) {
35 | // cols.push(superviseColumn);
36 | // }
37 |
38 | return sortBy(cols, ['order']);
39 | }, [showKickOut]);
40 |
41 | return cols;
42 | };
43 |
--------------------------------------------------------------------------------
/src/ui-kit/components/select/assets/arrow-icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/ui-kit/components/select/index.stories.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Meta } from '@storybook/react';
3 | import { Select } from '../select';
4 |
5 | const meta: Meta = {
6 | title: 'Components/Select',
7 | component: Select,
8 | };
9 |
10 | export const Docs = () => {
11 | const options = [
12 | { value: 'chocolate', label: 'Chocolate' },
13 | { value: 'strawberry', label: 'Strawberry' },
14 | { value: 'vanilla', label: 'Vanilla' },
15 | ];
16 | const [selectedOption, setSelectedOption] = useState('');
17 | return (
18 | <>
19 |
20 |
30 |
31 |
41 | >
42 | );
43 | };
44 |
45 | export default meta;
46 |
--------------------------------------------------------------------------------
/src/ui-kit/components/slider/index.css:
--------------------------------------------------------------------------------
1 | .fcr-theme.slider .ant-slider {
2 | margin: 0;
3 | }
4 |
5 | .fcr-theme.slider .ant-slider-track,
6 | .fcr-theme.slider .ant-slider-track:hover,
7 | .fcr-theme.slider .ant-slider:hover .ant-slider-track {
8 | background-color: #0073ff;
9 | }
10 | .fcr-theme.slider .ant-slider-handle,
11 | .fcr-theme.slider .ant-slider-handle:hover,
12 | .fcr-theme.slider .ant-slider:hover .ant-slider-handle:not(.ant-tooltip-open) {
13 | border-color: #0073ff;
14 | }
15 |
--------------------------------------------------------------------------------
/src/ui-kit/components/sound-player/index.tsx:
--------------------------------------------------------------------------------
1 | import { FC, useRef, useEffect } from 'react';
2 |
3 | type Props = {
4 | url: string;
5 | };
6 |
7 | export const SoundPlayer: FC = ({ url }: Props) => {
8 | const audioRef = useRef(null);
9 |
10 | useEffect(() => {
11 | const audioElement = new Audio(url);
12 | audioElement.play();
13 | audioRef.current = audioElement;
14 |
15 | return () => {
16 | if (audioRef.current) {
17 | audioRef.current.pause();
18 | audioRef.current = null;
19 | }
20 | };
21 | }, []);
22 |
23 | return null;
24 | };
25 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/generate.ts:
--------------------------------------------------------------------------------
1 | // import fs from 'fs';
2 | // import path from 'path';
3 |
4 | // fs.readdirSync(path.resolve(__dirname, './paths')).forEach((d) => {
5 | // const value = d.replace('.tsx', '');
6 | // const key = value.toUpperCase().replace(/-/g, '_');
7 |
8 | // console.log(`${key} = '${value}',`);
9 | // });
10 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/index.css:
--------------------------------------------------------------------------------
1 | .svg-story-div {
2 | display: flex;
3 | flex-direction: column;
4 | justify-content: center;
5 | align-items: center;
6 | margin-right: 25px;
7 | margin-bottom: 25px;
8 | }
9 | .my-svg-eraser {
10 | background: pink;
11 | cursor: pointer;
12 | transition: 0.5s;
13 | }
14 | .my-svg-eraser > .eraser {
15 | fill: yellow;
16 | }
17 | .my-svg-eraser:hover {
18 | background: #000;
19 | }
20 | .my-svg-eraser:hover > .eraser {
21 | fill: white;
22 | }
23 |
24 | .can-hover {
25 | cursor: pointer;
26 | border-radius: 50%;
27 | }
28 |
29 | .can-hover:hover {
30 | @apply fcr-bg-icon-selected-color;
31 | }
32 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/index.stories.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Meta } from '@storybook/react';
3 | import { SvgIcon } from './';
4 | import { SvgIconEnum } from './type';
5 | import './index.css';
6 |
7 | const meta: Meta = {
8 | title: 'Components/SvgImg',
9 | component: SvgIcon,
10 | };
11 |
12 | type DocsProps = {
13 | size: number;
14 | color: string;
15 | };
16 |
17 | const keys = Object.keys(SvgIconEnum);
18 | export const Docs = ({ size, color }: DocsProps) => {
19 | return (
20 |
21 |
Icon Gallery
22 |
23 | {keys.map((k) => {
24 | return (
25 |
26 |
32 |
33 | );
34 | })}
35 |
36 |
37 | );
38 | };
39 |
40 | Docs.args = {
41 | size: 100,
42 | color: '',
43 | };
44 |
45 | export default meta;
46 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/add-scene.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary }: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 | export const viewBox = '0 0 24 24'
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/add.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary }: PathOptions) => (
6 |
12 | );
13 |
14 | export const viewBox = '0 0 40 40';
15 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/arrow.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
9 |
10 |
11 |
16 |
17 |
18 |
19 | export const viewBox = '0 0 26 26'
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/auto-play-failed.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 | <>
7 |
8 |
14 | >
15 | );
16 | export const viewBox = '0 0 130 100';
17 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/backward.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 | export const viewBox = '0 0 1024 1024'
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/bad-signal.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 | export const viewBox = '0 0 1024 1024'
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/camera-enabled.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { PathOptions } from "../svg-dict"
3 |
4 | export const path = (props: PathOptions) =>
5 |
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = "0 0 24 24"
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/camera-off-mobile.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary }: PathOptions) => (
6 | <>
7 |
13 |
19 | >
20 | );
21 |
22 | export const viewBox = '0 0 40 40';
23 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/camera-on-mobile.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary }: PathOptions) => (
6 |
13 | );
14 |
15 | export const viewBox = '0 0 40 40';
16 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/camera.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
13 | );
14 |
15 | export const viewBox = '0 0 28 28';
16 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/checked.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024'
11 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/chevron-right.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
10 | );
11 |
12 | export const viewBox = '0 0 24 24';
13 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/circle.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1060 1024'
11 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/clear.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/clicker.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/clock.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 | <>
7 |
16 |
22 | >
23 | );
24 |
25 | export const viewBox = '0 0 16 16';
26 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/close.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/cloud-more.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { PathOptions } from '../svg-dict';
3 |
4 | export const path = (props: PathOptions) => (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 |
20 | export const viewBox = '0 0 32 32';
21 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/cloud.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 26 26';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/copy.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
7 |
12 |
21 |
22 | );
23 |
24 | export const viewBox = '0 0 22 22';
25 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/delete.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/down.tsx:
--------------------------------------------------------------------------------
1 |
2 | import React from 'react';
3 |
4 | import { PathOptions } from '../svg-dict';
5 |
6 | export const path = (props: PathOptions) =>
7 |
8 |
9 |
10 |
11 |
12 | export const viewBox = '0 0 10 6';
13 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/dropdown.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
7 |
13 |
14 | );
15 |
16 | export const viewBox = '0 0 48 48';
17 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/edit.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
7 |
13 |
17 |
18 | );
19 |
20 | export const viewBox = '0 0 16 16';
21 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/emoji.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 | import React from 'react';
4 |
5 | import { PathOptions } from '../svg-dict';
6 |
7 | export const path = (props: PathOptions) =>
8 |
9 |
10 |
11 |
12 |
13 |
14 | export const viewBox = '0 0 24 24';
15 |
16 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/eraser.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/excel.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 |
11 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/forward.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/fullscreen-shrink.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
7 |
14 |
21 |
22 | );
23 |
24 | export const viewBox = '0 0 48 48';
25 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/fullscreen.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
7 |
14 |
21 |
22 | );
23 |
24 | export const viewBox = '0 0 48 48';
25 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/goonstage.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
14 | );
15 |
16 | export const viewBox = '0 0 20 20';
17 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/hand.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/hands-up.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/id.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
7 |
13 |
14 | );
15 |
16 | export const viewBox = '0 0 48 48';
17 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/line.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1060 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/log.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/mark.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
12 | );
13 |
14 | export const viewBox = '0 0 48 48';
15 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/max.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/mic-disabled.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { PathOptions } from "../svg-dict"
3 |
4 | export const path = (props: PathOptions) =>
5 |
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = "0 0 24 24"
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/mic-enabled.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { PathOptions } from "../svg-dict"
3 |
4 | export const path = (props: PathOptions) =>
5 |
6 |
7 |
8 |
9 |
10 | export const viewBox = "0 0 24 24"
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/microphone.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
13 | );
14 |
15 | export const viewBox = '0 0 28 28';
16 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/min.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/more.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/mute-mobile.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary }: PathOptions) => (
6 | <>
7 |
14 | >
15 | );
16 |
17 | export const viewBox = '0 0 40 40';
18 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/none.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
12 | );
13 | export const viewBox = '0 0 40 40';
14 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/normal-signal.tsx:
--------------------------------------------------------------------------------
1 |
2 | import React from 'react';
3 |
4 | import { PathOptions } from '../svg-dict';
5 |
6 | export const path = (props: PathOptions) =>
10 |
11 | export const viewBox = '0 0 1024 1024'
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/on-podium.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { PathOptions } from "../svg-dict"
3 |
4 | export const path = (props: PathOptions) =>
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | export const viewBox = "0 0 22 22"
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pen-arrow.tsx:
--------------------------------------------------------------------------------
1 |
2 |
3 | import React from 'react';
4 |
5 | import { PathOptions } from '../svg-dict';
6 |
7 | export const path = ({ iconPrimary, penColor }: PathOptions) =>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | export const viewBox = '0 0 22 24';
16 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pen-circle.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary, penColor }: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | export const viewBox = '0 0 22 24';
14 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pen-curve.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary, penColor }: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | export const viewBox = '0 0 22 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pen-line.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary, penColor }: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | export const viewBox = '0 0 22 24';
14 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pen-rhombus.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary, penColor }: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | export const viewBox = '0 0 22 24';
14 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pen-square.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary, penColor }: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | export const viewBox = '0 0 22 24';
14 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pen-triangle.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = ({ iconPrimary, penColor }: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | export const viewBox = '0 0 22 24';
14 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pen.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pentagram.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
9 |
10 |
11 |
15 |
16 |
17 |
18 | export const viewBox = '0 0 26 26'
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pic.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 | export const viewBox = '0 0 26 26'
13 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/placeholder-no-setup.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
13 |
14 |
15 |
16 | export const viewBox = '0 0 90 90';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pretest-check.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
14 |
21 |
25 |
26 |
27 |
28 | export const viewBox = '0 0 30 30';
29 |
30 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/pretest-checked.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | export const viewBox = '0 0 30 30';
14 |
15 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/record.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/recording.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/red-caution.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/redo.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/register.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/reset.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
11 | );
12 |
13 | export const viewBox = '0 0 24 24';
14 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/review.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/rhombus.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
9 |
10 |
11 |
16 |
17 |
18 |
19 | export const viewBox = '0 0 26 26';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/room-label.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
7 |
13 |
14 | );
15 |
16 | export const viewBox = '0 0 15 14';
17 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/save-ghost.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/select.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/set.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/settings.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
10 | );
11 |
12 | export const viewBox = '0 0 14 14';
13 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/share-mobile.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 | <>
7 |
11 | >
12 | );
13 |
14 | export const viewBox = '0 0 24 24';
15 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/speaker.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/square.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/stage.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
11 | );
12 |
13 | export const viewBox = '0 0 28 28';
14 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/star-outline.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/star.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/stream-window-on.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { PathOptions } from "../svg-dict";
3 |
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 |
12 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/switch-screen-share.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
13 |
14 |
15 |
20 |
26 |
27 |
28 |
29 | export const viewBox = '0 0 26 26';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/text.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/tools.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/triangle-down.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | export const viewBox = '0 0 6 6';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/triangle-solid-down.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
18 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | export const viewBox = '0 0 18 14';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/triangle-solid-right.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | export const viewBox = '0 0 18 18';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/triangle-solid-up.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | export const viewBox = '0 0 18 14';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/triangle.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
9 |
10 |
11 |
15 |
16 |
17 |
18 |
19 | export const viewBox = '0 0 26 26';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/undo.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/video-gallery.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => (
6 |
12 | );
13 |
14 | export const viewBox = '0 0 24 24';
15 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/video.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/vote.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 |
11 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/whiteboard.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
6 |
7 |
8 |
9 |
10 | export const viewBox = '0 0 24 24';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/word.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/zoom-in.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) =>
9 |
10 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/paths/zoom-out.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import { PathOptions } from '../svg-dict';
4 |
5 | export const path = (props: PathOptions) => ;
8 |
9 | export const viewBox = '0 0 1024 1024';
--------------------------------------------------------------------------------
/src/ui-kit/components/svg-img/svg-dict.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const ctxRequire = require.context('./paths', false, /\.tsx$/);
4 |
5 | const paths: Record = {};
6 |
7 | ctxRequire.keys().forEach(async (path) => {
8 | const m = ctxRequire(path) as SvgPath;
9 | const key = path.replace('./', '').replace('.tsx', '');
10 | paths[key] = m;
11 | });
12 |
13 | export type PathOptions = {
14 | iconPrimary: string,
15 | iconSecondary: string,
16 | [key: string]: string
17 | };
18 |
19 | export type SvgPath = {
20 | path: (options: PathOptions) => React.ReactNode;
21 | viewBox?: string;
22 | };
23 |
24 | export const getPath = (name: string, props: PathOptions) => {
25 | const svg = paths[name];
26 |
27 | if (svg) {
28 | return svg.path(props);
29 | }
30 |
31 | return
32 |
33 | };
34 |
35 | export const getViewBox = (name: string) => {
36 | const svg = paths[name];
37 |
38 | if (svg) {
39 | return svg.viewBox;
40 | }
41 |
42 | return '0 0 0 0';
43 | };
44 |
--------------------------------------------------------------------------------
/src/ui-kit/components/svga-player/assets/audio/reward.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/svga-player/assets/audio/reward.mp3
--------------------------------------------------------------------------------
/src/ui-kit/components/svga-player/assets/star.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/svga-player/assets/star.gif
--------------------------------------------------------------------------------
/src/ui-kit/components/svga-player/assets/svga/hands-up.svga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/svga-player/assets/svga/hands-up.svga
--------------------------------------------------------------------------------
/src/ui-kit/components/svga-player/assets/svga/reward.svga:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/svga-player/assets/svga/reward.svga
--------------------------------------------------------------------------------
/src/ui-kit/components/svga-player/svga-types.ts:
--------------------------------------------------------------------------------
1 | export type SvgaTypes = 'reward';
2 |
--------------------------------------------------------------------------------
/src/ui-kit/components/tabs/index.css:
--------------------------------------------------------------------------------
1 | /* fix bug: tabs 某些 css 找不到,所以手动补充下*/
2 | .fcr-theme .ant-tabs-tabpane-hidden {
3 | display: none;
4 | }
5 |
6 | .whiteboard .tabs-top {
7 | width: 100%;
8 | }
9 | .whiteboard .tabs-top .tabs-nav-list {
10 | overflow-x: auto;
11 | }
12 | .whiteboard .tabs-top .tabs-nav-operations {
13 | display: none !important;
14 | }
15 |
--------------------------------------------------------------------------------
/src/ui-kit/components/tabs/index.tsx:
--------------------------------------------------------------------------------
1 | import Tabs, { TabPaneProps, TabsProps } from 'antd/lib/tabs';
2 | import classNames from 'classnames';
3 | import React, { FC, PropsWithChildren } from 'react';
4 | import { SvgIconEnum, SvgImg } from '../svg-img';
5 | import './index.css';
6 |
7 | export type ATabsProps = Pick<
8 | TabsProps,
9 | | 'className'
10 | | 'activeKey'
11 | | 'centered'
12 | | 'type'
13 | | 'onChange'
14 | | 'onEdit'
15 | | 'onTabClick'
16 | | 'animated'
17 | | 'moreIcon'
18 | | 'renderTabBar'
19 | | 'items'
20 | >;
21 |
22 | export const ATabs: FC> = ({
23 | type,
24 | className,
25 | onEdit,
26 | centered,
27 | ...props
28 | }) => {
29 | const { moreIcon = } = props;
30 |
31 | return (
32 |
33 | );
34 | };
35 |
36 | export type ATabPaneProps = Pick;
37 |
38 | export const ATabPane: FC> = ({ className, ...props }) => {
39 | return ;
40 | };
41 |
--------------------------------------------------------------------------------
/src/ui-kit/components/toast/index.css:
--------------------------------------------------------------------------------
1 | .toast {
2 | min-width: 100px;
3 | height: 34px;
4 |
5 | font-size: 14px;
6 | box-shadow: 0px 3px 8px 0px rgba(0, 0, 0, 0.1);
7 | border-radius: 4px;
8 | padding: 0 14px;
9 | animation: toastAnimation 0.2s;
10 | transition: top 0.3s, opacity 0.1s;
11 | @apply fcr-text-white fcr-cursor-pointer fcr-flex fcr-items-center fcr-justify-center fcr-box-border fcr-relative;
12 | }
13 |
14 | @keyframes toastAnimation {
15 | 0% {
16 | transform: scale(1);
17 | opacity: 0;
18 | }
19 | 50% {
20 | transform: scale(1.2);
21 | opacity: 0.5;
22 | }
23 | 100% {
24 | transform: scale(1);
25 | opacity: 1;
26 | }
27 | }
28 | .toast svg {
29 | margin-right: 6px;
30 | width: 21px;
31 | height: 21px;
32 | }
33 |
34 | .toast-success {
35 | @apply fcr-bg-safe fcr-border-safe fcr-border;
36 | }
37 |
38 | .toast-error {
39 | @apply fcr-bg-error fcr-border-error fcr-border;
40 | }
41 |
42 | .toast-warning {
43 | @apply fcr-bg-warning fcr-border-warning fcr-border;
44 | }
45 |
46 | .toast .toast-progress {
47 | position: absolute;
48 | width: 100%;
49 | height: 3px;
50 | background-color: #ccc;
51 | bottom: 0;
52 | left: 0;
53 | }
54 | .toast .toast-current {
55 | height: 3px;
56 | background-color: red;
57 | }
58 |
--------------------------------------------------------------------------------
/src/ui-kit/components/toolbar/util.ts:
--------------------------------------------------------------------------------
1 | import { SvgIconEnum } from '../svg-img';
2 |
3 | export const getPenIcon = (penTool: string) => {
4 | switch (penTool) {
5 | case 'square':
6 | return SvgIconEnum.PEN_SQUARE;
7 | case 'circle':
8 | return SvgIconEnum.PEN_CIRCLE;
9 | case 'line':
10 | return SvgIconEnum.PEN_LINE;
11 | case 'arrow':
12 | return SvgIconEnum.PEN_ARROW;
13 | case 'pentagram':
14 | return SvgIconEnum.PEN_PENTAGRAM;
15 | case 'rhombus':
16 | return SvgIconEnum.PEN_RHOMBUS;
17 | case 'triangle':
18 | return SvgIconEnum.PEN_TRIANGLE;
19 | case 'pen':
20 | default:
21 | return SvgIconEnum.PEN_CURVE;
22 | }
23 | };
24 |
25 | export const getPenShapeIcon = (penTool: string) => {
26 | switch (penTool) {
27 | case 'square':
28 | return SvgIconEnum.SQUARE;
29 | case 'circle':
30 | return SvgIconEnum.CIRCLE;
31 | case 'line':
32 | return SvgIconEnum.LINE;
33 | case 'arrow':
34 | return SvgIconEnum.ARROW;
35 | case 'pentagram':
36 | return SvgIconEnum.PENTAGRAM;
37 | case 'rhombus':
38 | return SvgIconEnum.RHOMBUS;
39 | case 'triangle':
40 | return SvgIconEnum.TRIANGLE;
41 | case 'pen':
42 | default:
43 | return SvgIconEnum.PEN;
44 | }
45 | };
46 |
--------------------------------------------------------------------------------
/src/ui-kit/components/tree/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AgoraIO-Community/CloudClass-Desktop/41651e4ae972718c8b5ac7674e97673f1a5a14b3/src/ui-kit/components/tree/style.css
--------------------------------------------------------------------------------
/src/ui-kit/components/util/colors.ts:
--------------------------------------------------------------------------------
1 | import { ElementOf, tuple } from './type';
2 |
3 | // eslint-disable-next-line import/prefer-default-export
4 | export const PresetColorTypes = tuple(
5 | 'pink',
6 | 'red',
7 | 'yellow',
8 | 'orange',
9 | 'cyan',
10 | 'green',
11 | 'blue',
12 | 'purple',
13 | 'geekblue',
14 | 'magenta',
15 | 'volcano',
16 | 'gold',
17 | 'lime',
18 | );
19 |
20 | export type PresetColorType = ElementOf;
21 |
--------------------------------------------------------------------------------
/src/ui-kit/components/util/getRenderPropValue.ts:
--------------------------------------------------------------------------------
1 | import { ReactNode } from 'react';
2 |
3 | export type RenderFunction = () => ReactNode;
4 |
5 | export const getRenderPropValue = (propValue?: ReactNode | RenderFunction): ReactNode => {
6 | if (!propValue) {
7 | return null;
8 | }
9 |
10 | const isRenderFunction = typeof propValue === 'function';
11 | if (isRenderFunction) {
12 | return (propValue as RenderFunction)();
13 | }
14 |
15 | return propValue;
16 | };
17 |
--------------------------------------------------------------------------------
/src/ui-kit/components/util/motion.ts:
--------------------------------------------------------------------------------
1 | import { CSSMotionProps, MotionEventHandler, MotionEndEventHandler } from 'rc-motion';
2 |
3 | // ================== Collapse Motion ==================
4 | const getCollapsedHeight: MotionEventHandler = () => ({
5 | height: 0,
6 | opacity: 0,
7 | });
8 | const getRealHeight: MotionEventHandler = (node) => ({
9 | height: node.scrollHeight,
10 | opacity: 1,
11 | });
12 | const getCurrentHeight: MotionEventHandler = (node) => ({
13 | height: node.offsetHeight,
14 | });
15 | const skipOpacityTransition: MotionEndEventHandler = (_, event) =>
16 | (event as TransitionEvent).propertyName === 'height';
17 |
18 | const collapseMotion: CSSMotionProps = {
19 | motionName: 'ant-motion-collapse',
20 | onAppearStart: getCollapsedHeight,
21 | onEnterStart: getCollapsedHeight,
22 | onAppearActive: getRealHeight,
23 | onEnterActive: getRealHeight,
24 | onLeaveStart: getCurrentHeight,
25 | onLeaveActive: getCollapsedHeight,
26 | onAppearEnd: skipOpacityTransition,
27 | onEnterEnd: skipOpacityTransition,
28 | onLeaveEnd: skipOpacityTransition,
29 | motionDeadline: 500,
30 | };
31 |
32 | const getTransitionName = (rootPrefixCls: string, motion: string, transitionName?: string) => {
33 | if (transitionName !== undefined) {
34 | return transitionName;
35 | }
36 | return `${rootPrefixCls}-${motion}`;
37 | };
38 | export { getTransitionName };
39 | export default collapseMotion;
40 |
--------------------------------------------------------------------------------
/src/ui-kit/components/util/type.ts:
--------------------------------------------------------------------------------
1 | import { CSSProperties } from 'react';
2 | import { SvgIconEnum } from '../svg-img';
3 |
4 | export interface BaseProps {
5 | style?: CSSProperties;
6 | className?: string;
7 | id?: string;
8 | }
9 |
10 | export const tuple = (...args: T) => args;
11 |
12 | export type ElementOf = T extends (infer E)[] ? E : T extends readonly (infer F)[] ? F : never;
13 |
14 | export type IconWithState = {
15 | icon: SvgIconEnum;
16 | color?: string;
17 | };
18 |
--------------------------------------------------------------------------------
/src/ui-kit/components/volume/index.stories.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { Meta } from '@storybook/react';
3 | import { Volume, AudioVolume } from '../volume';
4 |
5 | const meta: Meta = {
6 | title: 'Components/Volume',
7 | component: Volume,
8 | };
9 |
10 | type DocsProps = {
11 | width: number;
12 | height: number;
13 | currentVolume: number;
14 | maxLength: number;
15 | };
16 |
17 | export const Docs = () => {
18 | const [currentVolume, setCurrentVolume] = useState(0);
19 | let timer;
20 | useEffect(() => {
21 | timer = setInterval(() => {
22 | const number = (Math.random() * 100) | 0;
23 | setCurrentVolume(number);
24 | }, 1000);
25 | return () => {
26 | clearInterval(timer);
27 | };
28 | }, []);
29 | return (
30 | <>
31 |
35 |
36 |
has volume
37 |
38 |
39 |
40 |
isMicMuted
41 |
42 |
43 | >
44 | );
45 | };
46 |
47 | Docs.args = {
48 | width: 3,
49 | height: 12,
50 | currentVolumn: 0,
51 | maxLength: 20,
52 | };
53 |
54 | export default meta;
55 |
--------------------------------------------------------------------------------
/src/ui-kit/index.ts:
--------------------------------------------------------------------------------
1 | export * from './components';
2 | export * from './utilities';
3 |
--------------------------------------------------------------------------------
/src/ui-kit/styles/global.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 |
3 | @tailwind components;
4 |
5 | @tailwind utilities;
6 |
7 | @tailwind screens;
8 |
9 | html,
10 | html body {
11 | @apply fcr-font-scenario;
12 | }
13 |
--------------------------------------------------------------------------------
/src/ui-kit/utilities/index.ts:
--------------------------------------------------------------------------------
1 | import { Z_INDEX_RULES } from './style-config';
2 |
3 | export type I18nLanguage = 'zh' | 'en';
4 |
5 | export const getOS = () => {
6 | let ua = navigator.userAgent,
7 | isWindowsPhone = /(?:Windows Phone)/.test(ua),
8 | isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
9 | isAndroid = /(?:Android)/.test(ua),
10 | isFireFox = /(?:Firefox)/.test(ua),
11 | isChrome = /(?:Chrome|CriOS)/.test(ua),
12 | isTablet =
13 | /(?:iPad|PlayBook)/.test(ua) ||
14 | (isAndroid && !/(?:Mobile)/.test(ua)) ||
15 | (isFireFox && /(?:Tablet)/.test(ua)) ||
16 | (navigator.maxTouchPoints &&
17 | navigator.maxTouchPoints > 2 &&
18 | /MacIntel/.test(navigator.platform)) ||
19 | 'ontouchend' in document,
20 | isPhone = /(?:iPhone)/.test(ua) && !isTablet,
21 | isPc = !isPhone && !isAndroid && !isSymbian;
22 | return {
23 | isTablet: isTablet,
24 | isPhone: isPhone,
25 | isPc: isPc,
26 | };
27 | };
28 |
29 | export const Z_INDEX_CONST = Z_INDEX_RULES;
30 |
--------------------------------------------------------------------------------
/src/ui-kit/utilities/state-color.ts:
--------------------------------------------------------------------------------
1 | export const NetworkStateColors = {
2 | normal: '',
3 | bad: '',
4 | down: '',
5 | unknown: '',
6 | };
7 |
8 | export const InteractionStateColors = {
9 | allow: '#357BF6',
10 | disallow: '#F04C36',
11 | half: '#B3D6FF',
12 | disabled: '#7C7C7C66',
13 | normal: '#D8D8D8',
14 | };
15 |
16 | export const PlaceholderStateColors = {
17 | normal: '#97BAF9',
18 | disabled: '#C7D3ED',
19 | };
20 |
--------------------------------------------------------------------------------
/src/ui-kit/utilities/types.ts:
--------------------------------------------------------------------------------
1 | export type OnChangeEvents = {
2 | [Property in keyof Type as `onChange${Capitalize}`]: (
3 | newValue: Type[Property],
4 | ) => void;
5 | };
6 |
7 | export type HomeModule = OnChangeEvents &
8 | CustomizeVanillaType;
9 |
10 | export type IncludeUIKitSetter = {
11 | [Property in keyof Type as `set${Capitalize}`]: (
12 | newValue: Type[Property],
13 | ) => void;
14 | };
15 |
16 | export type UIKitModule = IncludeUIKitSetter & EntityType;
17 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [require('agora-common-libs/presets/tailwind.config.js')],
3 | };
4 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es6",
4 | "experimentalDecorators": true,
5 | "module": "esnext",
6 | "lib": [
7 | "dom",
8 | "dom.iterable",
9 | "esnext",
10 | "webworker"
11 | ],
12 | "outDir": "lib",
13 | "noImplicitAny": true,
14 | "noImplicitThis": true,
15 | "strictNullChecks": true,
16 | "allowJs": true,
17 | "skipLibCheck": true,
18 | "declaration": true,
19 | "esModuleInterop": true,
20 | "allowSyntheticDefaultImports": true,
21 | "strict": true,
22 | "forceConsistentCasingInFileNames": true,
23 | "noEmitHelpers": true,
24 | "noEmitOnError": false,
25 | "emitDeclarationOnly": true,
26 | "moduleResolution": "node",
27 | "resolveJsonModule": true,
28 | "isolatedModules": true,
29 | "jsx": "react-jsx",
30 | "noFallthroughCasesInSwitch": true,
31 | "baseUrl": ".",
32 | "paths": {
33 | "@classroom/*": ["src/*"],
34 | "agora-classroom-sdk": ["src/infra/api"]
35 | }
36 | },
37 | "include": [
38 | "src"
39 | ],
40 | "exclude": [
41 | "node_modules",
42 | "**/*/*.stories.tsx"
43 | ],
44 | }
45 |
--------------------------------------------------------------------------------
/typedoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "entryPoints": ["./src/infra/api"],
3 | "out": "./docs",
4 | "exclude": ["**/node_modules/**"],
5 | "excludeExternals": true,
6 | "excludePrivate": true,
7 | "hideGenerator": true
8 | }
9 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpackMerge = require('webpack-merge');
2 | const path = require('path');
3 | const baseConfig = require('agora-common-libs/presets/webpack.config.base.js');
4 | const ROOT_PATH = path.resolve(__dirname, './');
5 | const config = {
6 | entry: {
7 | edu_sdk: './src/infra/api/index.tsx',
8 | },
9 | output: {
10 | path: path.resolve(ROOT_PATH, 'lib'),
11 | publicPath: './',
12 | filename: '[name].bundle.js',
13 | libraryTarget: 'umd',
14 | clean: true,
15 | },
16 | resolve: {
17 | alias: {
18 | '@classroom': path.resolve(ROOT_PATH, './src'),
19 | 'agora-classroom-sdk': path.resolve(ROOT_PATH, './src/infra/api'),
20 | },
21 | },
22 | };
23 |
24 | const mergedConfig = webpackMerge.merge(baseConfig, config);
25 | module.exports = mergedConfig;
26 |
--------------------------------------------------------------------------------