@panelwave/player 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ story variables, multilingual text and paywalls, all in one component.
7
7
 
8
8
  [![npm](https://img.shields.io/npm/v/@panelwave/player.svg)](https://www.npmjs.com/package/@panelwave/player)
9
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/panelwave/player/blob/master/LICENSE)
10
- [![Angular](https://img.shields.io/badge/Angular-20-red)](https://angular.dev)
10
+ [![Angular](https://img.shields.io/badge/Angular-20%20%7C%2021%20%7C%2022-red)](https://angular.dev)
11
11
 
12
12
  **[Live demo](https://panelwave.github.io/player/)** ·
13
13
  **[Documentation](https://docs.panelwave.org/player/overview)** ·
@@ -64,8 +64,16 @@ authoring metadata the player doesn't need).
64
64
  npm install @panelwave/player @ngx-translate/core
65
65
  ```
66
66
 
67
- Peer dependencies: `@angular/core` and `@angular/common` **^20**,
68
- `@ngx-translate/core` **^17**, `rxjs` **^7.8**.
67
+ Peer dependencies: `@angular/core` and `@angular/common` **^20, ^21 or ^22**,
68
+ `@ngx-translate/core` **^17 or ^18**, `rxjs` **^7.8**.
69
+
70
+ **Angular compatibility.** The package is compiled with Angular 20 in partial
71
+ (linker) mode, so newer Angular versions link it at build time. Every CI run
72
+ installs the packed library into a fresh `ng new` app on Angular 20, 21 and
73
+ 22 with ngx-translate 18, and on Angular 20 and 22 with ngx-translate 17
74
+ (strict peer resolution, production build, headless render of a sample
75
+ manifest); the player works with zone.js and zoneless change detection (the
76
+ default for new Angular 21+ apps).
69
77
 
70
78
  ## Setup
71
79
 
@@ -74,13 +82,13 @@ for its UI strings:
74
82
 
75
83
  ```typescript
76
84
  // app.config.ts
77
- import { ApplicationConfig, importProvidersFrom } from '@angular/core';
85
+ import { ApplicationConfig, inject } from '@angular/core';
78
86
  import { HttpClient, provideHttpClient } from '@angular/common/http';
79
- import { TranslateLoader, TranslateModule, TranslationObject } from '@ngx-translate/core';
87
+ import { TranslateLoader, TranslationObject, provideTranslateService } from '@ngx-translate/core';
80
88
  import { Observable } from 'rxjs';
81
89
 
82
90
  class PlayerTranslateLoader implements TranslateLoader {
83
- constructor(private http: HttpClient) {}
91
+ private readonly http = inject(HttpClient);
84
92
  getTranslation(lang: string): Observable<TranslationObject> {
85
93
  return this.http.get<TranslationObject>(`./assets/i18n/${lang}.json`);
86
94
  }
@@ -89,15 +97,21 @@ class PlayerTranslateLoader implements TranslateLoader {
89
97
  export const appConfig: ApplicationConfig = {
90
98
  providers: [
91
99
  provideHttpClient(),
92
- importProvidersFrom(
93
- TranslateModule.forRoot({
94
- loader: { provide: TranslateLoader, useClass: PlayerTranslateLoader, deps: [HttpClient] },
95
- }),
96
- ),
100
+ provideTranslateService({
101
+ loader: { provide: TranslateLoader, useClass: PlayerTranslateLoader },
102
+ }),
97
103
  ],
98
104
  };
99
105
  ```
100
106
 
107
+ This works with ngx-translate 17 and 18. (`TranslateModule.forRoot()` still
108
+ works on 17 but no longer exists in 18.) Pass the loader as an explicit
109
+ provider as shown: on 18, `provideTranslateLoader(PlayerTranslateLoader)`
110
+ fails in production builds for a plain (non-`@Injectable`) class, because
111
+ 18 tells classes from factory functions by their source text, and the
112
+ minified class no longer looks like one ("Class constructor … cannot be
113
+ invoked without 'new'").
114
+
101
115
  **2. Assets and fonts.** Copy the player's UI translations into your app,
102
116
  and include the balloon lettering fonts:
103
117
 
@@ -117,11 +131,15 @@ Caveat, Anton and 10 more). The commercial Blambot font **Ames Pro** is not
117
131
  included. If your works use it, license it from [blambot.com](https://blambot.com)
118
132
  and add your own `@font-face`. Otherwise balloons fall back to Comic Neue.
119
133
 
134
+ The player depends on `json-logic-js`, a CommonJS module. To silence the
135
+ build warning about it, add `"allowedCommonJsDependencies": ["json-logic-js"]`
136
+ to the same build options.
137
+
120
138
  ## Usage
121
139
 
122
140
  ```typescript
123
141
  import { Component } from '@angular/core';
124
- import { PlayerShellComponent } from '@panelwave/player';
142
+ import { PlayerShellComponent, type PlayerPanelChangeEvent } from '@panelwave/player';
125
143
 
126
144
  @Component({
127
145
  selector: 'app-reader',
@@ -131,13 +149,15 @@ import { PlayerShellComponent } from '@panelwave/player';
131
149
  manifestUrl="/stories/my-story/panelwave.json"
132
150
  locale="en-US"
133
151
  [showToolbar]="true"
134
- (panelChange)="onPanel($event.panel.id)"
152
+ (panelChange)="onPanel($event)"
135
153
  (error)="onError($event)" />
136
154
  `,
137
155
  styles: `:host { display: block; height: 100dvh; }`,
138
156
  })
139
157
  export class ReaderComponent {
140
- onPanel(id: string) { console.log('now showing', id); }
158
+ onPanel(e: PlayerPanelChangeEvent) {
159
+ console.log(`panel ${e.panelId} in chapter ${e.chapter.id} (came from ${e.previousPanelId ?? 'start'})`);
160
+ }
141
161
  onError(err: Error) { console.error(err); }
142
162
  }
143
163
  ```
@@ -173,7 +193,7 @@ a new `entitlementSnapshot` re-evaluates the gates, and `locale`,
173
193
  | Output | Payload | Fires when |
174
194
  |---|---|---|
175
195
  | `ready` | `void` | The manifest is loaded and the player is ready |
176
- | `panelChange` | `{ panel, chapter }` | The reader moves to a new panel |
196
+ | `panelChange` | `PlayerPanelChangeEvent`: `{ panel, chapter, panelId, previousPanelId? }` | The reader moves to a new panel. `panelId` is the panel's key in `chapter.panels` (read the id from here: `panel.id` is optional in the format and usually absent); `previousPanelId` is the panel before it, unset for the first panel after a (re)load |
177
197
  | `chapterChange` | `Chapter` | A chapter boundary is crossed |
178
198
  | `variableChange` | `{ key, value }` | A story variable changes |
179
199
  | `localeChange` | `LocaleCode` | The language is switched |