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==