Commit 59197369 authored by 李维's avatar 李维

Update to new template

parent 809ed87d
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
# dependencies # dependencies
/node_modules /node_modules
/publish
# profiling files # profiling files
chrome-profiler-events*.json chrome-profiler-events*.json
......
# ng-template-generator # ng-template-generator
angularjs技术框架下的H5互动模板框架脚手架 angularjs技术框架下的H5互动模板框架脚手架,基于NG-ZORRO实现快速开发基于绘玩云的H5互动课件。
\ No newline at end of file
# 使用简介
## 前期准备
* git下载 https://git-scm.com/downloads
* nodejs下载 https://nodejs.org/zh-cn/download/
* 谷歌浏览器下载 https://www.google.cn/chrome/
都下载最新版就行,然后默认安装就可以
## 生成项目
* 登录绘玩云课件开发平台:http://staging-teach.ireadabc.com/
* 点击“登录账号,查看我的课件”
* 输入测试的用户名/密码:developers/12345678
* 在右上角“个人中心”的下拉菜单里,点击“我的模板” 菜单,然后点击“新建模板”, 填写必要的信息,在“技术选型”一项上选择“Angular”
* 点击“确定”后,列表页就会出现一个新生成的模板项目
* 在项目的卡片下找到“开发”按钮,则会弹出相对应的git地址
## 获取并启动项目
```
// xxx 是上面项目对应的Git地址
git clone xxx
cd 项目名称/
npm install -g yarn
yarn install
npm start
//启动成功后打开浏览器,输入:http://localhost:4200 则可以看到这个项目的初始化效果了
```
## 项目结构
|-- bin
|-- dist
|-- e2e
|-- node_modules
|-- publish
|-- src
| |-- app
| | |-- common
| | |-- form
| | |-- pipes
| | |-- play
| | |-- services
| | |-- style
| | |-- app.component.html
| | |-- app.component.scss
| | |-- app.component.ts
| | |-- app.module.ts
| |-- assets
| |-- environments
| |-- services
| |-- index.html
| |-- main.ts
| |--.......
* 其中 play 文件夹是H5模板展示页面,form文件夹是模板的配置页面
* common文件夹是以往做过的模板积累的一些比较常用的 AngularJs 的组件
* assets文件夹存放模板样式的静态资源,例如小图标、背景图片、字体、样式等等
* 其他文件夹开发者可以不做任何更改
## 开始开发
本脚手架的页面类UI框架是基于 [NG-ZORRO](https://ng.ant.design/docs/introduce/zh "With a Title") 框架实现的,在配置页面(form文件夹),一些表单输入,上传图片等组件也可以使用 NG-ZORRO 现成的组件
### 开发配置页面(form/)
配置页面主要作用是为了呈现多样化模板,提高H5模板的高复用性、灵活性提供的一个配置工具,根据H5模板的设计规划或特性,会规定某些元素是可以配置的,比如背景图片、音频、选项、标题等等等等。(课件制作者) 通过配置页面,就可以灵活的更换这些,从而形成多种多样的课件。
配置页面的开发要求很简单,我们不关心布局、样式、交互等所有实现细节与效果,只需调用两个内置的全局接口即可:
* setData 接口,用于将配置的数据存储到云端。
此方法是一个异步的方法,接收三个必要参数
obj: 一个json对象
callback: 回调函数
t_name: 模板名称
一般使用例子如下:
```
// ts语法,不能直接使用js的window对象自定义方法
(<any> window).courseware.setData(obj, callback, t_name);
```
* getData 接口,用于当点击修改的时候将配置的数据从云端获取下来。
此方法是一个异步的方法,接收两个必要参数
> callback: 回调函数, 回调函数里会得到云端保存的数据
> t_name: 模板名称
一般使用例子如下:
```
// ts语法,不能直接使用js的window对象自定义方法
const getData = (<any> window).courseware.getData;
getData((data) => {
//data 就是云端获取的数据,也就是setData方法存到云端的那个obj
//模板开发者需要根据数据,依次填写到表单的相应位置,方便用户二次修改编辑
});
```
### 开发展示页面(play/)
展示页面主要是呈现模板,通过H5技术,实现多样化的交互与展示方式。
展示页面更简单,开发者可以运用各种技术,实现Web端可以实现的任何效果,包括2D、3D、动画、游戏等各种场景,把表单配置的数据获取到,用于渲染相对应的页面即可:
* getData 接口,用于当点击修改的时候将配置的数据从云端获取下来。
此方法是一个异步的方法,接收两个必要参数
> callback: 回调函数, 回调函数里会得到云端保存的数据
> t_name: 模板名称
一般使用例子如下:
```
// ts语法,不能直接使用js的window对象自定义方法
const getData = (<any> window).courseware.getData;
getData((data) => {
//data 就是云端获取的数据,也就是setData方法存到云端的那个obj
//模板开发者需要根据数据来渲染或控制展示页面的呈现,达到模板的互动目的
});
```
### 互动课件
通过H5的交互方式,我们可以很轻松的制作在线的互动课件,使老师端与学生端实现联动,使在线课堂更具有交互性。
* onEvent 定义事件:用于自定义同步事件,配合多端互动使用,与sendEvent方法配合使用,用于监听多端发送的同步事件
参数
> evtName : 自定义事件的名称
> callback : 回调函数,回调函数里会得到传过来的数据
使用例子:
```
const cw = (<any> window).courseware;
//订阅一个事件
cw.onEvent('testEvent', (data,next) => {
console.log(data);
//处理事件的同步逻辑
//在逻辑处理完之后一定要执行next方法,用于解锁事件队列
next();
});
```
* sendEvent 发送事件:用于自定义同步事件,配合多端互动使用,与onEvent方法配合使用,用于对端发送同步事件
参数
> evtName : 自定义事件的名称
> data : 传递的参数
使用例子:
```
const cw = (<any> window).courseware;
//发送事件
//这样,所有端(教师、学生) 都会触发 testEvent 方法
cw.sendEvent('testEvent', 'Hello world');
```
* storeAspect 存储切面数据: 课件的切面状态数据;互动课件需要每一个开发者设计切面状态,用于学生进入已经进行的课件,恢复课件同步。例如老师讲图片轮播到第四页,这个时候学生进入教师,要恢复到第四页,才能跟老师同步上课。
参数
> data : 保存的数据,一个JSON对象
使用例子:
```
const cw = (<any> window).courseware;
//存储切面数据,用于学生进入教室,同步课堂信息等
cw.storeAspect({page: 5});
```
* getAspect 获取切面数据: 课件的切面状态数据;互动课件需要每一个开发者设计切面状态,用于学生进入已经进行的课件,恢复课件同步。例如老师讲图片轮播到第四页,这个时候学生进入教师,要恢复到第四页,才能跟老师同步上课。
参数
> callback : 获取切面数据的回调函数
使用例子:
```
const cw = (<any> window).courseware;
//存储切面数据,用于学生进入教室,同步课堂信息等
cw.getAspect(function(aspect){
//恢复切面状态的逻辑
});
```
* 补充项
1) 有时候我们在实现模板效果的时候,需要一些基本的信息,比如教室信息、当前用户信息等等,例如,老师会显示某个按钮,而学生不显示,我们可以用如下方式获取教室信息;后续大部分静态信息都会完善到这个对象里
```
//获取教室信息,值得注意的是获取这个信息一定要再 getData方法之后,或者确保页面完成之后
getData((data, aspect) => {
let airClassInfo = window["air"].airClassInfo;
console.log(airClassInfo);
});
```
2) 互动课件的 getData 方法的回调函数里多返回了一个切面参数,类似如下:
```
const getData = (<any> window).courseware.getData;
getData((data, aspect) => {
//data 就是云端获取的数据,也就是setData方法存到云端的那个obj
//aspect 切面参数,用于恢复页面的状态
//模板开发者需要根据数据来渲染或控制展示页面的呈现,达到模板的互动目的
});
```
3) 一些必要的内置事件,通过监听这些事件,我们可以实现一些相关的功能
* userchange 事件,用来监听教室内部的人员变动情况,例如某人进入,某人退出都会触发此事件
示例:
```
const cw = (<any> window).courseware;
//订阅一个事件
cw.onEvent('userchange', (data,next) => {
//data的结构如下
/*{
* id: '变动用户的ID',
* connected: true/false, true: 连接的,false:d断开的
* status: 'connect/reconnect', connect:新建连接,reconnect:重新连接;这个字段在断开连接的事件里是缺失的
* all_user: [] 这个是现有的用户列表
*}
*/
console.log(data);
//处理事件的同步逻辑
//在逻辑处理完之后一定要执行next方法,用于解锁事件队列
next();
});
```
4) 测试互动课件
我们在本地开发中,无法模拟线上老师和学生互动的交互场景,所以提供了一套开发者测试的账号,如下:
测试地址:http://staging-ac.ireadabc.com/
老师用户名/密码:devtea / 1
学生用户名/密码: 学生1(13877777711 / 1) 学生2(13877777712 / 1)
测试方法:
1、首先开发者发布完模板之后,在制作课件的菜单下用这个模板制作一个课件
2、在本地打开两个浏览器窗口 一个登陆老师用户,另一个登陆学生用户
3、老师用户进去之后,就会有很多课件,这个时候双击自己制作的课件,学生的窗口就会同步的打开课件了
4、测试自己的交互事件,看看老师端和学生端是否是自己想要的展示效果
### 补充方法
在模板的编辑或展示过程中,还会经常遇到如下两个场景,特提供针对性的解决办法
1) 表单录入往往需要上传图片、音视频等多媒体文件,所以脚手架内置如下方法,用于获取一个上传到云端的接口方法
```
const uploadUrl = (<any> window).courseware.uploadUrl;
const uploadData = (<any> window).courseware.uploadData;
//例如用于NG-ZORRO的上传组件则如下写法:
<nz-upload class="p-image-uploader" [nzDisabled]="disableUpload"
[nzShowUploadList]="false"
nzAccept = "image/*"
[nzAction]="uploadUrl" <!-- 注意这里 -->
[nzData]="uploadData" <!-- 注意这里 -->
(nzChange)="handleChange($event)">
</nz-upload>
```
2) 在展示页面加载完成的时候,需要调用一下下面的方法,用于释放切换课件的遮罩层
```
//此方法为固定写法,
//其中t_name为模板名称,obj是云端存储的配置数据
window["air"].hideAirClassLoading(t_name,obj);
```
## 打包发布
模板开发完成之后,要推送到云平台上使用则需要进行打包发布操作
```
npm run publish
```
在项目根目录下执行上述命令,则在 ./publish 目录下生产一个 .zip的压缩包,此时打开云平台
http://staging-teach.ireadabc.com/
点击“模板管理” 菜单,找到对应的模板卡片,点击“发布”按钮,在弹出的对话框中选中压缩包,然后点击“确定”,上传完成后,则发布就成功了
\ No newline at end of file
...@@ -3,13 +3,9 @@ ...@@ -3,13 +3,9 @@
"version": 1, "version": 1,
"newProjectRoot": "projects", "newProjectRoot": "projects",
"projects": { "projects": {
"ng-one": { "ng-template-generator": {
"projectType": "application", "projectType": "application",
"schematics": { "schematics": {},
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "", "root": "",
"sourceRoot": "src", "sourceRoot": "src",
"prefix": "app", "prefix": "app",
...@@ -17,39 +13,26 @@ ...@@ -17,39 +13,26 @@
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular-devkit/build-angular:browser",
"options": { "options": {
"outputPath": "dist", "outputPath": "dist/ng-template-generator",
"index": "src/index.html", "index": "src/index.html",
"main": "src/main.ts", "main": "src/main.ts",
"polyfills": "src/polyfills.ts", "polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json", "tsConfig": "tsconfig.app.json",
"aot": false, "aot": true,
"assets": [ "assets": [
"src/favicon.ico", "src/favicon.ico",
"src/assets", "src/assets",
{ "glob": "**/*", "input": "src/assets/libs/service-worker/", "output": "/" },
{ {
"glob": "**/*", "glob": "**/*",
"input": "./node_modules/@ant-design/icons-angular/src/inline-svg/", "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/",
"output": "/assets/" "output": "/assets/"
},
{
"glob": "**/*",
"input": "./dist/game/",
"output": "/assets/cocos/"
} }
], ],
"styles": [ "styles": [
"src/styles.scss", "node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css", "src/styles.css"
"./node_modules/font-awesome/css/font-awesome.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"./node_modules/animate.css/animate.min.css"
], ],
"scripts": [ "scripts": []
"src/assets/libs/audio-recorder/lame.min.js",
"src/assets/libs/audio-recorder/worker.js",
"src/assets/libs/audio-recorder/recorder.js"
]
}, },
"configurations": { "configurations": {
"production": { "production": {
...@@ -64,28 +47,39 @@ ...@@ -64,28 +47,39 @@
"sourceMap": false, "sourceMap": false,
"extractCss": true, "extractCss": true,
"namedChunks": false, "namedChunks": false,
"aot": true,
"extractLicenses": true, "extractLicenses": true,
"vendorChunk": false, "vendorChunk": false,
"buildOptimizer": true "buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
} }
} }
}, },
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular-devkit/build-angular:dev-server",
"options": { "options": {
"browserTarget": "ng-one:build" "browserTarget": "ng-template-generator:build"
}, },
"configurations": { "configurations": {
"production": { "production": {
"browserTarget": "ng-one:build:production" "browserTarget": "ng-template-generator:build:production"
} }
} }
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "@angular-devkit/build-angular:extract-i18n",
"options": { "options": {
"browserTarget": "ng-one:build" "browserTarget": "ng-template-generator:build"
} }
}, },
"test": { "test": {
...@@ -100,7 +94,8 @@ ...@@ -100,7 +94,8 @@
"src/assets" "src/assets"
], ],
"styles": [ "styles": [
"src/styles.scss" "node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.css"
], ],
"scripts": [] "scripts": []
} }
...@@ -122,15 +117,19 @@ ...@@ -122,15 +117,19 @@
"builder": "@angular-devkit/build-angular:protractor", "builder": "@angular-devkit/build-angular:protractor",
"options": { "options": {
"protractorConfig": "e2e/protractor.conf.js", "protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "ng-one:serve" "devServerTarget": "ng-template-generator:serve"
}, },
"configurations": { "configurations": {
"production": { "production": {
"devServerTarget": "ng-one:serve:production" "devServerTarget": "ng-template-generator:serve:production"
} }
} }
} }
} }
}}, }
"defaultProject": "ng-one" },
"defaultProject": "ng-template-generator",
"cli": {
"analytics": "0bdaa560-1d2a-46f5-b14c-1f80decb439e"
}
} }
\ No newline at end of file
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* 运行 npm run publish T_01,T_02,T_03,T_04 命令来分别打包 T_01,T_02,T_03,T_04 这四个模板,注意逗号要用英文的 * 运行 npm run publish T_01,T_02,T_03,T_04 命令来分别打包 T_01,T_02,T_03,T_04 这四个模板,注意逗号要用英文的
* 运行 npm run publish all 命令来打包所有模板 * 运行 npm run publish all 命令来打包所有模板
*/ */
const spawn = require('child_process').spawn; const spawn = require('child_process').spawn;
const path = require("path"); const path = require("path");
const fs = require("fs"); const fs = require("fs");
...@@ -12,9 +12,9 @@ const os = require('os'); ...@@ -12,9 +12,9 @@ const os = require('os');
const compressing = require("compressing"); const compressing = require("compressing");
//Linux系统上'Linux' //Linux系统上'Linux'
//macOS 系统上'Darwin' //macOS 系统上'Darwin'
//Windows系统上'Windows_NT' //Windows系统上'Windows_NT'
let sysType = os.type(); let sysType = os.type();
Date.prototype.Format = function(fmt) { Date.prototype.Format = function(fmt) {
var o = { var o = {
...@@ -44,9 +44,9 @@ const runSpawn = async function (){ ...@@ -44,9 +44,9 @@ const runSpawn = async function (){
await new Promise(function(resolve,reject){ await new Promise(function(resolve,reject){
let pkg = require("../package.json"); let pkg = require("../package.json");
let ls; let ls;
if(sysType==="Windows_NT"){ if(sysType==="Windows_NT"){
//ng build --prod --build--optimizer --base-href /ng-one/ //ng build --prod --build--optimizer --base-href /ng-one/
ls = spawn("cmd.exe", ['/c', 'ng', 'build', '--prod', '--build--optimizer', '--base-href', '/template-base-href/'] ); ls = spawn("cmd.exe", ['/c', 'ng', 'build', '--prod', '--build--optimizer', '--base-href', '/template-base-href/'] );
...@@ -57,7 +57,7 @@ const runSpawn = async function (){ ...@@ -57,7 +57,7 @@ const runSpawn = async function (){
ls.stdout.on('data', (data) => { ls.stdout.on('data', (data) => {
console.log(` ${data}`); console.log(` ${data}`);
}); });
ls.stderr.on('data', (data) => { ls.stderr.on('data', (data) => {
console.log(`stderr: ${data}`); console.log(`stderr: ${data}`);
reject(); reject();
...@@ -66,13 +66,13 @@ const runSpawn = async function (){ ...@@ -66,13 +66,13 @@ const runSpawn = async function (){
ls.on('close', (code) => { ls.on('close', (code) => {
console.log(`child process exited with code ${code}`); console.log(`child process exited with code ${code}`);
//要压缩的目录 //要压缩的目录
let zippath = path.resolve(__dirname,"../dist"); let zippath = path.resolve(__dirname,"../dist", pkg.name);
//压缩包的存放目录 //压缩包的存放目录
let date = new Date(); let date = new Date();
let zipname = pkg.name+"_"+date.Format("yyyyMMdd hh-mm-ss"); let zipname = pkg.name+"_"+date.Format("yyyyMMdd hh-mm-ss");
let zipdir = path.resolve(__dirname,"../publish/"+zipname+".zip"); let zipdir = path.resolve(__dirname,"../publish/"+zipname+".zip");
clean(zipdir); //删除原有的包 clean(zipdir); //删除原有的包
const tarStream = new compressing.zip.Stream(); const tarStream = new compressing.zip.Stream();
fs.readdir(zippath,function(err,files){ fs.readdir(zippath,function(err,files){
if(err){ if(err){
...@@ -84,16 +84,16 @@ const runSpawn = async function (){ ...@@ -84,16 +84,16 @@ const runSpawn = async function (){
tarStream.addEntry(zippath+"/"+files[i]); tarStream.addEntry(zippath+"/"+files[i]);
} }
let writeStream = fs.createWriteStream(zipdir); let writeStream = fs.createWriteStream(zipdir);
tarStream.pipe(writeStream); tarStream.pipe(writeStream);
writeStream.on('close', () => { writeStream.on('close', () => {
console.log(`模板 ${pkg.name} 打包已完成!`); console.log(`模板 ${pkg.name} 打包已完成!`);
resolve(); resolve();
}) })
}); });
}); });
}); });
} }
// let projects = ""; // let projects = "";
...@@ -101,7 +101,7 @@ const runSpawn = async function (){ ...@@ -101,7 +101,7 @@ const runSpawn = async function (){
// console.log("缺少参数"); // console.log("缺少参数");
// return; // return;
// } // }
// projects = process.argv[2]; // projects = process.argv[2];
let exec = async function(){ let exec = async function(){
//压缩模板 //压缩模板
...@@ -110,6 +110,5 @@ let exec = async function(){ ...@@ -110,6 +110,5 @@ let exec = async function(){
exec(); exec();
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2,76 +2,57 @@ ...@@ -2,76 +2,57 @@
"name": "ng-template-generator", "name": "ng-template-generator",
"version": "0.0.1", "version": "0.0.1",
"scripts": { "scripts": {
"start": "ng serve --host=0.0.0.0", "start": "ng serve",
"build": "ng build --build--optimizer --aot --base-href /JGT/v3/", "build": "ng build --build--optimizer --aot --base-href /JGT/v3/",
"publish": "node ./bin/publish.js" "publish": "node ./bin/publish.js",
"ng": "ng",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^7.2.10", "@angular/animations": "~9.0.2",
"@angular/cdk": "^7.2.2", "@angular/common": "~9.0.2",
"@angular/common": "^7.2.10", "@angular/compiler": "~9.0.2",
"@angular/compiler": "^7.2.10", "@angular/core": "~9.0.2",
"@angular/core": "^7.2.10", "@angular/forms": "~9.0.2",
"@angular/flex-layout": "^7.0.0-beta.24", "@angular/platform-browser": "~9.0.2",
"@angular/forms": "^7.2.10", "@angular/platform-browser-dynamic": "~9.0.2",
"@angular/http": "^7.2.10", "@angular/router": "~9.0.2",
"@angular/material": "^7.2.2", "@fortawesome/angular-fontawesome": "^0.6.0",
"@angular/platform-browser": "^7.2.10", "@fortawesome/fontawesome-svg-core": "^1.2.27",
"@angular/platform-browser-dynamic": "^7.2.10", "@fortawesome/free-regular-svg-icons": "^5.12.1",
"@angular/platform-server": "^7.2.10", "@fortawesome/free-solid-svg-icons": "^5.12.1",
"@angular/router": "^7.2.10", "@tweenjs/tween.js": "~18.5.0",
"@tweenjs/tween.js": "^17.3.0", "ali-oss": "^6.5.1",
"ali-oss": "^6.0.0", "compressing": "^1.5.0",
"angular-bootstrap-colorpicker": "^3.0.32", "ng-zorro-antd": "^8.5.2",
"angular-cropperjs": "^1.0.1", "rxjs": "~6.5.4",
"angular2-draggable": "^2.1.9",
"angular2-fontawesome": "^5.2.1",
"angularx-qrcode": "^1.5.3",
"animate.css": "^3.7.0",
"bootstrap": "^4.1.1",
"browser-image-compression": "^1.0.5",
"compressing": "^1.4.0",
"core-js": "^2.6.1",
"cropperjs": "1.4.1",
"css-element-queries": "^1.0.2",
"decimal.js": "^10.0.1",
"font-awesome": "^4.7.0",
"hammerjs": "^2.0.8",
"install": "^0.12.2",
"karma-cli": "^2.0.0",
"lodash": "^4.17.10",
"nedb": "^1.8.0",
"ng-lottie": "^0.3.1",
"ng-zorro-antd": "^7.2.0",
"ngx-color-picker": "^9.0.0",
"npm": "^6.5.0",
"rxjs": "^6.3.3",
"rxjs-compat": "^6.3.3",
"rxjs-tslint": "^0.1.6",
"spark-md5": "^3.0.0", "spark-md5": "^3.0.0",
"webpack": "^4.28.2", "tslib": "^1.10.0",
"zone.js": "^0.8.26" "zone.js": "~0.10.2",
"node-sass": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^0.11.4", "@angular-devkit/build-angular": "~0.900.3",
"@angular/cli": "^7.2.10", "@angular/cli": "~9.0.3",
"@angular/compiler-cli": "^7.2.10", "@angular/compiler-cli": "~9.0.2",
"@angular/language-service": "^7.2.10", "@angular/language-service": "~9.0.2",
"@types/jasmine": "^3.3.5", "@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3", "@types/jasminewd2": "~2.0.3",
"@types/node": "^10.12.18", "@types/node": "^12.11.1",
"codelyzer": "^4.5.0", "codelyzer": "^5.1.2",
"jasmine-core": "^3.3.0", "jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "^4.2.1", "jasmine-spec-reporter": "~4.2.1",
"karma": "^3.1.4", "karma": "~4.3.0",
"karma-chrome-launcher": "^2.2.0", "karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~2.0.0", "karma-coverage-istanbul-reporter": "~2.1.0",
"karma-jasmine": "^2.0.1", "karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0", "karma-jasmine-html-reporter": "^1.4.2",
"protractor": "^5.4.2", "protractor": "~5.4.3",
"ts-node": "~5.0.1", "ts-node": "~8.3.0",
"tslint": "^5.12.0", "tslint": "~5.18.0",
"typescript": "3.1.1" "typescript": "~3.7.5"
} }
} }
...@@ -6,7 +6,6 @@ import { FormsModule } from '@angular/forms'; ...@@ -6,7 +6,6 @@ import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd'; import { NgZorroAntdModule, NZ_I18N, zh_CN } from 'ng-zorro-antd';
import { NzButtonModule } from 'ng-zorro-antd/button'; import { NzButtonModule } from 'ng-zorro-antd/button';
import {Angular2FontawesomeModule} from 'angular2-fontawesome/angular2-fontawesome';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { FormComponent } from './form/form.component'; import { FormComponent } from './form/form.component';
...@@ -28,6 +27,10 @@ import {TimePipe} from "./pipes/time.pipe"; ...@@ -28,6 +27,10 @@ import {TimePipe} from "./pipes/time.pipe";
import {CustomHotZoneComponent} from "./common/custom-hot-zone/custom-hot-zone.component"; import {CustomHotZoneComponent} from "./common/custom-hot-zone/custom-hot-zone.component";
registerLocaleData(zh); registerLocaleData(zh);
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { fas } from '@fortawesome/free-solid-svg-icons';
import { far } from '@fortawesome/free-regular-svg-icons';
@NgModule({ @NgModule({
declarations: [ declarations: [
AppComponent, AppComponent,
...@@ -48,8 +51,8 @@ registerLocaleData(zh); ...@@ -48,8 +51,8 @@ registerLocaleData(zh);
HttpClientModule, HttpClientModule,
BrowserAnimationsModule, BrowserAnimationsModule,
BrowserModule, BrowserModule,
Angular2FontawesomeModule,
NgZorroAntdModule, NgZorroAntdModule,
FontAwesomeModule,
//ColorPickerModule //ColorPickerModule
], ],
...@@ -59,4 +62,8 @@ registerLocaleData(zh); ...@@ -59,4 +62,8 @@ registerLocaleData(zh);
], ],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { } export class AppModule {
constructor(library: FaIconLibrary) {
library.addIconPacks(fas, far);
}
}
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
(click)="onBtnClearAudio()" (click)="onBtnClearAudio()"
*ngIf="withRmBtn && (audioUrl || audioBlob)" *ngIf="withRmBtn && (audioUrl || audioBlob)"
> >
<fa name="close"></fa> <fa-icon name="close"></fa-icon>
</div> </div>
<div <div
class="btn-record" class="btn-record"
......
...@@ -41,8 +41,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { ...@@ -41,8 +41,8 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
@Output() @Output()
save = new EventEmitter(); save = new EventEmitter();
@ViewChild('canvas') canvas: ElementRef; @ViewChild('canvas', {static: true }) canvas: ElementRef;
@ViewChild('wrap') wrap: ElementRef; @ViewChild('wrap', {static: true }) wrap: ElementRef;
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event) { onResize(event) {
this.g_winResizeEventStream.next(); this.g_winResizeEventStream.next();
......
...@@ -52,7 +52,7 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy, ...@@ -52,7 +52,7 @@ export class LessonTitleConfigComponent implements OnInit, OnChanges, OnDestroy,
}; };
prevIcons = []; prevIcons = [];
prevType = ''; prevType = '';
@ViewChild('titleEl') titleEl: ElementRef; @ViewChild('titleEl', {static: true }) titleEl: ElementRef;
titleEW = null; titleEW = null;
@Input() @Input()
......
...@@ -18,7 +18,7 @@ import { ...@@ -18,7 +18,7 @@ import {
export class PlayerContentWrapperComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit { export class PlayerContentWrapperComponent implements OnInit, OnChanges, OnDestroy, AfterViewInit {
@ViewChild('wrapperEl') wrapperEl: ElementRef; @ViewChild('wrapperEl', {static: true }) wrapperEl: ElementRef;
// // aspect ratio? // // aspect ratio?
@Input() ratio; @Input() ratio;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<div class="p-upload-progress-bg" *ngIf="uploading"> <div class="p-upload-progress-bg" *ngIf="uploading">
<div class="i-bg" [style.width]="progress+'%'"></div> <div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text"> <div class="i-text">
<fa name="cloud-upload"></fa> <fa-icon name="cloud-upload"></fa-icon>
Uploading... Uploading...
</div> </div>
</div> </div>
......
...@@ -70,14 +70,14 @@ ...@@ -70,14 +70,14 @@
[ngClass]="{'smart-bar': showUploadBtn}" > [ngClass]="{'smart-bar': showUploadBtn}" >
<div class="i-bg" [style.width]="progress+'%'"></div> <div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text"> <div class="i-text">
<fa name="cloud-upload"></fa> <fa-icon name="cloud-upload"></fa-icon>
Uploading... Uploading...
</div> </div>
</div> </div>
<div class="p-upload-check-bg" *ngIf="checking"> <div class="p-upload-check-bg" *ngIf="checking">
<div class="i-bg" [style.width]="progress+'%'"></div> <div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text"> <div class="i-text">
<fa name="cloud-upload"></fa> <fa-icon name="cloud-upload"></fa-icon>
<i nz-icon type="loading" theme="outline"></i>Checking... <i nz-icon type="loading" theme="outline"></i>Checking...
</div> </div>
</div> </div>
......
...@@ -24,7 +24,7 @@ export class UploadVideoComponent implements OnChanges, OnDestroy { ...@@ -24,7 +24,7 @@ export class UploadVideoComponent implements OnChanges, OnDestroy {
@Input() @Input()
videoUrl = ''; videoUrl = '';
@ViewChild('videoNode') @ViewChild('videoNode', {static: true })
videoNode: ElementRef; videoNode: ElementRef;
......
...@@ -1056,8 +1056,8 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -1056,8 +1056,8 @@ export class PlayComponent implements OnInit, OnDestroy {
// //
// -------------------------------------------------- // --------------------------------------------------
@ViewChild("canvas") canvas: ElementRef; @ViewChild("canvas", {static: true }) canvas: ElementRef;
@ViewChild("wrap") wrap: ElementRef; @ViewChild("wrap", {static: true }) wrap: ElementRef;
@HostListener("window:resize", ["$event"]) @HostListener("window:resize", ["$event"])
onResize(event) { onResize(event) {
this.g_winResizeEventStream.next(); this.g_winResizeEventStream.next();
...@@ -1069,12 +1069,12 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -1069,12 +1069,12 @@ export class PlayComponent implements OnInit, OnDestroy {
ngOnInit() { ngOnInit() {
const getData = (<any>window).courseware.getData; const getData = (<any>window).courseware.getData;
getData(data => { getData(data => {
if (window['air'].airClassInfo.user.classRole == 'tea') { // if (window['air'].airClassInfo.user.classRole == 'tea') {
if(!this.g_ForceChangeDefaultRole){ // if(!this.g_ForceChangeDefaultRole){
this.g_teacherFlag = true; // this.g_teacherFlag = true;
} // }
} // }
this.g_currentUser = window['air'].airClassInfo.user; // this.g_currentUser = window['air'].airClassInfo.user;
if (data && typeof data == "object") { if (data && typeof data == "object") {
this.g_data = data; this.g_data = data;
this.g_formData = data.contentObj; this.g_formData = data.contentObj;
......
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="zh">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>NgOne</title> <title>NgOne</title>
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
</style> </style>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" /> <link rel="icon" type="image/x-icon" href="favicon.ico" />
<!-- <script type="text/javascript" src="http://teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air.js" ></script> --> <script type="text/javascript" src="http://teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air.js" ></script>
<script type="text/javascript" src="https://staging-teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air_online.js"></script> <!-- <script type="text/javascript" src="https://staging-teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air_online.js"></script> -->
</head> </head>
<body> <body>
<app-root></app-root> <app-root></app-root>
......
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>NgOne</title>
<base href="/">
<!-- <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">-->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<script type="text/javascript" src="https://staging-teach.cdn.ireadabc.com/h5template/h5-static-lib/js/air.js"></script>
</head>
<body>
Hello World!!
</body>
</html>
/* You can add global styles to this file, and also import other style files */ /* You can add global styles to this file, and also import other style files */
@import "~ng-zorro-antd/src/ng-zorro-antd.css"; @import "~ng-zorro-antd/ng-zorro-antd.min.css";
\ No newline at end of file \ No newline at end of file
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "./out-tsc/app", "outDir": "./out-tsc/app",
"types": [] "types": [
"node"
]
}, },
"files": [ "files": [
"src/main.ts", "src/main.ts",
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
] ]
}, },
"angularCompilerOptions": { "angularCompilerOptions": {
"enableIvy": false,
"fullTemplateTypeCheck": true, "fullTemplateTypeCheck": true,
"strictInjectionParameters": true "strictInjectionParameters": true
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment