@netless/app-presentation 0.1.8-beta.0 → 0.1.8

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/index.js CHANGED
@@ -794,127 +794,98 @@ function arrowRightSVG(namespace) {
794
794
  var _Preload = class _Preload {
795
795
  constructor(pages) {
796
796
  this.pages = pages;
797
+ // 正在加载的链接
797
798
  this.loadingLinks = /* @__PURE__ */ new Map();
799
+ // 需要预加载的链接集合
798
800
  this.preloadMap = /* @__PURE__ */ new Map();
799
- this.waitingLoadSet = /* @__PURE__ */ new Set();
800
- this.waitinglinks = [];
801
+ // 当前触摸的索引
801
802
  this.touchIndex = 0;
802
803
  this.preloadSize = 0;
803
804
  this.preloadMap = new Map(pages.map((e, index) => [index, {
804
805
  src: e.src,
805
806
  state: 0 /* unloaded */
806
807
  }]));
807
- this.waitingLoadSet = new Set(pages.map((e, index) => index));
808
808
  this.preloadSize = this.preloadMap.size;
809
- this.touch(0);
809
+ this.touch(0, true);
810
810
  }
811
- async touch(index) {
812
- this.touchIndex = index;
813
- const value = this.preloadMap.get(index);
814
- let state = 0 /* unloaded */;
815
- if (value) {
816
- state = value.state;
817
- if (value.state === 0 /* unloaded */) {
818
- if (this.loadingLinks.size) {
819
- for (const [i, link] of this.loadingLinks) {
820
- this.destroyLink(i, link);
821
- this.waitingLoadSet.add(i);
822
- const v = this.preloadMap.get(i);
823
- if (v) {
824
- v.state = 0 /* unloaded */;
825
- this.preloadMap.set(i, v);
826
- }
827
- }
828
- for (const i of this.waitinglinks) {
829
- this.waitingLoadSet.add(i);
830
- }
831
- this.waitinglinks.length = 0;
832
- }
833
- if (this.waitinglinks.includes(index)) {
834
- this.waitinglinks.splice(this.waitinglinks.indexOf(index), 1);
835
- }
836
- state = await new Promise((resolve) => {
837
- this.waitingLoadSet.delete(index);
838
- this.createLink(index, resolve);
839
- });
840
- }
841
- }
842
- if (this.waitingLoadSet.size) {
843
- this.requestAsyncCallBack(() => {
844
- this.autoTouch();
845
- }, 1e3);
846
- }
847
- return state;
848
- }
849
- autoTouch() {
850
- this.handler();
851
- if (this.waitingLoadSet.size === 0) {
852
- return;
811
+ touch(index, force = false) {
812
+ if (index >= this.preloadSize) {
813
+ this.touchIndex = 0;
814
+ } else {
815
+ this.touchIndex = index;
853
816
  }
854
- let nextTouchDelay = 1e3;
855
- this.touchIndex = (this.touchIndex + 1) % this.preloadSize;
856
817
  const value = this.preloadMap.get(this.touchIndex);
857
- if (value) {
858
- switch (value.state) {
859
- case 0 /* unloaded */:
860
- case 3 /* error */:
861
- if (!this.waitinglinks.includes(this.touchIndex)) {
862
- this.waitinglinks.push(this.touchIndex);
863
- this.waitingLoadSet.delete(this.touchIndex);
864
- }
865
- nextTouchDelay = 0;
866
- break;
818
+ if (value && value.state === 0 /* unloaded */) {
819
+ this.createLink(this.touchIndex, force);
820
+ }
821
+ if (this.loadingLinks.size < _Preload.maxLinks) {
822
+ const willLoad = [...this.preloadMap.entries()].find(([i, e]) => i > this.touchIndex && e.state !== 1 /* loaded */);
823
+ if (willLoad) {
824
+ this.requestAsyncCallBack(() => {
825
+ this.touch(willLoad[0], false);
826
+ }, 100);
867
827
  }
868
828
  }
869
- this.requestAsyncCallBack(() => {
870
- this.autoTouch();
871
- }, nextTouchDelay);
872
829
  }
873
- createLink(index, resolve) {
830
+ createLink(index, force = false) {
874
831
  const value = this.preloadMap.get(index);
832
+ if (force) {
833
+ this.destroySomeLink(index);
834
+ }
875
835
  if (value) {
876
- const link = document.createElement("link");
877
- link.rel = "preload";
878
- link.as = "image";
879
- link.href = value.src;
880
- link.dataset.order = index + "";
881
- document.head.appendChild(link);
882
- link.onload = () => {
883
- value.state = 2 /* loaded */;
884
- this.preloadMap.set(index, value);
885
- document.head.contains(link) && document.head.removeChild(link);
886
- this.loadingLinks.delete(index);
887
- resolve && resolve(2 /* loaded */);
888
- this.autoTouch();
836
+ if (value.state === 1 /* loaded */) {
837
+ return 1 /* loaded */;
838
+ }
839
+ const curlink = this.loadingLinks.get(index);
840
+ if (curlink) {
841
+ if (curlink.isForce !== force) {
842
+ curlink.isForce = force;
843
+ this.loadingLinks.set(index, curlink);
844
+ }
845
+ return 0 /* unloaded */;
846
+ }
847
+ if (this.loadingLinks.size > _Preload.maxLinks) {
848
+ return 0 /* unloaded */;
849
+ }
850
+ const linkDom = document.createElement("link");
851
+ linkDom.rel = "preload";
852
+ linkDom.as = "image";
853
+ linkDom.href = value.src;
854
+ linkDom.dataset.order = index + "";
855
+ document.head.appendChild(linkDom);
856
+ linkDom.onload = () => {
857
+ const value2 = this.preloadMap.get(index);
858
+ if (value2) {
859
+ value2.state = 1 /* loaded */;
860
+ this.preloadMap.set(index, value2);
861
+ document.head.contains(linkDom) && document.head.removeChild(linkDom);
862
+ this.loadingLinks.delete(index);
863
+ this.touch(this.touchIndex + 1, false);
864
+ }
889
865
  };
890
- link.onerror = () => {
891
- value.state = 3 /* error */;
892
- this.preloadMap.set(index, value);
893
- if (!this.waitinglinks.includes(index)) {
894
- this.waitinglinks.push(index);
895
- this.waitingLoadSet.delete(this.touchIndex);
866
+ linkDom.onerror = () => {
867
+ const value2 = this.preloadMap.get(index);
868
+ if (value2 == null ? void 0 : value2.src) {
869
+ linkDom.href = value2.src;
896
870
  }
897
- document.head.contains(link) && document.head.removeChild(link);
898
- this.loadingLinks.delete(index);
899
- resolve && resolve(3 /* error */);
900
- this.autoTouch();
901
871
  };
902
- this.loadingLinks.set(index, link);
903
- value.state = 1 /* loading */;
872
+ this.loadingLinks.set(index, {
873
+ link: linkDom,
874
+ isForce: force
875
+ });
876
+ value.state = 0 /* unloaded */;
904
877
  this.preloadMap.set(index, value);
878
+ return 0 /* unloaded */;
905
879
  }
880
+ return 2 /* error */;
906
881
  }
907
- handler() {
908
- if (!this.waitinglinks.length) {
909
- return;
910
- }
911
- let i = this.loadingLinks.size;
912
- while (i < _Preload.maxLinks) {
913
- const index = this.waitinglinks.shift();
914
- if (index !== void 0) {
915
- this.createLink(index);
882
+ destroySomeLink(excludeIndex) {
883
+ for (const [index, { link }] of this.loadingLinks) {
884
+ if (excludeIndex !== void 0 && index === excludeIndex) {
885
+ continue;
916
886
  }
917
- i++;
887
+ document.head.contains(link) && document.head.removeChild(link);
888
+ this.loadingLinks.delete(index);
918
889
  }
919
890
  }
920
891
  async requestAsyncCallBack(callBack, timeout) {
@@ -931,17 +902,9 @@ var _Preload = class _Preload {
931
902
  });
932
903
  callBack();
933
904
  }
934
- destroyLink(index, link) {
935
- document.head.contains(link) && document.head.removeChild(link);
936
- this.loadingLinks.delete(index);
937
- }
938
905
  dispose() {
939
- for (const [index, link] of this.loadingLinks) {
940
- this.destroyLink(index, link);
941
- }
906
+ this.destroySomeLink();
942
907
  this.preloadMap.clear();
943
- this.waitingLoadSet.clear();
944
- this.waitinglinks.length = 0;
945
908
  }
946
909
  };
947
910
  _Preload.maxLinks = 5;
@@ -1168,16 +1131,7 @@ var Presentation = class {
1168
1131
  }
1169
1132
  this.timer = setTimeout(() => {
1170
1133
  this.timer = null;
1171
- this.preload.touch(this.pageIndex).then(() => {
1172
- const page = this.page();
1173
- if (!page) {
1174
- this.image.src = "";
1175
- return;
1176
- }
1177
- this.image.width = page.width;
1178
- this.image.height = page.height;
1179
- this.image.src = page.src;
1180
- });
1134
+ this.preload.touch(this.pageIndex, true);
1181
1135
  }, 200);
1182
1136
  }
1183
1137
  /** Returns a modified URL that points to the thumbnail image. */
@@ -1205,7 +1159,77 @@ var Presentation = class {
1205
1159
  // src/style.scss?inline
1206
1160
  var style_default = ".netless-app-presentation{height:100%;display:flex;flex-flow:column nowrap}.netless-app-presentation-content{position:relative;height:100%;overflow:hidden}.netless-app-presentation-preview-mask{display:none;position:absolute;z-index:200;top:0;left:0;width:100%;height:100%}.netless-app-presentation-preview{display:flex;flex-direction:column;align-items:center;position:absolute;z-index:300;top:0;left:0;width:33%;max-width:200px;height:100%;padding-top:10px;transform:translate(-100%);background:#ededf0e6;box-shadow:inset -1px 0 #0000001c;transition:transform .4s;overflow:auto;overflow-y:scroll}.netless-app-presentation-preview-active .netless-app-presentation-preview-mask{display:block}.netless-app-presentation-preview-active .netless-app-presentation-preview{transform:translate(0)}.netless-app-presentation-preview-page{position:relative;display:block;width:55%;margin-bottom:10px;font-size:0;color:#0000;outline:none;border:7px solid rgba(0,0,0,0);border-radius:4px;transition:border-color .3s;user-select:none}.netless-app-presentation-preview-page:hover,.netless-app-presentation-preview-page.netless-app-presentation-preview-page-active{border-color:#444e601a}.netless-app-presentation-preview-page>img{width:100%;height:auto;box-sizing:border-box;border:1px solid rgba(0,0,0,.5);border-radius:1px;background-color:#fff;box-shadow:0 2px 8px #0000004d}.netless-app-presentation-preview-page-name{position:absolute;top:1px;left:-10px;transform:translate(-100%);text-align:right;font-size:12px;color:#5f5f5f;user-select:none}.netless-app-presentation-footer{box-sizing:border-box;height:26px;display:flex;align-items:center;padding:0 16px;border-top:1px solid #eeeef7;color:#191919}.netless-app-presentation-float-footer{width:100%;min-height:26px;position:absolute;left:0;bottom:0;z-index:2000;background:#f9f9fce6;transition:opacity .4s}.netless-app-presentation-footer-btn{box-sizing:border-box;width:26px;height:26px;font-size:0;margin:0;padding:3px;border:none;border-radius:1px;outline:none;color:currentColor;background:#0000;transition:background .4s;cursor:pointer;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.netless-app-presentation-footer-btn:hover{background:#ededf0e6}@media (hover: none){.netless-app-presentation-footer-btn:hover{background:#0000!important}}.netless-app-presentation-footer-btn>svg{width:100%;height:100%}.netless-app-presentation-footer-btn>svg:nth-of-type(2){display:none}.netless-app-presentation-footer-btn.netless-app-presentation-footer-btn-playing>svg:nth-of-type(1){display:none}.netless-app-presentation-footer-btn.netless-app-presentation-footer-btn-playing>svg:nth-of-type(2){display:initial}.netless-app-presentation-footer-btn~.netless-app-presentation-footer-btn{margin-left:15px}.netless-app-presentation-page-jumps{flex:1;display:flex;justify-content:center;align-items:center}.netless-app-presentation-page-number{margin-left:auto;font-size:13px;user-select:none;white-space:nowrap;word-break:keep-all}.netless-app-presentation-page-number-input{border:none;outline:none;width:3em;margin:0;padding:0 2px;text-align:right;font-size:13px;line-height:1;font-weight:400;font-family:inherit;border-radius:2px;color:currentColor;background:#0000;transition:background .4s;user-select:text;-webkit-tap-highlight-color:rgba(0,0,0,0)}.netless-app-presentation-page-number-input:hover,.netless-app-presentation-page-number-input:focus,.netless-app-presentation-page-number-input:active{background:#fff;box-shadow:#63636333 0 2px 8px}.netless-app-presentation-readonly.netless-app-presentation-footer{display:none}.netless-app-presentation-wb-view{position:absolute;top:0;left:0;width:100%;height:100%;z-index:100;overflow:hidden;transition:opacity .2s}.netless-app-presentation-image{width:100%;height:100%;display:flex;align-items:center;justify-content:center}.netless-app-presentation-image>img{max-width:100%;max-height:100%;object-fit:contain}.telebox-color-scheme-dark .netless-app-presentation-page-number-input{color:#a6a6a8}.telebox-color-scheme-dark .netless-app-presentation-page-number-input:active,.telebox-color-scheme-dark .netless-app-presentation-page-number-input:focus,.telebox-color-scheme-dark .netless-app-presentation-page-number-input:hover{color:#222}.telebox-color-scheme-dark .netless-app-presentation-footer{color:#a6a6a8;background:#2d2d33;border-top:none}.telebox-color-scheme-dark .netless-app-presentation-footer-btn:hover{background:#212126}.telebox-color-scheme-dark .netless-app-presentation-preview{background:#323232e6}";
1207
1161
 
1162
+ // src/store.ts
1163
+ function noop() {
1164
+ }
1165
+ function safe_not_equal(a, b) {
1166
+ return a != a ? b == b : a !== b || a && typeof a === "object" || typeof a === "function";
1167
+ }
1168
+ function readable(value, start = noop) {
1169
+ let stop;
1170
+ const subscribers = /* @__PURE__ */ new Set();
1171
+ function set(new_value) {
1172
+ if (safe_not_equal(value, new_value)) {
1173
+ value = new_value;
1174
+ if (stop) {
1175
+ for (const run of subscribers) {
1176
+ run(value);
1177
+ }
1178
+ }
1179
+ }
1180
+ }
1181
+ function subscribe(run) {
1182
+ subscribers.add(run);
1183
+ if (subscribers.size === 1) {
1184
+ stop = start(set) || noop;
1185
+ }
1186
+ run(value);
1187
+ return () => {
1188
+ subscribers.delete(run);
1189
+ if (subscribers.size === 0) {
1190
+ stop && stop();
1191
+ stop = void 0;
1192
+ }
1193
+ };
1194
+ }
1195
+ function reaction(run) {
1196
+ subscribers.add(run);
1197
+ if (subscribers.size === 1) {
1198
+ stop = start(set) || noop;
1199
+ }
1200
+ return () => {
1201
+ subscribers.delete(run);
1202
+ if (subscribers.size === 0) {
1203
+ stop && stop();
1204
+ stop = void 0;
1205
+ }
1206
+ };
1207
+ }
1208
+ function dispose2(new_value) {
1209
+ if (new_value !== void 0) {
1210
+ set(new_value);
1211
+ }
1212
+ subscribers.clear();
1213
+ stop && stop();
1214
+ stop = void 0;
1215
+ }
1216
+ return {
1217
+ get value() {
1218
+ if (subscribers.size === 0) {
1219
+ stop = start(set) || noop;
1220
+ stop();
1221
+ stop = void 0;
1222
+ }
1223
+ return value;
1224
+ },
1225
+ subscribe,
1226
+ reaction,
1227
+ dispose: dispose2
1228
+ };
1229
+ }
1230
+
1208
1231
  // src/app-presentation.ts
1232
+ var emptySceneName = "$$empty$$";
1209
1233
  var ppt2page = (ppt, name) => ppt ? { width: ppt.width, height: ppt.height, src: ppt.src, thumbnail: ppt.previewURL, name } : null;
1210
1234
  var createLogger = (room) => {
1211
1235
  if (room && room.logger) {
@@ -1214,10 +1238,22 @@ var createLogger = (room) => {
1214
1238
  return (...args) => console.log(...args);
1215
1239
  }
1216
1240
  };
1241
+ var scenesEqual = (scenes1, scenes2) => {
1242
+ if (!scenes1 || !scenes2) {
1243
+ return false;
1244
+ }
1245
+ if (scenes1.length !== scenes2.length)
1246
+ return false;
1247
+ return scenes1.every((scene, index) => {
1248
+ var _a, _b, _c, _d, _e, _f;
1249
+ const scene2 = scenes2[index];
1250
+ return scene.name === scene2.name && ((_a = scene.ppt) == null ? void 0 : _a.width) === ((_b = scene2.ppt) == null ? void 0 : _b.width) && ((_c = scene.ppt) == null ? void 0 : _c.height) === ((_d = scene2.ppt) == null ? void 0 : _d.height) && ((_e = scene.ppt) == null ? void 0 : _e.src) === ((_f = scene2.ppt) == null ? void 0 : _f.src);
1251
+ });
1252
+ };
1217
1253
  var NetlessAppPresentation = {
1218
1254
  kind: "Presentation",
1219
1255
  setup(context) {
1220
- var _a, _b, _c, _d, _e;
1256
+ var _a, _b, _c;
1221
1257
  const view = context.getView();
1222
1258
  if (!view)
1223
1259
  throw new Error("[Presentation]: no whiteboard view, make sure you have added options.scenePath in addApp()");
@@ -1235,43 +1271,88 @@ var NetlessAppPresentation = {
1235
1271
  }
1236
1272
  const log = options.log || createLogger(context.getRoom());
1237
1273
  log(`[Presentation] new ${context.appId}`);
1274
+ const dispose2 = disposableStore();
1275
+ dispose2.add(() => log(`[Presentation] dispose ${context.appId}`));
1276
+ const view$$ = context.createStorage("view", { uid: "", originX: 0, originY: 0, width: 0, height: 0 });
1277
+ const _addScenePathListener = (name, listener) => {
1278
+ const windowManger = context.manager.windowManger;
1279
+ windowManger.emitter.on(name, listener);
1280
+ return () => windowManger == null ? void 0 : windowManger.emitter.off(name, listener);
1281
+ };
1282
+ const getPageIndex = (view2) => {
1283
+ const focusScenePath = view2.focusScenePath;
1284
+ const name = focusScenePath == null ? void 0 : focusScenePath.split("/").pop();
1285
+ let _pageIndex = pages.findIndex((page, index) => {
1286
+ var _a2;
1287
+ const n = (_a2 = page.name) != null ? _a2 : String(index + 1);
1288
+ return n === name;
1289
+ });
1290
+ if (_pageIndex === -1) {
1291
+ _pageIndex = 0;
1292
+ }
1293
+ return _pageIndex;
1294
+ };
1295
+ let pageIndex = getPageIndex(view);
1296
+ const pageIndex$ = readable(pageIndex, (set) => {
1297
+ set(pageIndex);
1298
+ return _addScenePathListener("onAppScenePathChange", (payload) => {
1299
+ const { appId } = payload;
1300
+ if (appId === context.appId) {
1301
+ const _pageIndex = getPageIndex(payload.view);
1302
+ set(_pageIndex);
1303
+ }
1304
+ });
1305
+ });
1306
+ dispose2.add(() => {
1307
+ pageIndex$.dispose();
1308
+ });
1238
1309
  if (context.isAddApp) {
1239
1310
  if (pages.length > 100)
1240
1311
  console.warn(`[Presentation]: too many pages (${pages.length}), may cause performance issues`);
1312
+ let redirectResolve = void 0;
1241
1313
  const room = context.getRoom();
1242
1314
  if (room && room.isWritable) {
1243
1315
  const scenes = room.entireScenes()[scenePath];
1244
- for (let i = 0; i < pages.length; i++) {
1245
- const p = pages[i];
1246
- const name = (_c = p.name) != null ? _c : String(i + 1);
1247
- const scene = scenes.find((scene2) => scene2.name == name && scene2.ppt);
1248
- if (scene) {
1249
- if (scene.ppt && ((_d = scene.ppt) == null ? void 0 : _d.src) === p.src) {
1250
- continue;
1251
- }
1252
- room.removeScenes(`${scenePath}/${name}`);
1253
- }
1254
- room.putScenes(scenePath, pages.map((p2, index) => {
1316
+ if (pageIndex$.value < 0 || pageIndex$.value >= pages.length) {
1317
+ throw new Error(`[Presentation] Invalid page index: ${pageIndex$.value}, scenes length: ${pages.length}`);
1318
+ }
1319
+ new Promise((resolve) => {
1320
+ const { name, ppt } = scenes[pageIndex$.value];
1321
+ redirectResolve = resolve;
1322
+ const _scenes = pages.map((p, index) => {
1255
1323
  var _a2;
1256
1324
  return {
1257
- name: (_a2 = p2.name) != null ? _a2 : String(index + 1),
1258
- ppt: { width: p2.width, height: p2.height, src: p2.src }
1325
+ name: (_a2 = p.name) != null ? _a2 : String(index + 1),
1326
+ ppt: { width: p.width, height: p.height, src: p.src }
1259
1327
  };
1260
- }));
1261
- }
1328
+ });
1329
+ if (!scenesEqual(scenes, _scenes)) {
1330
+ room.removeScenes(scenePath);
1331
+ room.putScenes(scenePath, _scenes);
1332
+ }
1333
+ if (name === _scenes[pageIndex$.value].name && !ppt) {
1334
+ context.addPage({ scene: { name: emptySceneName } }).then(() => {
1335
+ log(`[Presentation] setup setScenePath ${scenePath}/${emptySceneName}`);
1336
+ context.setScenePath(`${scenePath}/${emptySceneName}`).then(() => {
1337
+ redirectResolve && redirectResolve(true);
1338
+ });
1339
+ });
1340
+ } else {
1341
+ redirectResolve && redirectResolve(false);
1342
+ }
1343
+ }).then(async (bol) => {
1344
+ await syncPage(pageIndex$.value, room.logger);
1345
+ if (bol) {
1346
+ log(`[Presentation] setup removeScenes ${scenePath}/${emptySceneName}`);
1347
+ room.removeScenes(`${scenePath}/${emptySceneName}`);
1348
+ }
1349
+ });
1262
1350
  }
1263
1351
  }
1264
- const dispose2 = disposableStore();
1265
- dispose2.add(() => log(`[Presentation] dispose ${context.appId}`));
1266
- const page$$ = context.createStorage("page", { index: 0 });
1267
- const view$$ = context.createStorage("view", { uid: "", originX: 0, originY: 0, width: 0, height: 0 });
1268
- let lastIndex = -1;
1269
- const syncPage = async (index) => {
1352
+ const me = ((_c = context.getRoom()) == null ? void 0 : _c.uid) || context.getDisplayer().observerId + "";
1353
+ let throttleSyncView = 0;
1354
+ const syncPage = async (index, logger) => {
1270
1355
  var _a2;
1271
- if (lastIndex !== index) {
1272
- lastIndex = index;
1273
- context.dispatchAppEvent("pageStateChange", { index, length: pages.length });
1274
- }
1275
1356
  if (!context.getIsWritable())
1276
1357
  return;
1277
1358
  const scenes = context.getDisplayer().entireScenes()[scenePath];
@@ -1282,6 +1363,9 @@ var NetlessAppPresentation = {
1282
1363
  if (!scenes.some((scene) => scene.name === name)) {
1283
1364
  await context.addPage({ scene: { name, ppt: { width: p.width, height: p.height, src: p.src } } });
1284
1365
  }
1366
+ if (logger) {
1367
+ logger.info(`[Presentation] syncPage ${scenePath}/${name}`);
1368
+ }
1285
1369
  await context.setScenePath(`${scenePath}/${name}`);
1286
1370
  };
1287
1371
  const jumpPage = (index) => {
@@ -1302,14 +1386,14 @@ var NetlessAppPresentation = {
1302
1386
  const p = pages[index];
1303
1387
  const name = (_a2 = p.name) != null ? _a2 : String(index + 1);
1304
1388
  if (!scenes.some((scene) => scene.name === name)) {
1305
- context.addPage({ scene: { name } });
1389
+ context.addPage({ scene: { name, ppt: { width: p.width, height: p.height, src: p.src } } });
1306
1390
  }
1307
- page$$.setState({ index });
1391
+ syncPage(index);
1308
1392
  return true;
1309
1393
  };
1310
- const prevPage = () => jumpPage(page$$.state.index - 1);
1311
- const nextPage = () => jumpPage(page$$.state.index + 1);
1312
- const pageState = () => ({ index: page$$.state.index, length: pages.length });
1394
+ const prevPage = () => jumpPage(pageIndex$.value - 1);
1395
+ const nextPage = () => jumpPage(pageIndex$.value + 1);
1396
+ const pageState = () => ({ index: pageIndex$.value, length: pages.length });
1313
1397
  const scaleDocsToFit = () => {
1314
1398
  const { width, height } = app.page() || {};
1315
1399
  if (width && height) {
@@ -1334,8 +1418,6 @@ var NetlessAppPresentation = {
1334
1418
  syncViewFromRemote(true);
1335
1419
  }
1336
1420
  };
1337
- const me = ((_e = context.getRoom()) == null ? void 0 : _e.uid) || context.getDisplayer().observerId + "";
1338
- let throttleSyncView = 0;
1339
1421
  const syncView = () => {
1340
1422
  if (throttleSyncView > 0)
1341
1423
  return;
@@ -1370,12 +1452,10 @@ var NetlessAppPresentation = {
1370
1452
  });
1371
1453
  }
1372
1454
  };
1373
- syncPage(page$$.state.index);
1374
- dispose2.add(page$$.addStateChangedListener(() => syncPage(page$$.state.index)));
1375
1455
  dispose2.add(view$$.addStateChangedListener(() => syncViewFromRemote(false, true)));
1376
1456
  const box = context.getBox();
1377
- const app = dispose2.add(createPresentation(box, pages, jumpPage, page$$, options.thumbnail));
1378
- app.contentDOM.dataset.appPresentationVersion = "0.1.7";
1457
+ const app = dispose2.add(createPresentation(box, pages, jumpPage, pageIndex$, options.thumbnail));
1458
+ app.contentDOM.dataset.appPresentationVersion = "0.1.8";
1379
1459
  app.scaleDocsToFit = scaleDocsToFit;
1380
1460
  app.log = log;
1381
1461
  if (options.justDocsViewReadonly) {
@@ -1549,6 +1629,7 @@ var AppPresentation = class extends Presentation {
1549
1629
  this.image.style.display = "none";
1550
1630
  }
1551
1631
  updateImage() {
1632
+ super.updateImage();
1552
1633
  }
1553
1634
  onNewPageIndex(index, origin) {
1554
1635
  if (origin === "keydown" && this.box && !this.box.focus)
@@ -1562,15 +1643,14 @@ var AppPresentation = class extends Presentation {
1562
1643
  }
1563
1644
  }
1564
1645
  };
1565
- function createPresentation(box, pages, jumpPage, page$$, thumbnail) {
1646
+ function createPresentation(box, pages, jumpPage, pageIndex$, thumbnail) {
1566
1647
  box.mountStyles(style_default);
1567
1648
  const app = new AppPresentation({ pages, readonly: box.readonly, jumpPage, thumbnail });
1568
1649
  app.box = box;
1569
1650
  box.mountContent(app.contentDOM);
1570
1651
  box.mountFooter(app.footerDOM);
1571
- app.setPageIndex(page$$.state.index);
1572
- app.dispose.add(page$$.addStateChangedListener(() => {
1573
- app.setPageIndex(page$$.state.index);
1652
+ app.dispose.add(pageIndex$.subscribe((pageIndex) => {
1653
+ app.setPageIndex(pageIndex);
1574
1654
  }));
1575
1655
  return app;
1576
1656
  }
@@ -1583,7 +1663,7 @@ var install = (register, options = {}) => {
1583
1663
  };
1584
1664
 
1585
1665
  // src/index.ts
1586
- var version = "0.1.7";
1666
+ var version = "0.1.8";
1587
1667
 
1588
1668
  exports.NetlessAppPresentation = NetlessAppPresentation;
1589
1669
  exports.Presentation = Presentation;