diff --git a/src/containers/action-bar/toolbox/index.tsx b/src/containers/action-bar/toolbox/index.tsx index 6ec8441..f7c131e 100644 --- a/src/containers/action-bar/toolbox/index.tsx +++ b/src/containers/action-bar/toolbox/index.tsx @@ -7,6 +7,7 @@ import './index.css'; import { useI18n } from 'agora-common-libs'; import { ToolTip } from '@components/tooltip'; import { useZIndex } from '@ui-scene/utils/hooks/use-z-index'; +import { RttTypeEnum } from '@ui-scene/uistores/type'; export const ToolBox = observer(() => { const { layoutUIStore: { setHasPopoverShowed } } = useStore(); @@ -57,6 +58,7 @@ const ToolBoxPopoverContent = observer(({ onClick }: { onClick: () => void }) => const { getters, eduToolApi: { registeredCabinetToolItems }, + widgetUIStore: { widgetActiveList } } = useStore(); const transI18n = useI18n(); const isWidgetActive = (widgetId: string) => { @@ -64,10 +66,10 @@ const ToolBoxPopoverContent = observer(({ onClick }: { onClick: () => void }) => return getters.isBreakoutActive; } if (widgetId === 'rtt') { - return "true" === localStorage.getItem(`${getters.roomUuid}_subtitle`) + return widgetActiveList.includes(widgetId) } if (widgetId === 'rttbox') { - return "true" === localStorage.getItem(`${getters.roomUuid}_transcribe`) + return widgetActiveList.includes(widgetId) } return getters.activeWidgetIds.includes(widgetId); }; @@ -85,7 +87,6 @@ const ToolBoxPopoverContent = observer(({ onClick }: { onClick: () => void }) => onWidgetIdChange={()=>{ }} active={isWidgetActive(id)} - dropupActive={id === "rtt" || id === "rttbox"} /> ))} @@ -97,52 +98,81 @@ interface ToolBoxItemProps { icon: SvgIconEnum; label: string; active: boolean; - dropupActive: boolean; onClick: () => void; onWidgetIdChange: (id: string) => void; } const ToolBoxItem: FC = observer((props) => { - const { icon, label, active, dropupActive, id, onClick, onWidgetIdChange } = props; + const { icon, label, active, id, onClick, onWidgetIdChange } = props; const { widgetUIStore, eduToolApi, breakoutUIStore } = useStore(); const { updateZIndex } = useZIndex(id); useEffect(() => { if (id === 'rtt') { widgetUIStore.createWidget(id); - eduToolApi.setWidgetVisible(id, false); eduToolApi.sendWidgetVisibleIsShowTool(id, true); } if (id === 'rttbox') { widgetUIStore.createWidget(id); - eduToolApi.setWidgetVisible(id, false); } }, []); + + //修改最大最小化 + const setMinimizedState = (minimized: boolean) => { + eduToolApi.setMinimizedState({ + minimized: minimized, + widgetId: id, + minimizedProperties: { + minimizedCollapsed: + widgetUIStore.widgetInstanceList.find((w) => w.widgetId === id)?.minimizedProperties + ?.minimizedCollapsed || false, + }, + }); + } + const handleClick = () => { - if (eduToolApi.isWidgetMinimized(id)) { - eduToolApi.setMinimizedState({ - minimized: false, - widgetId: id, - minimizedProperties: { - minimizedCollapsed: - widgetUIStore.widgetInstanceList.find((w) => w.widgetId === id)?.minimizedProperties - ?.minimizedCollapsed || false, - }, - }); - } else { - updateZIndex(); - onWidgetIdChange(id) - if (id === 'breakout') { - breakoutUIStore.setDialogVisible(true); - } else if (id === 'rtt') { - eduToolApi.setWidgetVisible('rtt', true); - eduToolApi.sendWidgetVisibleIsShowRtt(id, true); - eduToolApi.changeSubtitleOpenState() - } else { - if (id === "rttbox") { + //当前widget是否是最小化的 + const widgetIsMinimized = eduToolApi.isWidgetMinimized(id); + //档位widget是否是正在使用的状态 + const widgetActive = (RttTypeEnum.SUBTITLE === id || RttTypeEnum.CONVERSION === id) ? widgetUIStore.widgetActiveList.includes(id) : active; + switch (id) { + case RttTypeEnum.SUBTITLE: + if(widgetIsMinimized){setMinimizedState(false)}else{ + updateZIndex(); + onWidgetIdChange(id) + //如果没有激活使用的话也要弹窗显示 + if(!widgetActive){ + eduToolApi.setWidgetVisible(id, true); + } + eduToolApi.sendWidgetVisibleIsShowRtt(id, true); + eduToolApi.changeSubtitleOpenState() + } + break + case RttTypeEnum.CONVERSION: + updateZIndex(); + onWidgetIdChange(id) + if(!eduToolApi.isWidgetVisible(id)){ + eduToolApi.setWidgetVisible(id, true); + } + if(widgetActive){ + setMinimizedState(!widgetIsMinimized) + }else{ eduToolApi.sendWidgetRttboxShow(id, true); eduToolApi.changeConversionOpenState() } - widgetUIStore.createWidget(id); - } + break; + case 'breakout': + if (widgetIsMinimized) { setMinimizedState(false) } else { + updateZIndex(); + onWidgetIdChange(id) + breakoutUIStore.setDialogVisible(true); + } + break; + default: + if (widgetIsMinimized) { setMinimizedState(false) } else { + widgetUIStore.createWidget(id); + updateZIndex(); + onWidgetIdChange(id) + } + break; } onClick(); }; @@ -154,8 +184,7 @@ const ToolBoxItem: FC = observer((props) => {
{label} - {dropupActive&&
handleSettingClick}> -
} + {(id === "rtt" || id === "rttbox") &&
handleSettingClick}>
} {active &&
}
); diff --git a/src/containers/status-bar/widgets/index.tsx b/src/containers/status-bar/widgets/index.tsx index e7b95fd..cb1a5bf 100644 --- a/src/containers/status-bar/widgets/index.tsx +++ b/src/containers/status-bar/widgets/index.tsx @@ -10,6 +10,7 @@ import { useEffect, useState } from 'react'; import { AgoraExtensionWidgetEvent } from '@ui-scene/extension/events'; import { useZIndex } from '@ui-scene/utils/hooks/use-z-index'; import { useI18n } from 'agora-common-libs'; +import { RttTypeEnum } from '@ui-scene/uistores/type'; export const StatusBarWidgetSlot = observer(() => { const { eduToolApi } = useStore(); @@ -195,47 +196,60 @@ const RttMinimize = observer(() => { const transI18n = useI18n(); const { eduToolApi: { isWidgetMinimized, setMinimizedState }, - widgetUIStore: { - widgetInstanceList, - classroomStore: { - widgetStore: { widgetController }, - }, + widgetUIStore: { widgetInstanceList,widgetActiveList }, + classroomStore: { + widgetStore: { widgetController }, }, } = useStore(); - const { updateZIndex } = useZIndex('rttbox'); - const [countdownTimerState, setCountdownTimerState] = useState({ - current: 0, - state: CountdownTimerState.STOPPED, - tooltip: '', - icon: SvgIconEnum.FCR_V2_RTT, - }); - const countdownTimer = widgetInstanceList.find((w) => w.widgetId === 'rttbox'); - - const handleClick = () => { - if (isWidgetMinimized('rttbox')) { - setMinimizedState({ - minimized: false, - widgetId: 'rttbox', - minimizedProperties: { - minimizedCollapsed: false, - }, + const widgetId = RttTypeEnum.CONVERSION; + const { updateZIndex } = useZIndex(widgetId); + const [show, setShow] = useState(false) + + const rttWidget = widgetInstanceList.find((w) => w.widgetId === widgetId); + useEffect(() => { + if (widgetController) { + widgetController.addBroadcastListener({ + messageType: AgoraExtensionWidgetEvent.RttConversionOpenSuccess, + onMessage: () => { setShow(true) }, + }); + widgetController.addBroadcastListener({ + messageType: AgoraExtensionWidgetEvent.RttConversionCloseSuccess, + onMessage: () => { setShow(false) }, }); - } else { - updateZIndex(); } - }; + }, [ widgetController]); - const { current, state, icon } = countdownTimerState; - return countdownTimer ? ( -
- - {transI18n('fcr_device_option_rtt')} - {/* 转写中... */} -
+ const handleClick = () => { + if(!rttWidget){ + widgetController?.broadcast(AgoraExtensionWidgetEvent.RttSettingShowConversion) + }else{ + if (isWidgetMinimized(widgetId)) { + updateZIndex(); + setMinimizedState({ + minimized: false, + widgetId: widgetId, + minimizedProperties: { + minimizedCollapsed: false, + }, + }); + } else { + setMinimizedState({ + minimized: true, + widgetId: widgetId, + minimizedProperties: { + minimizedCollapsed: false, + }, + }); + } + } + }; + return show ? ( +
+ + {transI18n('fcr_device_option_rtt')} + {/* 转写中... */} +
) : null; }); diff --git a/src/extension/edu-tool.ts b/src/extension/edu-tool.ts index e492bfa..7339859 100644 --- a/src/extension/edu-tool.ts +++ b/src/extension/edu-tool.ts @@ -1,12 +1,13 @@ -import { AgoraWidgetController } from 'agora-edu-core'; +import { AgoraWidgetController,EduRoleTypeEnum } from 'agora-edu-core'; import { Log, Logger, bound } from 'agora-rte-sdk'; import { action, computed, IReactionDisposer, observable } from 'mobx'; import { AgoraExtensionRoomEvent, AgoraExtensionWidgetEvent } from './events'; import { SvgIconEnum } from '@components/svg-img'; import { computedFn } from 'mobx-utils'; -import { StreamMediaPlayerOpenParams, WebviewOpenParams } from '@ui-scene/uistores/type'; +import { RttTypeEnum, StreamMediaPlayerOpenParams, WebviewOpenParams } from '@ui-scene/uistores/type'; import { transI18n, FcrUISceneWidget } from 'agora-common-libs'; import { AgoraIMMessageBase, CabinetToolItem } from './type'; +import { useStore } from '@ui-scene/utils/hooks/use-store'; @Log.attach({ proxyMethods: false }) export class EduTool { @@ -22,7 +23,8 @@ export class EduTool { onTrackUpdate: () => {}, }; @observable - private _registeredCabinetToolItems: CabinetToolItem[] = [ + //@ts-ignore + private _registeredCabinetToolItems: CabinetToolItem[] = EduRoleTypeEnum.student === window.EduClassroomConfig.sessionInfo.role ? [] : [ { name: transI18n('fcr_tool_box_breakout_room'), id: 'breakout', @@ -268,6 +270,11 @@ export class EduTool { @action.bound private _handleRegisterCabinetTool(cabinetToolItem: CabinetToolItem) { + //@ts-ignore + if (EduRoleTypeEnum.student === window.EduClassroomConfig.sessionInfo.role && !(RttTypeEnum.SUBTITLE === cabinetToolItem.id || RttTypeEnum.CONVERSION === cabinetToolItem.id)) { + return + } + const item = this._registeredCabinetToolItems.find(item=>item.id === cabinetToolItem.id) if (!item) { this._registeredCabinetToolItems.push(cabinetToolItem); diff --git a/src/extension/events.ts b/src/extension/events.ts index f6b7354..bf758d7 100644 --- a/src/extension/events.ts +++ b/src/extension/events.ts @@ -177,6 +177,22 @@ export enum AgoraExtensionWidgetEvent { UpdatePosition = 'update-position', //更新倒计时状态 CountdownTimerStateChanged = 'countdown-timer-state-changed', + //widget启用状态改变处理 + WidgetActiveStateChange = 'WidgetActiveStateChange', //显示转写弹窗 RttShowConversion = "RttShowConversion", + //字幕功能开启成功 + RttSubtitleOpenSuccess = "RttSubtitleOpenSuccess", + //字幕功能关闭成功 + RttSubtitleCloseSuccess = "RttSubtitleCloseSuccess", + //转写功能开启成功 + RttConversionOpenSuccess = "RttConversionOpenSuccess", + //转写功能关闭成功 + RttConversionCloseSuccess = "RttConversionCloseSuccess", + //修改字幕开启状态 + RttChangeToSubtitleOpenState = "RttChangeToSubtitleOpenState", + //修改转写开启状态 + RttChangeToConversionOpenState = "RttChangeToConversionOpenState", + //设置里面的显示转写视图 + RttSettingShowConversion = "RttSettingShowConversion", } diff --git a/src/uistores/action-bar.ts b/src/uistores/action-bar.ts index afce6f5..d9e4008 100644 --- a/src/uistores/action-bar.ts +++ b/src/uistores/action-bar.ts @@ -125,7 +125,7 @@ export class ActionBarUIStore extends EduUIStoreBase { } @computed get showToolBox() { - return this.getters.isHost; + return this.getters.isHost || this.getters.isStudent; } @computed get showWhiteBoard() { return this.getters.isHost; @@ -142,6 +142,9 @@ export class ActionBarUIStore extends EduUIStoreBase { @computed get showCloud() { return this.getters.isHost; } + @computed get isStudent() { + return this.getters.isStudent; + } @observable showLeaveOption = false; @observable leaveFlag = 1; diff --git a/src/uistores/type.ts b/src/uistores/type.ts index 2017cd0..3143fa1 100644 --- a/src/uistores/type.ts +++ b/src/uistores/type.ts @@ -120,3 +120,10 @@ export type StreamMediaPlayerOpenParams = { url: string; title: string; }; +//rtt功能类型枚举 +export enum RttTypeEnum{ + //字幕 + SUBTITLE = "rtt", + //转写 + CONVERSION = "rttbox", +} \ No newline at end of file diff --git a/src/uistores/widget.ts b/src/uistores/widget.ts index 05f8113..be88e2f 100644 --- a/src/uistores/widget.ts +++ b/src/uistores/widget.ts @@ -12,7 +12,7 @@ import { import { ToastApi } from '@components/toast'; import { AgoraExtensionRoomEvent, AgoraExtensionWidgetEvent } from '@ui-scene/extension/events'; import { ConfirmDialogProps } from '@components/dialog/confirm-dialog'; -import { CommonDialogType } from './type'; +import { CommonDialogType, RttTypeEnum } from './type'; import { v4 as uuidv4 } from 'uuid'; @Log.attach({ proxyMethods: false }) export class WidgetUIStore extends EduUIStoreBase { @@ -26,6 +26,8 @@ export class WidgetUIStore extends EduUIStoreBase { private _widgetInstanceRenderKeys: Record = {}; @observable private _widgetInstances: Record = {}; + //widget是否正在使用的列表,当前为rtt新增的变量,后续也可以添加使用 + private _widgetActiveList: string[] = []; private _stateListener = { onActive: this._handleWidgetActive, onInactive: this._handleWidgetInactive, @@ -49,6 +51,11 @@ export class WidgetUIStore extends EduUIStoreBase { return Object.values(this._widgetInstances); } + @computed + get widgetActiveList() { + return this._widgetActiveList; + } + get widgetInstanceRenderKeys() { return this._widgetInstanceRenderKeys; } @@ -295,7 +302,7 @@ export class WidgetUIStore extends EduUIStoreBase { this._disposers.push( reaction( - () => ({controller: this.classroomStore.widgetStore.widgetController,}), + () => ({controller: this.classroomStore.widgetStore.widgetController}), ({ controller }) => { if (controller) { controller.removeBroadcastListener({ @@ -303,7 +310,11 @@ export class WidgetUIStore extends EduUIStoreBase { onMessage: this._handleVisibleRttConversionChange, }) controller.addBroadcastListener({ - messageType: AgoraExtensionWidgetEvent.RttShowConversion, + messageType: AgoraExtensionWidgetEvent.WidgetActiveStateChange, + onMessage: this._handleWidgetActiveStateChange, + }) + controller.addBroadcastListener({ + messageType: AgoraExtensionWidgetEvent.RttSettingShowConversion, onMessage: this._handleVisibleRttConversionChange, }) } @@ -381,19 +392,40 @@ export class WidgetUIStore extends EduUIStoreBase { @bound private _handleVisibleRttConversionChange() { - this.createWidget("rttbox"); + this.createWidget(RttTypeEnum.CONVERSION); if (this.classroomStore.widgetStore.widgetController) { this.classroomStore.widgetStore.widgetController.broadcast(AgoraExtensionWidgetEvent.SetVisible, { - widgetId: "rttbox", + widgetId: RttTypeEnum.CONVERSION, visible: true, }); } } + //widge状态改变监听 + @bound + @action + private _handleWidgetActiveStateChange(message:{state:boolean,widgetId:string}) { + if(message.state){ + this._widgetActiveList.push(message.widgetId) + }else{ + const index = this._widgetActiveList.indexOf(message.widgetId) + if(index >= 0){ + this._widgetActiveList.splice(index,1) + } + } + } onDestroy() { this.classroomStore.widgetStore.widgetController?.removeBroadcastListener({ messageType: AgoraExtensionWidgetEvent.RttShowConversion, onMessage: this._handleVisibleRttConversionChange, }) + this.classroomStore.widgetStore.widgetController?.removeBroadcastListener({ + messageType: AgoraExtensionWidgetEvent.WidgetActiveStateChange, + onMessage: this._handleWidgetActiveStateChange, + }) + this.classroomStore.widgetStore.widgetController?.removeBroadcastListener({ + messageType: AgoraExtensionWidgetEvent.RttSettingShowConversion, + onMessage: this._handleVisibleRttConversionChange, + }) this._disposers.forEach((d) => d()); this._disposers = []; }