@netless/app-slide 0.3.0-canary.1 → 0.3.0-canary.11
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/dist/SlideViewer.d.ts +21 -4
- package/dist/index.d.ts +4 -1
- package/dist/main.iife.js +2 -6362
- package/dist/main.iife.js.map +1 -1
- package/dist/main.js +3 -0
- package/dist/main.js.map +1 -0
- package/dist/main.mjs +1104 -0
- package/dist/main.mjs.map +1 -0
- package/dist/typings.d.ts +7 -15
- package/package.json +9 -7
- package/src/SlideViewer.ts +63 -34
- package/src/index.ts +61 -28
- package/src/style.scss +61 -15
- package/src/typings.ts +19 -15
- package/dist/main.cjs.js +0 -6363
- package/dist/main.cjs.js.map +0 -1
- package/dist/main.es.js +0 -38205
- package/dist/main.es.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -6,11 +6,15 @@ export type { SlideState, AddHooks, AppOptions, Attributes, MagixEvents, SlideVi
|
|
|
6
6
|
|
|
7
7
|
import ColorString from "color-string";
|
|
8
8
|
import { SideEffectManager } from "side-effect-manager";
|
|
9
|
+
import { Slide } from "@netless/slide";
|
|
9
10
|
import { SlideViewer } from "./SlideViewer";
|
|
10
11
|
import { refrigerator, addHooks } from "./Refrigerator";
|
|
11
|
-
import {
|
|
12
|
+
import { DefaultUrl } from "./constants";
|
|
12
13
|
|
|
13
|
-
export { SlideViewer, refrigerator, addHooks };
|
|
14
|
+
export { Slide, SlideViewer, refrigerator, addHooks, DefaultUrl };
|
|
15
|
+
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
export const usePlugin = /* @__PURE__ */ Slide.usePlugin.bind(Slide) as (plugin: any) => void;
|
|
14
18
|
|
|
15
19
|
export const version = __APP_VERSION__;
|
|
16
20
|
|
|
@@ -23,29 +27,36 @@ const SlideApp: NetlessApp<Attributes, MagixEvents, AppOptions, void> = {
|
|
|
23
27
|
throw new Error("[Slide] no taskId");
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
const
|
|
27
|
-
const
|
|
30
|
+
const appOptions = context.getAppOptions() || {};
|
|
31
|
+
const options = appOptions.renderOptions || {};
|
|
32
|
+
const logger = make_logger(context, appOptions.debug);
|
|
33
|
+
logger.info("[Slide] setup @ " + __APP_VERSION__);
|
|
28
34
|
|
|
29
35
|
const sideEffect = new SideEffectManager();
|
|
30
36
|
|
|
31
|
-
//
|
|
37
|
+
// Create UI
|
|
32
38
|
const viewer = new SlideViewer({
|
|
33
39
|
interactive: true,
|
|
34
40
|
mode: "interactive",
|
|
35
41
|
resize: true,
|
|
36
42
|
enableGlobalClick: true,
|
|
37
|
-
controller: debug,
|
|
38
43
|
timestamp: make_timestamp(context),
|
|
39
|
-
logger:
|
|
44
|
+
logger: appOptions.logger || logger,
|
|
40
45
|
renderOptions: {
|
|
41
46
|
minFPS: options.minFPS || 25,
|
|
42
47
|
maxFPS: options.maxFPS || 30,
|
|
43
48
|
autoFPS: options.autoFPS ?? true,
|
|
44
49
|
autoResolution: options.autoResolution ?? true,
|
|
45
50
|
resolution: options.resolution,
|
|
46
|
-
|
|
51
|
+
maxResolutionLevel: options.maxResolutionLevel,
|
|
52
|
+
transactionBgColor: options.transactionBgColor || make_bg_color(context.box.$content),
|
|
47
53
|
},
|
|
48
|
-
|
|
54
|
+
rtcAudio: appOptions.rtcAudio,
|
|
55
|
+
useLocalCache: appOptions.useLocalCache,
|
|
56
|
+
resourceTimeout: appOptions.resourceTimeout,
|
|
57
|
+
loaderDelegate: appOptions.loaderDelegate,
|
|
58
|
+
navigatorDelegate: appOptions.navigatorDelegate,
|
|
59
|
+
fixedFrameSize: appOptions.fixedFrameSize,
|
|
49
60
|
taskId: context.storage.state.taskId,
|
|
50
61
|
url: context.storage.state.url,
|
|
51
62
|
});
|
|
@@ -61,37 +72,45 @@ const SlideApp: NetlessApp<Attributes, MagixEvents, AppOptions, void> = {
|
|
|
61
72
|
(window as any).slideViewer = viewer;
|
|
62
73
|
}
|
|
63
74
|
|
|
64
|
-
//
|
|
75
|
+
// Mount UI
|
|
65
76
|
context.box.mountStyles(SlideViewer.styles);
|
|
66
77
|
context.box.mountStage(viewer.$slide);
|
|
67
78
|
context.box.mountFooter(viewer.$footer);
|
|
68
79
|
context.box.mountContent(viewer.$content);
|
|
69
80
|
sideEffect.addDisposer(() => viewer.destroy());
|
|
70
81
|
|
|
71
|
-
//
|
|
72
|
-
connect({ context, viewer, sideEffect,
|
|
82
|
+
// Connect UI with Netless App
|
|
83
|
+
connect({ context, viewer, sideEffect, logger });
|
|
73
84
|
|
|
74
85
|
onUnmount(context, () => {
|
|
75
|
-
|
|
86
|
+
logger.info("[Slide] destroy");
|
|
76
87
|
sideEffect.flushAll();
|
|
77
88
|
});
|
|
89
|
+
|
|
90
|
+
return viewer;
|
|
78
91
|
},
|
|
79
92
|
};
|
|
80
93
|
|
|
81
94
|
export default SlideApp;
|
|
82
95
|
|
|
83
96
|
export function previewSlide(options: SlideViewerOptions & { container: HTMLElement }) {
|
|
84
|
-
const { container } = options;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
const { container, ...slideOptions } = options;
|
|
98
|
+
const wrapper = document.createElement("div");
|
|
99
|
+
wrapper.className = "netless-app-slide-preview-wrapper";
|
|
100
|
+
const viewer = new SlideViewer(slideOptions);
|
|
101
|
+
wrapper.appendChild(document.createElement("style")).textContent = SlideViewer.styles;
|
|
102
|
+
wrapper.appendChild(viewer.$content);
|
|
103
|
+
wrapper.appendChild(viewer.$footer);
|
|
104
|
+
container.appendChild(wrapper);
|
|
90
105
|
viewer.prepare(() => viewer.slide.renderSlide(1));
|
|
91
|
-
viewer.slide.on("slideChange", page => viewer.setPage(page));
|
|
92
106
|
return viewer;
|
|
93
107
|
}
|
|
94
108
|
|
|
109
|
+
if (import.meta.env.DEV) {
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
111
|
+
(window as any).previewSlide = previewSlide;
|
|
112
|
+
}
|
|
113
|
+
|
|
95
114
|
function make_timestamp(context: AppContext): () => number {
|
|
96
115
|
const room = context.room;
|
|
97
116
|
const player = context.displayer as Player;
|
|
@@ -104,7 +123,8 @@ function make_timestamp(context: AppContext): () => number {
|
|
|
104
123
|
}
|
|
105
124
|
}
|
|
106
125
|
|
|
107
|
-
function make_logger(context: AppContext) {
|
|
126
|
+
function make_logger(context: AppContext, debug?: boolean): { info: (msg: string) => void } {
|
|
127
|
+
void debug; // not used for now
|
|
108
128
|
if (import.meta.env.DEV) {
|
|
109
129
|
return { info: console.debug.bind(console) };
|
|
110
130
|
}
|
|
@@ -155,18 +175,19 @@ interface ConnectParams {
|
|
|
155
175
|
context: AppContext;
|
|
156
176
|
viewer: SlideViewer;
|
|
157
177
|
sideEffect: SideEffectManager;
|
|
158
|
-
|
|
178
|
+
logger: { info: (msg: string) => void };
|
|
159
179
|
}
|
|
160
180
|
|
|
161
|
-
function connect({ context, viewer, sideEffect,
|
|
162
|
-
const log =
|
|
181
|
+
function connect({ context, viewer, sideEffect, logger }: ConnectParams) {
|
|
182
|
+
const log = import.meta.env.DEV ? console.log.bind(console) : logger.info.bind(logger);
|
|
163
183
|
|
|
164
184
|
let whiteboard: WhiteBoardView | null = null;
|
|
165
185
|
|
|
166
186
|
viewer.prepare(({ width, height, slideCount }) => {
|
|
167
187
|
if (context.destroyed) return;
|
|
168
188
|
width && context.box.setStageRatio(height / width);
|
|
169
|
-
whiteboard = context.createWhiteBoardView(slideCount);
|
|
189
|
+
whiteboard = context.createWhiteBoardView({ size: slideCount });
|
|
190
|
+
whiteboard.setBaseRect({ width, height });
|
|
170
191
|
kick_start();
|
|
171
192
|
});
|
|
172
193
|
|
|
@@ -229,9 +250,10 @@ function connect({ context, viewer, sideEffect, debug }: ConnectParams) {
|
|
|
229
250
|
|
|
230
251
|
// save state
|
|
231
252
|
slide.on("slideChange", page => {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
253
|
+
if (context.isWritable && whiteboard) {
|
|
254
|
+
log("[Slide] page to", page);
|
|
255
|
+
whiteboard.jumpPage(page - 1);
|
|
256
|
+
}
|
|
235
257
|
});
|
|
236
258
|
|
|
237
259
|
// handle ui events
|
|
@@ -241,4 +263,15 @@ function connect({ context, viewer, sideEffect, debug }: ConnectParams) {
|
|
|
241
263
|
viewer.setReadonly(!w);
|
|
242
264
|
})
|
|
243
265
|
);
|
|
266
|
+
|
|
267
|
+
sideEffect.addEventListener(window, "keydown", ev => {
|
|
268
|
+
if (context.box.focus) {
|
|
269
|
+
if (ev.key === "ArrowUp" || ev.key === "ArrowLeft") {
|
|
270
|
+
viewer.slide.prevStep();
|
|
271
|
+
}
|
|
272
|
+
if (ev.key === "ArrowRight" || ev.key === "ArrowDown") {
|
|
273
|
+
viewer.slide.nextStep();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
});
|
|
244
277
|
}
|
package/src/style.scss
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
@import "./fancy-scrollbar.scss";
|
|
2
2
|
|
|
3
|
+
@mixin no-user-select {
|
|
4
|
+
-webkit-touch-callout: none;
|
|
5
|
+
-webkit-user-select: none;
|
|
6
|
+
-moz-user-select: none;
|
|
7
|
+
-ms-user-select: none;
|
|
8
|
+
user-select: none;
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
$namespace: "netless-app-slide";
|
|
4
12
|
|
|
5
13
|
.#{$namespace}-content {
|
|
@@ -11,12 +19,13 @@ $namespace: "netless-app-slide";
|
|
|
11
19
|
.#{$namespace}-slide {
|
|
12
20
|
width: 100%;
|
|
13
21
|
height: 100%;
|
|
22
|
+
@include no-user-select;
|
|
14
23
|
}
|
|
15
24
|
|
|
16
25
|
.#{$namespace}-preview-mask {
|
|
17
26
|
display: none;
|
|
18
27
|
position: absolute;
|
|
19
|
-
z-index:
|
|
28
|
+
z-index: 10200;
|
|
20
29
|
top: 0;
|
|
21
30
|
left: 0;
|
|
22
31
|
width: 100%;
|
|
@@ -28,7 +37,7 @@ $namespace: "netless-app-slide";
|
|
|
28
37
|
flex-direction: column;
|
|
29
38
|
align-items: center;
|
|
30
39
|
position: absolute;
|
|
31
|
-
z-index:
|
|
40
|
+
z-index: 10300;
|
|
32
41
|
top: 0;
|
|
33
42
|
left: 0;
|
|
34
43
|
width: 33%;
|
|
@@ -39,6 +48,7 @@ $namespace: "netless-app-slide";
|
|
|
39
48
|
background: rgba(237, 237, 240, 0.9);
|
|
40
49
|
box-shadow: inset -1px 0 0 rgba(0, 0, 0, 0.11);
|
|
41
50
|
transition: transform 0.4s;
|
|
51
|
+
@include no-user-select;
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
.#{$namespace}-preview-active {
|
|
@@ -62,7 +72,7 @@ $namespace: "netless-app-slide";
|
|
|
62
72
|
border: 7px solid transparent;
|
|
63
73
|
border-radius: 4px;
|
|
64
74
|
transition: border-color 0.3s;
|
|
65
|
-
user-select
|
|
75
|
+
@include no-user-select;
|
|
66
76
|
|
|
67
77
|
&:hover,
|
|
68
78
|
&.#{$namespace}-preview-page-active {
|
|
@@ -88,7 +98,23 @@ $namespace: "netless-app-slide";
|
|
|
88
98
|
text-align: right;
|
|
89
99
|
font-size: 12px;
|
|
90
100
|
color: #5f5f5f;
|
|
91
|
-
user-select
|
|
101
|
+
@include no-user-select;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.#{$namespace}-overlay {
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
justify-content: center;
|
|
108
|
+
position: absolute;
|
|
109
|
+
z-index: 10100;
|
|
110
|
+
top: 0;
|
|
111
|
+
left: 0;
|
|
112
|
+
width: 100%;
|
|
113
|
+
height: 100%;
|
|
114
|
+
background: rgba(255, 0, 0, 0.25);
|
|
115
|
+
transition: opacity 0.3s;
|
|
116
|
+
opacity: 0;
|
|
117
|
+
pointer-events: none;
|
|
92
118
|
}
|
|
93
119
|
|
|
94
120
|
.#{$namespace}-footer {
|
|
@@ -98,7 +124,8 @@ $namespace: "netless-app-slide";
|
|
|
98
124
|
align-items: center;
|
|
99
125
|
padding: 0 16px;
|
|
100
126
|
border-top: 1px solid #eeeef7;
|
|
101
|
-
|
|
127
|
+
font-family: system-ui, -apple-system, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Noto Sans",
|
|
128
|
+
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
102
129
|
}
|
|
103
130
|
|
|
104
131
|
.#{$namespace}-float-footer {
|
|
@@ -126,7 +153,7 @@ $namespace: "netless-app-slide";
|
|
|
126
153
|
background: transparent;
|
|
127
154
|
transition: background 0.4s;
|
|
128
155
|
cursor: pointer;
|
|
129
|
-
user-select
|
|
156
|
+
@include no-user-select;
|
|
130
157
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
131
158
|
|
|
132
159
|
&:hover {
|
|
@@ -171,11 +198,15 @@ $namespace: "netless-app-slide";
|
|
|
171
198
|
}
|
|
172
199
|
|
|
173
200
|
.#{$namespace}-page-number {
|
|
201
|
+
display: flex;
|
|
202
|
+
align-items: center;
|
|
203
|
+
height: 26px;
|
|
174
204
|
margin-left: auto;
|
|
175
205
|
font-size: 13px;
|
|
176
|
-
user-select
|
|
206
|
+
@include no-user-select;
|
|
177
207
|
white-space: nowrap;
|
|
178
208
|
word-break: keep-all;
|
|
209
|
+
font-variant-numeric: tabular-nums;
|
|
179
210
|
}
|
|
180
211
|
|
|
181
212
|
.#{$namespace}-page-number-input {
|
|
@@ -183,7 +214,7 @@ $namespace: "netless-app-slide";
|
|
|
183
214
|
outline: none;
|
|
184
215
|
width: 3em;
|
|
185
216
|
margin: 0;
|
|
186
|
-
padding: 0 2px;
|
|
217
|
+
padding: 0 0.5em 0 2px;
|
|
187
218
|
text-align: right;
|
|
188
219
|
font-size: 13px;
|
|
189
220
|
line-height: 1;
|
|
@@ -191,14 +222,17 @@ $namespace: "netless-app-slide";
|
|
|
191
222
|
font-family: inherit;
|
|
192
223
|
border-radius: 2px;
|
|
193
224
|
color: currentColor;
|
|
225
|
+
font-family: system-ui, -apple-system, "Segoe UI", "Roboto", "Ubuntu", "Cantarell", "Noto Sans",
|
|
226
|
+
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
194
227
|
background: transparent;
|
|
195
228
|
transition: background 0.4s;
|
|
196
|
-
|
|
229
|
+
font-variant-numeric: tabular-nums;
|
|
197
230
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
198
231
|
|
|
199
232
|
&:hover,
|
|
200
233
|
&:focus,
|
|
201
234
|
&:active {
|
|
235
|
+
user-select: text;
|
|
202
236
|
background: #fff;
|
|
203
237
|
box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
|
|
204
238
|
}
|
|
@@ -234,17 +268,13 @@ $namespace: "netless-app-slide";
|
|
|
234
268
|
}
|
|
235
269
|
|
|
236
270
|
.telebox-color-scheme-dark {
|
|
237
|
-
.#{$namespace}-page-number-input {
|
|
238
|
-
color: #a6a6a8;
|
|
239
|
-
}
|
|
240
271
|
.#{$namespace}-page-number-input:active,
|
|
241
272
|
.#{$namespace}-page-number-input:focus,
|
|
242
273
|
.#{$namespace}-page-number-input:hover {
|
|
243
|
-
color:
|
|
274
|
+
color: currentColor;
|
|
275
|
+
background: #25282e;
|
|
244
276
|
}
|
|
245
277
|
.#{$namespace}-footer {
|
|
246
|
-
color: #a6a6a8;
|
|
247
|
-
background: #2d2d33;
|
|
248
278
|
border-top: none;
|
|
249
279
|
}
|
|
250
280
|
.#{$namespace}-footer-btn:hover {
|
|
@@ -254,3 +284,19 @@ $namespace: "netless-app-slide";
|
|
|
254
284
|
background: rgba(50, 50, 50, 0.9);
|
|
255
285
|
}
|
|
256
286
|
}
|
|
287
|
+
|
|
288
|
+
.#{$namespace}-preview-wrapper {
|
|
289
|
+
width: 100%;
|
|
290
|
+
height: 100%;
|
|
291
|
+
overflow: hidden;
|
|
292
|
+
display: flex;
|
|
293
|
+
flex-flow: column nowrap;
|
|
294
|
+
|
|
295
|
+
.#{$namespace}-content {
|
|
296
|
+
flex: 1;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.#{$namespace}-footer {
|
|
300
|
+
flex-shrink: 0;
|
|
301
|
+
}
|
|
302
|
+
}
|
package/src/typings.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Slide, SLIDE_EVENTS, SyncEvent } from "@netless/slide";
|
|
1
|
+
import type { ISlideConfig, Slide, SLIDE_EVENTS, SyncEvent } from "@netless/slide";
|
|
2
2
|
import type { RegisterParams } from "@netless/window-manager";
|
|
3
3
|
|
|
4
4
|
export type SlideState = Slide["slideState"];
|
|
@@ -18,19 +18,23 @@ export interface MagixEvents {
|
|
|
18
18
|
[SLIDE_EVENTS.syncDispatch]: SyncEvent;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
export interface AppOptions
|
|
22
|
-
|
|
21
|
+
export interface AppOptions
|
|
22
|
+
extends Pick<
|
|
23
|
+
ISlideConfig,
|
|
24
|
+
| "renderOptions"
|
|
25
|
+
| "rtcAudio"
|
|
26
|
+
| "useLocalCache"
|
|
27
|
+
| "resourceTimeout"
|
|
28
|
+
| "loaderDelegate"
|
|
29
|
+
| "navigatorDelegate"
|
|
30
|
+
| "fixedFrameSize"
|
|
31
|
+
| "logger"
|
|
32
|
+
> {
|
|
23
33
|
debug?: boolean;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
/** maximal fps (default: 30) */
|
|
31
|
-
maxFPS?: number;
|
|
32
|
-
/** automatically decrease fps (default: true) */
|
|
33
|
-
autoFPS?: boolean;
|
|
34
|
-
/** whether to re-scale automatically (default: true) */
|
|
35
|
-
autoResolution?: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ILogger {
|
|
37
|
+
info?(msg: string): void;
|
|
38
|
+
error?(msg: string): void;
|
|
39
|
+
warn?(msg: string): void;
|
|
36
40
|
}
|