@panelwave/player 1.1.0 → 1.3.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 +43 -17
- package/fesm2022/panelwave-player.mjs +5464 -2636
- package/fesm2022/panelwave-player.mjs.map +1 -1
- package/index.d.ts +816 -71
- package/package.json +6 -5
- package/src/assets/fonts/balloon/balloon-fonts.css +7 -4
- package/src/assets/i18n/de.json +23 -1
- package/src/assets/i18n/en.json +23 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ story variables, multilingual text and paywalls, all in one component.
|
|
|
7
7
|
|
|
8
8
|
[](https://www.npmjs.com/package/@panelwave/player)
|
|
9
9
|
[](https://github.com/panelwave/player/blob/master/LICENSE)
|
|
10
|
-
[](https://angular.dev)
|
|
10
|
+
[](https://angular.dev)
|
|
11
11
|
|
|
12
12
|
**[Live demo](https://panelwave.github.io/player/)** ·
|
|
13
13
|
**[Documentation](https://docs.panelwave.org/player/overview)** ·
|
|
@@ -53,7 +53,7 @@ it into a complete reading experience:
|
|
|
53
53
|
|
|
54
54
|
Stories are authored in the PanelWave CMS or written by hand against the
|
|
55
55
|
[open JSON Schema](https://github.com/panelwave/schema). The player supports
|
|
56
|
-
manifests up to format 1.
|
|
56
|
+
manifests up to format 1.7 (video panels, edge-transition inheritance,
|
|
57
57
|
typography style presets, the infinite canvas, paywall rules unlocked by any
|
|
58
58
|
of several products, each Buy option named and priced from `paywall.products`; 1.5's asset folders and localization blocks are
|
|
59
59
|
authoring metadata the player doesn't need).
|
|
@@ -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,
|
|
85
|
+
import { ApplicationConfig, inject } from '@angular/core';
|
|
78
86
|
import { HttpClient, provideHttpClient } from '@angular/common/http';
|
|
79
|
-
import { TranslateLoader,
|
|
87
|
+
import { TranslateLoader, TranslationObject, provideTranslateService } from '@ngx-translate/core';
|
|
80
88
|
import { Observable } from 'rxjs';
|
|
81
89
|
|
|
82
90
|
class PlayerTranslateLoader implements TranslateLoader {
|
|
83
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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
|
|
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(
|
|
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 |
|
|
@@ -205,7 +225,9 @@ navigation stops at the gate. Works without paywall rules aren't affected.
|
|
|
205
225
|
`extras` rules lock an extras block, never panels.
|
|
206
226
|
- **Age:** `ageGate` / `minimumAge` is checked on top of the rule's
|
|
207
227
|
entitlement. The reader answers the age gate first, then gets the paywall
|
|
208
|
-
if the purchase or subscription is still missing.
|
|
228
|
+
if the purchase or subscription is still missing. Age requirements combine
|
|
229
|
+
across every rule that applies to a panel, so a chapter preview or a free
|
|
230
|
+
panel rule never skips a work-wide age gate.
|
|
209
231
|
- **Buy / Subscribe:** the overlay offers a Buy option per product of a
|
|
210
232
|
purchase rule and a Subscribe option per tier of a subscription rule (name,
|
|
211
233
|
description and price from the rule), next to Sign in and Maybe later.
|
|
@@ -215,6 +237,10 @@ navigation stops at the gate. Works without paywall rules aren't affected.
|
|
|
215
237
|
pass a new `entitlementSnapshot`; the overlay closes once the reader is
|
|
216
238
|
through. Story keys and swipes do nothing while the paywall or the age
|
|
217
239
|
gate is open.
|
|
240
|
+
- **Custom `entitlementAdapter`:** it decides navigation, not rendering. A
|
|
241
|
+
panel the adapter refuses still renders (on the initial load the paywall
|
|
242
|
+
opens over it), so don't rely on an adapter to hide content: strip it on
|
|
243
|
+
the server (`"x-locked": true`) or pass an `entitlementSnapshot`.
|
|
218
244
|
|
|
219
245
|
### Going further
|
|
220
246
|
|