diff --git a/examples/angular/tsconfig.json b/examples/angular/tsconfig.json index 2338536e..57d6c25a 100644 --- a/examples/angular/tsconfig.json +++ b/examples/angular/tsconfig.json @@ -6,12 +6,7 @@ */ { "files": [], - "references": [ - { + "references": [{ "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.spec.json" - } -] + }] } diff --git a/package.json b/package.json index 2ba49213..3fbafed1 100644 --- a/package.json +++ b/package.json @@ -26,12 +26,14 @@ "@commitlint/config-conventional": "^11.0.0", "@typescript-eslint/eslint-plugin": "^4.6.0", "@typescript-eslint/parser": "^4.6.0", + "chokidar": "^3.4.3", "eslint": "^7.8.1", "eslint-config-airbnb-typescript": "^12.0.0", "eslint-plugin-import": "^2.22.0", "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-react": "^7.20.6", "eslint-plugin-react-hooks": "^4.1.0", + "fs-extra": "^9.0.1", "husky": "^4.2.5", "lerna": "^3.22.1", "react": "^17.0.0", diff --git a/packages/angular/angular.json b/packages/angular/angular.json index 5fa1a2f7..6eac5238 100644 --- a/packages/angular/angular.json +++ b/packages/angular/angular.json @@ -22,6 +22,73 @@ } } } + }, + "@vime/angular-test": { + "projectType": "application", + "root": "test", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/vime/test", + "index": "test/src/index.html", + "main": "test/src/main.ts", + "polyfills": "test/src/polyfills.ts", + "tsConfig": "test/tsconfig.json", + "aot": true, + "assets": [ + "src/favicon.ico" + ], + "styles": [ + "test/src/styles.css" + ], + "scripts": [] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "test/src/environments/environment.ts", + "with": "test/src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb", + "maximumError": "10kb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "@vime/angular-test:build" + }, + "configurations": { + "production": { + "browserTarget": "@vime/angular-test:build:production" + } + } + } + } } }, "defaultProject": "@vime/angular" diff --git a/packages/angular/package.json b/packages/angular/package.json index aa43d275..2e225667 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,12 +1,17 @@ { "name": "@vime/angular", "version": "5.0.10", + "license": "MIT", "scripts": { "ng": "ng", - "start": "ng serve", + "serve": "ng serve", "build": "ng build --prod", + "build:watch": "ng build @vime/angular --watch", "prepare": "node scripts/bump-version.js && node scripts/unpack-dist.js" }, + "dependencies": { + "@vime/core": "^5.0.8" + }, "devDependencies": { "@angular-devkit/build-angular": "~0.1100.4", "@angular/cli": "~11.0.4", @@ -14,7 +19,8 @@ "@angular/compiler": "~11.0.4", "@angular/compiler-cli": "~11.0.4", "@angular/core": "~11.0.4", - "fs-extra": "^9.0.1", + "@angular/platform-browser": "~10.2.1", + "@angular/platform-browser-dynamic": "~10.2.1", "ng-packagr": "^11.0.0", "rxjs": "~6.6.0", "tslib": "^2.0.0", diff --git a/packages/angular/projects/vime/angular/src/VimeComponent.ts b/packages/angular/projects/vime/angular/src/VimeComponent.ts index fa7de711..af00c934 100644 --- a/packages/angular/projects/vime/angular/src/VimeComponent.ts +++ b/packages/angular/projects/vime/angular/src/VimeComponent.ts @@ -5,8 +5,9 @@ import { usePlayerContext, createDispatcher, } from '@vime/core'; -import { ElementRef } from '@angular/core'; +import { ElementRef, Injectable } from '@angular/core'; +@Injectable() export abstract class VimeComponent { private playerDispatch: Dispatcher = () => {}; diff --git a/packages/angular/projects/vime/angular/src/lib.ts b/packages/angular/projects/vime/angular/src/lib.ts index 8270e1ed..9e9084b8 100644 --- a/packages/angular/projects/vime/angular/src/lib.ts +++ b/packages/angular/projects/vime/angular/src/lib.ts @@ -7,22 +7,22 @@ export const define = (tagName: string, clazz: any) => { if (isClient && !customElements.get(tagName)) customElements.define(tagName, clazz); }; -export const proxyInputs = (Cmp: any, inputs: string[]) => { - const Prototype = Cmp.prototype; - inputs.forEach((item) => { - Object.defineProperty(Prototype, item, { +export const proxyInputs = (Component: any, inputs: string[]) => { + const Prototype = Component.prototype; + inputs.forEach((input) => { + Object.defineProperty(Prototype, input, { get() { - return this.el[item]; + return this.el[input]; }, set(val: any) { - this.z.runOutsideAngular(() => (this.el[item] = val)); + this.z.runOutsideAngular(() => (this.el[input] = val)); }, }); }); }; -export const proxyMethods = (Cmp: any, methods: string[]) => { - const Prototype = Cmp.prototype; +export const proxyMethods = (Component: any, methods: string[]) => { + const Prototype = Component.prototype; methods.forEach((methodName) => { Prototype[methodName] = function () { const args = arguments; @@ -36,11 +36,9 @@ export const initOutputs = (instance: any, events: string[]) => { } export function ProxyCmp(opts: { inputs?: any; methods?: any }) { - const decorator = function (cls: any) { - if (opts.inputs) proxyInputs(cls, opts.inputs); - if (opts.methods) proxyMethods(cls, opts.methods); - return cls; + return function (Component: any) { + if (opts.inputs) proxyInputs(Component, opts.inputs); + if (opts.methods) proxyMethods(Component, opts.methods); + return Component; }; - - return decorator; } diff --git a/packages/angular/scripts/bump-version.js b/packages/angular/scripts/bump-version.js index 94ed5d16..3ce353f8 100644 --- a/packages/angular/scripts/bump-version.js +++ b/packages/angular/scripts/bump-version.js @@ -8,4 +8,5 @@ const rootPkg = JSON.parse(fs.readFileSync(rootPkgPath)); const distPkg = JSON.parse(fs.readFileSync(distPkgPath)); distPkg.version = rootPkg.version; +distPkg.dependencies['@vime/core'] = rootPkg.dependencies['@vime/core']; fs.writeFileSync(distPkgPath, JSON.stringify(distPkg, undefined, 2)); diff --git a/packages/angular/test/.browserslistrc b/packages/angular/test/.browserslistrc new file mode 100644 index 00000000..77d35a26 --- /dev/null +++ b/packages/angular/test/.browserslistrc @@ -0,0 +1,8 @@ +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR +not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line. +not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. diff --git a/packages/angular/test/src/app/app.component.html b/packages/angular/test/src/app/app.component.html new file mode 100644 index 00000000..abb3fcad --- /dev/null +++ b/packages/angular/test/src/app/app.component.html @@ -0,0 +1,61 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/packages/angular/test/src/app/app.component.ts b/packages/angular/test/src/app/app.component.ts new file mode 100644 index 00000000..11599d7f --- /dev/null +++ b/packages/angular/test/src/app/app.component.ts @@ -0,0 +1,15 @@ +import { Component, ViewChild } from '@angular/core'; +import { Player } from '@vime/angular'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', +}) +export class AppComponent { + // Obtain a ref if you need to call any methods. + @ViewChild('player') player!: Player; + + onPlaybackReady() { + // ... + } +} diff --git a/packages/angular/test/src/app/app.module.ts b/packages/angular/test/src/app/app.module.ts new file mode 100644 index 00000000..ee7e63c6 --- /dev/null +++ b/packages/angular/test/src/app/app.module.ts @@ -0,0 +1,20 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { VimeModule } from '@vime/angular'; + +import { AppComponent } from './app.component'; +import { TapSidesToSeekComponent } from './tap-sides-to-seek/tap-sides-to-seek.component'; + +@NgModule({ + declarations: [ + AppComponent, + TapSidesToSeekComponent, + ], + imports: [ + BrowserModule, + VimeModule, + ], + providers: [], + bootstrap: [AppComponent], +}) +export class AppModule { } diff --git a/packages/angular/test/src/app/tap-sides-to-seek/tap-sides-to-seek.component.html b/packages/angular/test/src/app/tap-sides-to-seek/tap-sides-to-seek.component.html new file mode 100644 index 00000000..bb36832e --- /dev/null +++ b/packages/angular/test/src/app/tap-sides-to-seek/tap-sides-to-seek.component.html @@ -0,0 +1,32 @@ +
+
+
+ + \ No newline at end of file diff --git a/packages/angular/test/src/app/tap-sides-to-seek/tap-sides-to-seek.component.ts b/packages/angular/test/src/app/tap-sides-to-seek/tap-sides-to-seek.component.ts new file mode 100644 index 00000000..53a9cd6d --- /dev/null +++ b/packages/angular/test/src/app/tap-sides-to-seek/tap-sides-to-seek.component.ts @@ -0,0 +1,48 @@ +import { Component, ElementRef } from '@angular/core'; +import { VimeComponent } from '@vime/angular'; + +@Component({ + selector: 'tap-sides-to-seek', + templateUrl: './tap-sides-to-seek.component.html', +}) +export class TapSidesToSeekComponent extends VimeComponent { + currentTime = 0; + + duration = -1; + + /** + * When we extend the `Component` class a few things are happening under the hood. + * + * 1. The super constructor overwrites all player properties with fresh getters/setters. Not all + * properties contain setters (readonly), so it's best to refer to the documentation. + * 2. The component binds itself to the player context so that player properties are updated as + * they change. + * 3. The component will dispatch any updates to the player if a writable player prop is changed. + * 4. When the component is destroyed, it will automatically unbind itself from the player. + * + * IMPORTANT: The `ElementRef` is required as the `Component` class uses it to dispatch + * custom events to the player. Angular automatically injects this value. + * + * @see https://vimejs.com/components/core/player/api + */ + constructor(protected ref: ElementRef) { + // Pass in the properties you'd like to bind to this component. + super([ + 'currentTime', + 'duration', + ]); + + // There is a player ref if you need to call any methods. + // this.player + } + + onSeekBackward() { + if (this.currentTime < 5) return; + this.currentTime -= 5; + } + + onSeekForward() { + if (this.currentTime > (this.duration - 5)) return; + this.currentTime += 5; + } +} diff --git a/packages/angular/test/src/environments/environment.prod.ts b/packages/angular/test/src/environments/environment.prod.ts new file mode 100644 index 00000000..c9669790 --- /dev/null +++ b/packages/angular/test/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true, +}; diff --git a/packages/angular/test/src/environments/environment.ts b/packages/angular/test/src/environments/environment.ts new file mode 100644 index 00000000..99c3763c --- /dev/null +++ b/packages/angular/test/src/environments/environment.ts @@ -0,0 +1,16 @@ +// This file can be replaced during build by using the `fileReplacements` array. +// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. +// The list of file replacements can be found in `angular.json`. + +export const environment = { + production: false, +}; + +/* + * For easier debugging in development mode, you can import the following file + * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. + * + * This import should be commented out in production mode because it will have a negative impact + * on performance if an error is thrown. + */ +// import 'zone.js/dist/zone-error'; // Included with Angular CLI. diff --git a/packages/angular/test/src/favicon.ico b/packages/angular/test/src/favicon.ico new file mode 100644 index 00000000..997406ad Binary files /dev/null and b/packages/angular/test/src/favicon.ico differ diff --git a/packages/angular/test/src/index.html b/packages/angular/test/src/index.html new file mode 100644 index 00000000..ec033450 --- /dev/null +++ b/packages/angular/test/src/index.html @@ -0,0 +1,13 @@ + + + + + @vime/angular-test + + + + + + + + diff --git a/packages/angular/test/src/main.ts b/packages/angular/test/src/main.ts new file mode 100644 index 00000000..db96f116 --- /dev/null +++ b/packages/angular/test/src/main.ts @@ -0,0 +1,12 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/packages/angular/test/src/polyfills.ts b/packages/angular/test/src/polyfills.ts new file mode 100644 index 00000000..741c8867 --- /dev/null +++ b/packages/angular/test/src/polyfills.ts @@ -0,0 +1 @@ +import 'zone.js/dist/zone'; diff --git a/packages/angular/test/src/styles.css b/packages/angular/test/src/styles.css new file mode 100644 index 00000000..da13fc13 --- /dev/null +++ b/packages/angular/test/src/styles.css @@ -0,0 +1,12 @@ +/* Default theme. */ +@import "~@vime/core/themes/default.css"; + +/* Optional light theme (extends default). */ +/* @import "~@vime/core/themes/light.css"; */ + +html, +body { + width: 100%; + height: 100%; + margin: 0; +} \ No newline at end of file diff --git a/packages/angular/test/tsconfig.json b/packages/angular/test/tsconfig.json new file mode 100644 index 00000000..39ac917b --- /dev/null +++ b/packages/angular/test/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts", + "src/polyfills.ts", + ], + "include": [ + "src/**/*.d.ts" + ] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d76846c0..fc7a1d14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -193,6 +193,20 @@ dependencies: tslib "^2.0.0" +"@angular/platform-browser-dynamic@~10.2.1": + version "10.2.4" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-10.2.4.tgz#c2fc87f9edf862a9f310f34a7a1f9082b259f73a" + integrity sha512-+oON9ujv9EOC3yJVgnV/vy3262dpMKBFlQ+dHcr5rfk2WpsnyJ26R+Nhkaug9FEdmSo9w+GqowF5bodrtTOTlA== + dependencies: + tslib "^2.0.0" + +"@angular/platform-browser@~10.2.1": + version "10.2.4" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-10.2.4.tgz#08fa0cfff88951120d00327993e00a4454ce0230" + integrity sha512-gYewLxoTnxOxX3XXK959YiDaw8CEnksKIbK6RYuofIcB8dTL9AlS9/l22xdGifTXTkFjs8noO6i/WT5hCt49Ww== + dependencies: + tslib "^2.0.0" + "@babel/code-frame@^7.0.0": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -3637,7 +3651,7 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -"chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.2.1, chokidar@^3.4.1: +"chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.2.1, chokidar@^3.4.1, chokidar@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==