import SDKBaseView from "./SDKBaseView"; import SDKControllerBase from "../SDKController/SDKControllerBase"; import * as SDKENUM from "../SDKConst/SDKEnum"; import * as SDKLogicsCore from "../SDKLogics/SDKLogicsCore"; import * as SDKRegistCommand from "../SDKConst/SDKRegistCommand"; import SDKUserInfo from "../SDKLogics/SDKUserInfo"; import SDKPacket from "../SDKNetwork/SDKPacket"; import SDKPacketPool from "../SDKNetwork/SDKPacketPool"; import { DOMButton, DOMCheckbox, SDKControllerUIComponents, setDefaultStyle, SDKControllerUIComponent, setObserverStyle } from "./SDKControlUI"; export default class SDKWebDashBoardView extends SDKBaseView { /**菜单栏 */ protected _menuContainer: any; /** 分屏容器节点 */ protected _childContainer: any; //UI组件集合 protected _components: any; //前菜单名 protected _lastMenuName: string; //当前菜单名 protected _currentMenuName: string; /**学生上台模式。。。某一个学生操作,其他的人看*/ //protected _btnStudents: Array; /**鼠标形态 */ protected _mouseName: string; /**学生ids */ protected _userIds: Array; /**学生iframe */ protected _userIframes: Array; /**学生iframe初始化 */ protected _userIframeInits: Array; /**教学模式 */ protected _teachingMode: SDKENUM.TEACHING_MODE; /**控制者id */ protected _controllerId: string; protected _isFirstInit: boolean; protected _isShowControllUI: boolean; constructor(controller: SDKControllerBase) { super(controller); this.initUI(); } private initUI() { this.initRem(); this.initMenuContaner(); this.initMenuContent('Video'); this.setController(this._controllerId); this.teachModleChange(SDKLogicsCore.controllState.teachingMode); } /** * 计算REM */ private initRem() { let rem = window.innerWidth / window.innerHeight > 1.83 ? window.innerHeight / 10.8 : window.innerWidth / 19.2; document.getElementsByTagName('html')[0].style.fontSize = rem + 'px'; } /** * 创建菜单容器, * 设置界面样式 */ private initMenuContaner(): void { // let style = document.createElement('style'); // style.innerText = 'body{overflow:hidden;background-color:transparent !important;}div{background-color:transparent !important;}#controllCenter{position:absolute;left:0;top:0;z-index:999;}#controllCenter>button{padding:3px;}.inspliting canvas{display:none}.inspliting video{display:none}'; // document.getElementsByTagName('head')[0].appendChild(style); //设置样式 if (SDKLogicsCore.parameterVo.isTeacher()) { setDefaultStyle(); } else if (SDKLogicsCore.parameterVo.isOberverTeacher()) { setObserverStyle(); } this._menuContainer = document.createElement('div'); this._menuContainer.setAttribute('id', 'controllCenter'); document.body.appendChild(this._menuContainer); this._childContainer = document.createElement('div'); this._childContainer.setAttribute('id', 'childIframes'); this._childContainer.style.display = 'none'; this._childContainer.style.backgroundColor = '#2F2F37'; document.body.appendChild(this._childContainer); } /** * 初始化菜单内容 */ private initMenuContent(menuName: string): void { let self = this; this._lastMenuName = this._currentMenuName; this._currentMenuName = menuName; //隐藏所有ui组件 // this._menuContainer.childNodes.forEach(element => { // element.style.display = 'none'; // }); Array.prototype.forEach.call(this._menuContainer.childNodes, element =>{ element.style.display = 'none'; }); let componentList = []; let componentHideList = []; //加入当前ui组件模块但是一开始不显示 switch (menuName) { case 'Video': componentList = ['prev', 'next', 'forward', 'backward', 'play', 'split', 'controll']; componentHideList = ['forward', 'backward', 'play']; break; case 'Checkpoint': componentList = ['prev', 'next', 'prevCheck', 'nextCheck', 'split', 'controll']; componentHideList = ['prevCheck', 'nextCheck']; break; case 'Split': componentList = ['split']; componentHideList = []; break; default: throw new TypeError(`教师控制面板:未定义的控制模组${menuName}`); } for (let item of componentList) { let comp = SDKControllerUIComponents[item]; if (this._components[item]) { this._components[item].show(); // this.components[item].refresh(comp); continue; } if (comp.type == 'button') { this.createButton(comp) } else if (comp.type == 'checkbox') { this.createCheckbox(comp); } this._components[item].onMouseOver = function () { self.onMouseOver(); }; this._components[item].onMouseOut = function () { self.onMouseOut(); } } for (let item of componentHideList) { let comp = SDKControllerUIComponents[item]; if (this._components[item]) { this._components[item].hide(); // this.components[item].refresh(comp); continue; } if (comp.type == 'button') { this.createButton(comp, true); } else if (comp.type == 'checkbox') { this.createCheckbox(comp); } } this._components["controll"].onClick = function () { if (this.status == "teacher") { self.onTeacherControll(); } else { self.onFreeControll(); } }; this._components["split"].onClick = function () { if (this.status == "full") { self.onTeacherModle(); } else { self.onSplitModle(); } }; this._components["prev"].onClick = function () { self._controller.dispatcherHandle("gamePrevScene", null, true); } this._components["next"].onClick = function () { self._controller.dispatcherHandle("gameNextScene", null, true); } } //这个className对应的是样式类,请一定要对号入座 private createButton(comp: SDKControllerUIComponent, notShow?: boolean) { let button = new DOMButton(comp, this); if (notShow) button.hide(); this._components[comp.name] = button; this._menuContainer.appendChild(button.domElem); } private createCheckbox(comp: SDKControllerUIComponent, notShow?: boolean) { let checkbox = new DOMCheckbox(comp, this); if (notShow) checkbox.hide(); this._components[comp.name] = checkbox; this._menuContainer.appendChild(checkbox.domElem); } protected onMouseOver(): void { this._mouseName = document.body.style.cursor; this._controller.dispatcherHandle("gameMouseLeave", null, false); } protected onMouseOut(): void { if (this._teachingMode == SDKENUM.TEACHING_MODE.TYPE_TEACHING) { this._controller.dispatcherHandle("gameMouseEnter", this._mouseName, false); } } /** * 切换到教学模式 */ protected onTeacherModle(): void { this.teahcerModle(); this._controller.dispatcherCMD(SDKRegistCommand.TEACH_MODLE_CHANGE, this._teachingMode, false); } protected teahcerModle(): void { if (this._teachingMode == SDKENUM.TEACHING_MODE.TYPE_TEACHING) { return; } this._teachingMode = SDKENUM.TEACHING_MODE.TYPE_TEACHING; SDKLogicsCore.controllState.teachingMode = this._teachingMode; this.hideUserIframes(); this.initMenuContent('Video'); this.updateChangeSceneState(); this.displayControll(this._isShowControllUI); } /** * 分屏查看模式 */ protected onSplitModle(): void { this.spliteModle(); this._controller.dispatcherCMD(SDKRegistCommand.TEACH_MODLE_CHANGE, this._teachingMode, false); } protected spliteModle(): void { if (this._teachingMode == SDKENUM.TEACHING_MODE.TYPE_INSPECTION) { return; } this._teachingMode = SDKENUM.TEACHING_MODE.TYPE_INSPECTION; SDKLogicsCore.controllState.teachingMode = this._teachingMode; this.updateSplitFrames(); this.initMenuContent('Split'); } /** * 更新分屏信息 */ updateSplitFrames(): void { this.UpdateUserIframes(); this.showUserIframes(); if (!this._isFirstInit) { //初始化子iframe脚本 let time: number = 1000; setTimeout(() => { this.synchronizeIframes(); }, time); } } /** *同步各个学生最新的状态 */ private synchronizeIframes(): void { let index = 0, count = 0; let userId: string; let userInfo: SDKUserInfo; console.log("同步分屏。。。。。学生屏幕个数:", this._userIframes.length); count = this._userIframes.length; for (index = 0; index < count; index++) { userId = this._userIds[index]; userInfo = SDKLogicsCore.userInfos.getUserInfoById(userId); if (!userInfo) { console.error("userInfo为空........"); continue; } if (!userInfo.isActive) { console.log("userInfo掉线了........"); continue; } this.synchronizeIframe(userInfo); } } /** * 同步某一个学生的最新状态 */ private synchronizeIframe(userInfo: SDKUserInfo): void { let index: number, count: number; let packet: SDKPacket; let userIndex: number; userIndex = this._userIds.indexOf(userInfo.userId); if (userIndex == -1) { console.log("找不到userInfo............"); return; } index = userInfo.getLastMainIndex(); if (index == -1) { return; } count = userInfo.count(); for (index; index < count; index++) { packet = userInfo.getPacketByIndex(index); let sceneName : string = packet.data; if (SDKRegistCommand.EVENTS_LIST.indexOf(packet.name) == -1) { if (packet.name != 'gameChangeScene' && packet.isMainFrame) { this.checkChangeScene(packet, this._userIframes[userIndex].contentWindow); } this.sendSubPacket(packet, this._userIframes[userIndex].contentWindow); if(sceneName == 'gameChangeScene'){ this.initScene(sceneName,this._userIframes[userIndex].contentWindow); } } else { console.log("系统消息不同步给分屏。。。", packet); } } } private checkChangeScene(packet: SDKPacket, window: any): void { let tempPacket: SDKPacket; console.log("分屏同步场景。。。。。"); tempPacket = SDKPacketPool.Acquire(packet.name); packet.clone(tempPacket); tempPacket.name = 'gameChangeScene'; tempPacket.sendId = SDKLogicsCore.parameterVo.userId; tempPacket.data = packet.secene; this.sendSubPacket(tempPacket, window); } private initScene(sceneName : string, window: any): void { let tempPacket: SDKPacket; console.log("初始化场景。。。。。"); tempPacket = SDKPacketPool.Acquire('gameSceneReset'); tempPacket.sendId = SDKLogicsCore.parameterVo.userId; tempPacket.isMainFrame = false; tempPacket.data = sceneName; this.sendSubPacket(tempPacket, window); } /** * 向子iframe 发送消息 * @param packet * @param target */ public sendSubPacket(packet: SDKPacket, target: Window = window.parent) { console.log("向子iframe派发消息.....", packet); target.postMessage(packet, '*'); } /**更新学生的iframes */ private UpdateUserIframes(): void { let index = 0, count = 0; let userInfo: SDKUserInfo; count = SDKLogicsCore.userInfos.getCount(); for (index = 0; index < count; index++) { userInfo = SDKLogicsCore.userInfos.getUserInfoByIndex(index); //过滤掉自己 if (userInfo.userId == SDKLogicsCore.parameterVo.userId) { continue; } //过滤掉已经有的 if (this._userIds.indexOf(userInfo.userId) != -1) { continue; } //过滤掉监视的对象 if (userInfo.userId == SDKLogicsCore.parameterVo.observerId) { continue; } this.addUserIframe(userInfo); } console.log("totalIframes....", this._userIframes.length); } private studentHandle(studentId: number): void { console.log(studentId); } private onTeacherControll(): void { if (this._controllerId == SDKLogicsCore.parameterVo.userId) { return; } this._controllerId = SDKLogicsCore.parameterVo.userId; SDKLogicsCore.controllState.controllerId = this._controllerId; this._controller.dispatcherCMD(SDKRegistCommand.CONTROLLER_CHANGE, this._controllerId, false); this.updateChangeSceneState(); } private onFreeControll(): void { if (this._controllerId == '-1') { return; } this._controllerId = '-1'; SDKLogicsCore.controllState.controllerId = this._controllerId; this._controller.dispatcherCMD(SDKRegistCommand.CONTROLLER_CHANGE, this._controllerId, false); this.updateChangeSceneState(); } private updateChangeSceneState(): void { if (SDKLogicsCore.controllState.isFullOwn()) { this._components["prev"].show(); this._components["next"].show(); } else { this._components["prev"].hide(); this._components["next"].hide(); } } private addUserIframe(userInfo: SDKUserInfo): void { let child = document.createElement('div'); child.classList.add('sdk-child'); //增加一个新的iframe let iframe = document.createElement('iframe'); iframe.src = this.createStudentUrl(userInfo.userId);; iframe.setAttribute('border', 'none'); iframe.classList.add('sdk-child-iframe');//这个类一定要有 child.appendChild(iframe); let name = document.createElement('div'); name.classList.add('sdk-child-name'); name.innerText = `学生${userInfo.name}`; child.appendChild(name); this._childContainer.appendChild(child); this._userIframes.push(iframe); this._userIds.push(userInfo.userId); this._userIframeInits.push(false); console.log("iframeSrc....", iframe.src); } /**生成一个新的url */ private createStudentUrl(studentId: string): string { let parameterVo = SDKLogicsCore.parameterVo.clone(); parameterVo.userId = studentId; parameterVo.role = SDKENUM.USER_ROLE.STUDENT; parameterVo.usage = SDKENUM.GAME_TYPE.SPLITSCREEN; return parameterVo.getUrl(); } /** * 隐藏学生的iframes */ private hideUserIframes(): void { let index = 0, count = 0; let packet: SDKPacket; count = this._userIframes.length; for (index = 0; index < count; index++) { //packet = SDKPacketPool.Acquire(SDKRegistCommand.GAME_STOP); //this.sendSubPacket(packet,this._userIframes[index].contentWindow); this._userIframes[index].style.display = 'none'; //this._btnStudents[index].style.display = "none"; } //document.body.classList.remove('inspliting'); this._childContainer.style.display = 'none'; document.body.classList.remove('inspliting'); document.body.classList.remove(`split${this._userIframes.length}`); } /** * 显示学生的iframes */ private showUserIframes(): void { let index = 0, count = 0; let packet: SDKPacket; let userInfo: SDKUserInfo; count = this._userIframes.length; for (index = 0; index < count; index++) { //packet = SDKPacketPool.Acquire(SDKRegistCommand.GAME_RESUME); //this.sendSubPacket(packet,this._userIframes[index].contentWindow); userInfo = SDKLogicsCore.userInfos.getUserInfoById(this._userIds[index]); if (userInfo.isActive) { this._userIframes[index].style.display = 'block'; //this._btnStudents[index].style.display = "block"; } else { this._userIframes[index].style.display = 'none'; //this._btnStudents[index].style.display = "none"; } } document.body.classList.add('inspliting'); this._childContainer.style.display = 'block'; document.body.classList.add(`split${this._userIframes.length}`); } /**设置权限 历史恢复使用*/ public setController(controllerId: string): void { this._controllerId = controllerId; if (this._controllerId == SDKLogicsCore.parameterVo.userId || this._controllerId == SDKLogicsCore.parameterVo.observerId) { this._components["controll"].setStatus("teacher"); } else { this._components["controll"].setStatus("student"); } this.updateChangeSceneState(); } /** * 子iframe通知初始化准备好了 * @param userId 学生id */ public splitGameReady(userId: string): void { let userInfo: SDKUserInfo; console.log("同步分屏。。。。。。学生id:", userId); userInfo = SDKLogicsCore.userInfos.getUserInfoById(userId); if (!userInfo) { console.error("userInfo为空........"); return; } let index = this._userIds.indexOf(userId); if (index != -1) { this._userIframeInits[index] = true; } this.synchronizeIframe(userInfo); this._isFirstInit = false; } /** * 收到学生的信息 同步到分屏中去。。。。 * @param packet */ public dispatcherSubIframe(packet: SDKPacket) { let index = 0, count = 0; console.log("收到消息同步分屏。。。。。"); count = this._userIframes.length; for (index = 0; index < count; index++) { console.error("游戏模式......", this._controllerId); if (this._controllerId == '-1') { //各玩各的时候 if (packet.sendId == this._userIds[index]) { //分屏 同步到具体的一个iframe this.sendSubPacket(packet, this._userIframes[index].contentWindow); } } else if (this._controllerId != "") { this.sendSubPacket(packet, this._userIframes[index].contentWindow); } } } /** * 更新用户信息 */ public updateUsers(): void { if (this._teachingMode == SDKENUM.TEACHING_MODE.TYPE_INSPECTION) { console.log("学生更新。。。。"); this.updateSplitFrames(); } } /** * 显示或者隐藏老师切换控制权限 */ public displayControll(isShow: boolean): void { this._isShowControllUI = isShow; if (isShow) { this._components["controll"].show(); } else { this._components["controll"].hide(); } } /** * 切换教学模式 * @param teacherModle */ public teachModleChange(teacherModle: SDKENUM.TEACHING_MODE) { if (teacherModle == SDKENUM.TEACHING_MODE.TYPE_TEACHING) { this._components["split"].setStatus("full"); this.teahcerModle(); } else if (teacherModle == SDKENUM.TEACHING_MODE.TYPE_INSPECTION) { this._components["split"].setStatus("split"); this.spliteModle(); } } public reset(): void { super.reset(); this._isFirstInit = true; this._userIds = []; this._userIframes = []; this._userIframeInits = []; //this._btnStudents = []; this._mouseName = 'auto'; this._components = {}; this._lastMenuName = ""; this._currentMenuName = ""; this._isShowControllUI = true; this._controllerId = SDKLogicsCore.controllState.controllerId; this._teachingMode = SDKENUM.TEACHING_MODE.TYPE_TEACHING; } public destroy(): void { super.destroy(); this._userIds = null; this._userIframes = null; //this._btnStudents = null; this._userIframeInits = null; } }