@netless/window-manager 0.4.0-canary.7 → 0.4.1-canary.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/.idea/inspectionProfiles/Project_Default.xml +7 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/window-manager.iml +12 -0
- package/.vscode/settings.json +1 -0
- package/CHANGELOG.md +39 -2
- package/README.md +3 -0
- package/dist/App/MagixEvent/index.d.ts +29 -0
- package/dist/{src/App → App}/Storage/StorageEvent.d.ts +0 -0
- package/dist/App/Storage/index.d.ts +39 -0
- package/dist/{src/App → App}/Storage/typings.d.ts +1 -0
- package/dist/{src/App → App}/Storage/utils.d.ts +0 -0
- package/dist/AppContext.d.ts +68 -0
- package/dist/{src/AppListener.d.ts → AppListener.d.ts} +2 -0
- package/dist/{src/AppManager.d.ts → AppManager.d.ts} +23 -8
- package/dist/{src/AppProxy.d.ts → AppProxy.d.ts} +5 -5
- package/dist/{src/AttributesDelegate.d.ts → AttributesDelegate.d.ts} +2 -2
- package/dist/{src/BoxManager.d.ts → BoxManager.d.ts} +6 -4
- package/dist/{src/BuiltinApps.d.ts → BuiltinApps.d.ts} +0 -1
- package/dist/{src/ContainerResizeObserver.d.ts → ContainerResizeObserver.d.ts} +0 -0
- package/dist/{src/Cursor → Cursor}/Cursor.d.ts +10 -12
- package/dist/{src/Cursor → Cursor}/icons.d.ts +0 -0
- package/dist/{src/Cursor → Cursor}/index.d.ts +6 -16
- package/dist/{src/Helper.d.ts → Helper.d.ts} +1 -0
- package/dist/{src/ReconnectRefresher.d.ts → ReconnectRefresher.d.ts} +0 -0
- package/dist/{src/Register → Register}/index.d.ts +5 -0
- package/dist/{src/Register → Register}/loader.d.ts +0 -0
- package/dist/{src/Register → Register}/storage.d.ts +5 -1
- package/dist/Utils/AppCreateQueue.d.ts +11 -0
- package/dist/{src/Utils → Utils}/Common.d.ts +4 -1
- package/dist/{src/Utils → Utils}/Reactive.d.ts +0 -0
- package/dist/Utils/RoomHacker.d.ts +3 -0
- package/dist/{src/Utils → Utils}/error.d.ts +0 -0
- package/dist/{src/Utils → Utils}/log.d.ts +0 -0
- package/dist/{src/View → View}/MainView.d.ts +4 -3
- package/dist/{src/View → View}/ViewManager.d.ts +0 -0
- package/dist/{src/constants.d.ts → constants.d.ts} +5 -2
- package/dist/{src/index.d.ts → index.d.ts} +34 -6
- package/dist/index.es.js +41 -1
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +41 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/{src/typings.d.ts → typings.d.ts} +2 -2
- package/docs/advanced.md +53 -0
- package/docs/api.md +79 -6
- package/docs/concept.md +9 -0
- package/docs/replay.md +40 -0
- package/package.json +7 -8
- package/src/App/MagixEvent/index.ts +68 -0
- package/src/App/Storage/index.ts +89 -43
- package/src/App/Storage/typings.ts +4 -2
- package/src/AppContext.ts +61 -24
- package/src/AppListener.ts +28 -8
- package/src/AppManager.ts +244 -71
- package/src/AppProxy.ts +40 -29
- package/src/AttributesDelegate.ts +2 -2
- package/src/BoxManager.ts +33 -19
- package/src/BuiltinApps.ts +0 -1
- package/src/ContainerResizeObserver.ts +3 -3
- package/src/Cursor/Cursor.svelte +25 -21
- package/src/Cursor/Cursor.ts +25 -38
- package/src/Cursor/icons.ts +2 -0
- package/src/Cursor/index.ts +45 -139
- package/src/Helper.ts +12 -1
- package/src/Register/index.ts +32 -17
- package/src/Register/loader.ts +28 -13
- package/src/Register/storage.ts +6 -1
- package/src/Utils/AppCreateQueue.ts +54 -0
- package/src/Utils/Common.ts +35 -2
- package/src/Utils/RoomHacker.ts +44 -14
- package/src/View/MainView.ts +19 -12
- package/src/View/ViewManager.ts +1 -2
- package/src/constants.ts +6 -2
- package/src/image/laser-pointer-cursor.svg +17 -0
- package/src/index.ts +153 -35
- package/src/shim.d.ts +5 -0
- package/src/style.css +6 -1
- package/src/typings.ts +2 -2
- package/vite.config.js +8 -2
- package/dist/src/App/Storage/index.d.ts +0 -26
- package/dist/src/AppContext.d.ts +0 -46
- package/dist/src/Base/Context.d.ts +0 -12
- package/dist/src/Base/index.d.ts +0 -7
- package/dist/src/Utils/RoomHacker.d.ts +0 -3
- package/src/Base/Context.ts +0 -45
- package/src/Base/index.ts +0 -10
package/dist/style.css
CHANGED
@@ -1 +1 @@
|
|
1
|
-
.page-renderer-pages-container{position:relative;overflow:hidden}.page-renderer-page{position:absolute;top:0;left:0;will-change:transform;background-position:center;background-size:cover;background-repeat:no-repeat}.page-renderer-page-img{display:block;width:100%;height:auto;user-select:none}.netless-app-docs-viewer-static-scrollbar{position:absolute;top:0;right:0;z-index:2147483647;width:8px;min-height:30px;margin:0;padding:0;border:none;outline:none;border-radius:4px;background:rgba(68,78,96,.4);box-shadow:1px 1px 8px #ffffffb3;opacity:0;transition:background .4s,opacity .4s 3s,transform .2s;will-change:transform,height;user-select:none}.netless-app-docs-viewer-static-scrollbar.netless-app-docs-viewer-static-scrollbar-dragging{background:rgba(68,78,96,.6);opacity:1;transition:background .4s,opacity .4s 3s!important}.netless-app-docs-viewer-static-scrollbar:hover,.netless-app-docs-viewer-static-scrollbar:focus{background:rgba(68,78,96,.5)}.netless-app-docs-viewer-static-scrollbar:active{background:rgba(68,78,96,.6)}.netless-app-docs-viewer-content:hover .netless-app-docs-viewer-static-scrollbar{opacity:1;transition:background .4s,opacity .4s,transform .2s}.netless-app-docs-viewer-readonly .netless-app-docs-viewer-static-scrollbar{display:none}.netless-app-docs-viewer-static-pages:hover .netless-app-docs-viewer-static-scrollbar{opacity:1;transition:background .4s,opacity .4s,transform .2s}.netless-window-manager-playground{width:100%;height:100%;position:relative;z-index:1;overflow:hidden;user-select:none}.netless-window-manager-sizer{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;overflow:hidden;display:flex}.netless-window-manager-sizer-horizontal{flex-direction:column}.netless-window-manager-sizer:before,.netless-window-manager-sizer:after{flex:1;content:"";display:block}.netless-window-manager-chess-sizer:before,.netless-window-manager-chess-sizer:after{background-image:linear-gradient(45deg,#b0b0b0 25%,transparent 25%),linear-gradient(-45deg,#b0b0b0 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#b0b0b0 75%),linear-gradient(-45deg,transparent 75%,#b0b0b0 75%);background-color:#fff;background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px}.netless-window-manager-wrapper{position:relative;z-index:1;width:100%;height:100%;overflow:hidden}.netless-window-manager-main-view{width:100%;height:100%}.netless-window-manager-cursor-pencil-image{width:26px;height:26px}.netless-window-manager-cursor-eraser-image{width:26px;height:26px}.netless-window-manager-cursor-selector-image{width:24px;height:24px}.netless-window-manager-cursor-selector-avatar{border-radius:50%;border-style:solid;border-width:2px;border-color:#fff;margin-bottom:2px}.netless-window-manager-cursor-selector-avatar img{width:12px}.netless-window-manager-cursor-inner{border-radius:4px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:4px;padding-right:4px;font-size:12px}.netless-window-manager-cursor-inner-mellow{height:32px;border-radius:16px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:16px;padding-right:16px}.netless-window-manager-cursor-tag-name{font-size:12px;margin-left:4px;padding:2px 8px;border-radius:4px}.netless-window-manager-cursor-mid{display:flex;flex-direction:column;align-items:center;justify-content:center;position:absolute;width:26px;height:26px;z-index:2147483647;left:0;top:0;will-change:transform;transition:transform .05s;transform-origin:0 0;user-select:none}.netless-window-manager-cursor-pencil-offset{margin-left:-20px}.netless-window-manager-cursor-selector-offset{margin-left:-22px;margin-top:56px}.netless-window-manager-cursor-text-offset{margin-left:-30px;margin-top:18px}.netless-window-manager-cursor-shape-offset{display:flex;flex-direction:column;align-items:center;justify-content:center;position:absolute;width:180px;height:64px;margin-left:-30px;margin-top:12px}.netless-window-manager-cursor-name{width:100%;height:48px;display:flex;align-items:center;justify-content:center;position:absolute;top:-40px}.cursor-image-wrapper{display:flex;justify-content:center}.telebox-collector{position:absolute;right:10px;bottom:15px}.tele-fancy-scrollbar{overscroll-behavior:contain;overflow:auto;overflow-y:scroll;overflow-y:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.tele-fancy-scrollbar::-webkit-scrollbar{height:8px;width:8px}.tele-fancy-scrollbar::-webkit-scrollbar-track{background-color:transparent}.tele-fancy-scrollbar::-webkit-scrollbar-thumb{background-color:#444e601a;background-color:transparent;border-radius:4px;transition:background-color .4s}.tele-fancy-scrollbar:hover::-webkit-scrollbar-thumb{background-color:#444e601a}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:hover{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:active{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:vertical{min-height:50px}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-box{position:absolute;top:0;left:0;z-index:100;will-change:transform;transition:width .4s cubic-bezier(.4,.9,.71,1.02),height .4s cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .4s ease}.telebox-box-main{position:relative;width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden;background:#f9f9fc;box-shadow:0 4px 10px #2f419226;border-radius:6px;border:1px solid #e3e3ec}.telebox-titlebar-wrap{flex-shrink:0;position:relative;z-index:1}.telebox-content-wrap{flex:1;width:100%;overflow:hidden;display:flex;justify-content:center;align-items:center}.telebox-content{width:100%;height:100%;position:relative}.telebox-footer-wrap{flex-shrink:0;display:flex;flex-direction:column}.telebox-footer-wrap:before{content:"";display:block;flex:1}.telebox-resize-handle{position:absolute;z-index:2147483647}.telebox-n{width:100%;height:5px;left:0;top:-5px;cursor:n-resize}.telebox-s{width:100%;height:5px;left:0;bottom:-5px;cursor:s-resize}.telebox-w{width:5px;height:100%;left:-5px;top:0;cursor:w-resize}.telebox-e{width:5px;height:100%;right:-5px;top:0;cursor:e-resize}.telebox-nw{width:15px;height:15px;top:-5px;left:-5px;cursor:nw-resize}.telebox-ne{width:15px;height:15px;top:-5px;right:-5px;cursor:ne-resize}.telebox-se{width:15px;height:15px;bottom:-5px;right:-5px;cursor:se-resize}.telebox-sw{width:15px;height:15px;bottom:-5px;left:-5px;cursor:sw-resize}.telebox-track-mask{position:fixed;top:0;left:0;z-index:2147483647;width:100%;height:100%;background:rgba(0,0,0,.0001);cursor:move}.telebox-cursor-n{cursor:n-resize}.telebox-cursor-s{cursor:s-resize}.telebox-cursor-w{cursor:w-resize}.telebox-cursor-e{cursor:e-resize}.telebox-cursor-nw{cursor:nw-resize}.telebox-cursor-ne{cursor:ne-resize}.telebox-cursor-se{cursor:se-resize}.telebox-cursor-sw{cursor:sw-resize}.telebox-maximized .telebox-resize-handles,.telebox-no-resize .telebox-resize-handles{display:none}.telebox-maximized{box-shadow:none;transition:none}.telebox-minimized{will-change:transform;transition:width 50ms cubic-bezier(.4,.9,.71,1.02),height 50ms cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .6s ease;opacity:0;pointer-events:none;user-select:none}.telebox-transforming{will-change:transform;transition:opacity .6s cubic-bezier(.7,0,.84,0)}.telebox-readonly .telebox-resize-handle{cursor:initial!important;pointer-events:none!important}.telebox-color-scheme-dark .telebox-box-main{color:#e9e9e9;background:#212126;border-color:#43434d}.telebox-titlebar{box-sizing:border-box;height:26px;display:flex;align-items:center;padding:0 16px;background:#fff;user-select:none;border-bottom:1px solid #eeeef7}.telebox-title{overflow:hidden;margin:0 24px 0 0;padding:0;font-size:14px;font-weight:400;font-family:PingFangSC-Regular,PingFang SC;white-space:nowrap;word-break:keep-all;text-overflow:ellipsis;color:#191919}.telebox-titlebar-btns{white-space:nowrap;word-break:keep-all;margin-left:auto;font-size:0}.telebox-titlebar-btn{width:22px;height:22px;padding:0;outline:0;border:none;background:0 0;cursor:pointer}.telebox-titlebar-btn~.telebox-titlebar-btn{margin-left:10px}.telebox-titlebar-btn-icon{width:22px;height:22px}.telebox-readonly .telebox-titlebar-btn{cursor:not-allowed}.telebox-titlebar-icon-minimize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPHBhdGggZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBkPSJNOSAxM2gxMHYxLjZIOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-titlebar-icon-maximize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPGcgZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBtYXNrPSJ1cmwoI2IpIj4KICAgICAgICAgICAgPHBhdGgKICAgICAgICAgICAgICAgIGQ9Ik0yMC40ODEgMTcuMWgxLjJ2NC41ODFIMTcuMXYtMS4yaDMuMzgxVjE3LjF6bS0xNC4xOTA1LS4wMDloMS4ydjMuMzgxaDMuMzgwOXYxLjJoLTQuNTgxdi00LjU4MXpNMTcuMSA2LjE5MDVoNC41ODF2NC41ODA5aC0xLjJ2LTMuMzgxSDE3LjF2LTEuMnptLTEwLjcwMDguMTA4N2g0Ljc5ODV2MS4ySDcuNTk5MnYzLjU5ODVoLTEuMlY2LjI5OTJ6IiAvPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg==)}.telebox-titlebar-icon-maximize.is-active{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjZ2MjZIMHoiIC8+CiAgICAgICAgPHBhdGggaWQ9ImMiIGQ9Ik0yNi44NjkgMEwyOCAxLjEzMVYyNi44N0wyNi44NjkgMjhIMS4xM0wwIDI2Ljg3VjEuMTMxTDEuMTMgMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEgMSkiPgogICAgICAgICAgICA8bWFzayBpZD0iYiIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNhIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tNC42NDI5LTQuNjQyOWgzNS4yODU4djM1LjI4NThILTQuNjQyOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8bWFzayBpZD0iZCIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNjIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tMTcuNTE2OCAxNEwxNC0xNy41MTY4IDQ1LjUxNjggMTQgMTQgNDUuNTE2OHoiIG1hc2s9InVybCgjZCkiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxwYXRoIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjIiCiAgICAgICAgICAgIGQ9Ik0xMC4wODg2IDIxLjQ4NjV2LTMuNjk2Nkg2LjM5Mk0yMS4zODU1IDEwLjE4OTVoLTMuNjk2NlY2LjQ5M00yMS40MDIgMTcuNzk4M2gtMy42OTY2djMuNjk2Nk0xMC4yNTAzIDYuMTQ5OHYzLjg5ODVINi4zNTE3IiAvPgogICAgPC9nPgo8L3N2Zz4K)}.telebox-titlebar-icon-close{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAyOCI+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjQiPgogICAgICAgIDxwYXRoIGQ9Ik04LjM1MyAyMC4zMzIxTDIwLjMzMiA4LjM1M00yMC4zMzIyIDIwLjMzMjFMOC4zNTMgOC4zNTMiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-color-scheme-dark .telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-collector{visibility:hidden;display:block;position:absolute;z-index:200;width:40px;height:40px;margin:0;padding:0;border:none;outline:0;font-size:0;border-radius:50%;background:#fff;box-shadow:0 2px 6px #2f419226;cursor:pointer;user-select:none;pointer-events:none;background-repeat:no-repeat;background-size:18px 16px;background-position:center}.telebox-collector-visible{visibility:visible;pointer-events:initial}.telebox-collector-readonly{cursor:not-allowed}.telebox-color-scheme-dark.telebox-collector{background-color:#43434d}.telebox-max-titlebar{display:none;position:absolute;top:0;left:0;z-index:50000;user-select:none}.telebox-max-titlebar-maximized{display:flex}.telebox-titles{flex:1;height:100%;margin:0 16px 0 -16px;overflow-y:hidden;overflow-x:scroll;overflow-x:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.telebox-titles::-webkit-scrollbar{height:8px;width:8px}.telebox-titles::-webkit-scrollbar-track{background-color:transparent}.telebox-titles::-webkit-scrollbar-thumb{background-color:#eeeef7cc;background-color:transparent;border-radius:4px;transition:background-color .4s}.telebox-titles:hover::-webkit-scrollbar-thumb{background-color:#eeeef7cc}.telebox-titles::-webkit-scrollbar-thumb:hover{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:active{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:vertical{min-height:50px}.telebox-titles::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-titles-content{height:100%;display:flex;flex-wrap:nowrap;align-items:center;padding:0}.telebox-titles-tab{overflow:hidden;max-width:182px;min-width:50px;padding:0 26px 0 16px;outline:0;font-size:13px;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;text-overflow:ellipsis;white-space:nowrap;word-break:keep-all;border:none;border-right:1px solid #e5e5f0;color:#7b88a0;background:0 0;cursor:pointer}.telebox-titles-tab~.telebox-titles-tab{margin-left:2px}.telebox-titles-tab-focus{color:#357bf6}.telebox-readonly .telebox-titles-tab{cursor:not-allowed}.telebox-color-scheme-dark{color-scheme:dark}.telebox-color-scheme-dark.telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-color-scheme-dark .telebox-titles-tab{border-right-color:#7b88a0}.telebox-color-scheme-dark .telebox-title{color:#e9e9e9}
|
1
|
+
.netless-window-manager-playground{width:100%;height:100%;position:relative;z-index:1;overflow:hidden;user-select:none}.netless-window-manager-sizer{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1;overflow:hidden;display:flex}.netless-window-manager-sizer-horizontal{flex-direction:column}.netless-window-manager-sizer:before,.netless-window-manager-sizer:after{flex:1;content:"";display:block}.netless-window-manager-chess-sizer:before,.netless-window-manager-chess-sizer:after{background-image:linear-gradient(45deg,#b0b0b0 25%,transparent 25%),linear-gradient(-45deg,#b0b0b0 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#b0b0b0 75%),linear-gradient(-45deg,transparent 75%,#b0b0b0 75%);background-color:#fff;background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0px}.netless-window-manager-wrapper{position:relative;z-index:1;width:100%;height:100%;overflow:hidden}.netless-window-manager-main-view{width:100%;height:100%}.netless-window-manager-cursor-pencil-image{width:26px;height:26px}.netless-window-manager-cursor-eraser-image{width:26px;height:26px}.netless-window-manager-cursor-selector-image{width:24px;height:24px}.netless-window-manager-cursor-selector-avatar{border-radius:50%;border-style:solid;border-width:2px;border-color:#fff;margin-bottom:2px}.netless-window-manager-cursor-selector-avatar img{width:12px}.netless-window-manager-cursor-inner{border-radius:4px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:4px;padding-right:4px;font-size:12px}.netless-window-manager-cursor-inner-mellow{height:32px;border-radius:16px;display:flex;align-items:center;justify-content:center;flex-direction:row;padding-left:16px;padding-right:16px}.netless-window-manager-cursor-tag-name{font-size:12px;margin-left:4px;padding:2px 8px;border-radius:4px}.netless-window-manager-cursor-mid{display:flex;flex-direction:column;align-items:center;justify-content:center;position:absolute;width:26px;height:26px;z-index:2147483647;left:0;top:0;will-change:transform;transition:transform .1s;transform-origin:0 0;user-select:none}.netless-window-manager-cursor-pencil-offset{margin-left:-20px}.netless-window-manager-cursor-selector-offset{margin-left:-22px;margin-top:56px}.netless-window-manager-cursor-text-offset{margin-left:-30px;margin-top:18px}.netless-window-manager-cursor-shape-offset{display:flex;flex-direction:column;align-items:center;justify-content:center;position:absolute;width:180px;height:64px;margin-left:-30px;margin-top:12px}.netless-window-manager-cursor-laserPointer-image{margin-left:-22px;margin-top:3px}.netless-window-manager-cursor-name{width:100%;height:48px;display:flex;align-items:center;justify-content:center;position:absolute;top:-40px}.cursor-image-wrapper{display:flex;justify-content:center}.telebox-collector{position:absolute;right:10px;bottom:15px}.tele-fancy-scrollbar{overscroll-behavior:contain;overflow:auto;overflow-y:scroll;overflow-y:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.tele-fancy-scrollbar::-webkit-scrollbar{height:8px;width:8px}.tele-fancy-scrollbar::-webkit-scrollbar-track{background-color:transparent}.tele-fancy-scrollbar::-webkit-scrollbar-thumb{background-color:#444e601a;background-color:transparent;border-radius:4px;transition:background-color .4s}.tele-fancy-scrollbar:hover::-webkit-scrollbar-thumb{background-color:#444e601a}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:hover{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:active{background-color:#444e6033}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:vertical{min-height:50px}.tele-fancy-scrollbar::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-box{position:absolute;top:0;left:0;z-index:100;transition:width .4s cubic-bezier(.4,.9,.71,1.02),height .4s cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .4s ease}.telebox-box-main{position:relative;width:100%;height:100%;display:flex;flex-direction:column;overflow:hidden;background:#f9f9fc;box-shadow:0 4px 10px #2f419226;border-radius:6px;border:1px solid #e3e3ec}.telebox-titlebar-wrap{flex-shrink:0;position:relative;z-index:1}.telebox-content-wrap{flex:1;width:100%;overflow:hidden;display:flex;justify-content:center;align-items:center}.telebox-content{width:100%;height:100%;position:relative}.telebox-footer-wrap{flex-shrink:0;display:flex;flex-direction:column}.telebox-footer-wrap:before{content:"";display:block;flex:1}.telebox-resize-handle{position:absolute;z-index:2147483647}.telebox-n{width:100%;height:5px;left:0;top:-5px;cursor:n-resize}.telebox-s{width:100%;height:5px;left:0;bottom:-5px;cursor:s-resize}.telebox-w{width:5px;height:100%;left:-5px;top:0;cursor:w-resize}.telebox-e{width:5px;height:100%;right:-5px;top:0;cursor:e-resize}.telebox-nw{width:15px;height:15px;top:-5px;left:-5px;cursor:nw-resize}.telebox-ne{width:15px;height:15px;top:-5px;right:-5px;cursor:ne-resize}.telebox-se{width:15px;height:15px;bottom:-5px;right:-5px;cursor:se-resize}.telebox-sw{width:15px;height:15px;bottom:-5px;left:-5px;cursor:sw-resize}.telebox-track-mask{position:fixed;top:0;left:0;z-index:2147483647;width:100%;height:100%;background:rgba(0,0,0,.0001);cursor:move}.telebox-cursor-n{cursor:n-resize}.telebox-cursor-s{cursor:s-resize}.telebox-cursor-w{cursor:w-resize}.telebox-cursor-e{cursor:e-resize}.telebox-cursor-nw{cursor:nw-resize}.telebox-cursor-ne{cursor:ne-resize}.telebox-cursor-se{cursor:se-resize}.telebox-cursor-sw{cursor:sw-resize}.telebox-maximized .telebox-resize-handles,.telebox-no-resize .telebox-resize-handles{display:none}.telebox-maximized{box-shadow:none;transition:none}.telebox-minimized{transition:width 50ms cubic-bezier(.4,.9,.71,1.02),height 50ms cubic-bezier(.55,.82,.63,.95),opacity .6s cubic-bezier(.7,0,.84,0),transform .6s ease;opacity:0;pointer-events:none;user-select:none}.telebox-transforming{will-change:transform;transition:opacity .6s cubic-bezier(.7,0,.84,0)}.telebox-readonly .telebox-resize-handle{cursor:initial!important;pointer-events:none!important}.telebox-color-scheme-dark .telebox-box-main{color:#e9e9e9;background:#212126;border-color:#43434d}.telebox-titlebar{box-sizing:border-box;height:26px;display:flex;align-items:center;padding:0 16px;background:#fff;user-select:none;border-bottom:1px solid #eeeef7;touch-action:manipulation}.telebox-title-area{overflow:hidden;position:relative;height:100%;flex:1;display:flex;align-items:center}.telebox-title{overflow:hidden;margin:0;padding:0;font-size:14px;font-weight:400;font-family:PingFangSC-Regular,PingFang SC;white-space:nowrap;word-break:keep-all;text-overflow:ellipsis;color:#191919}.telebox-drag-area{position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;z-index:10}.telebox-titlebar-btns{white-space:nowrap;word-break:keep-all;margin-left:auto;font-size:0}.telebox-titlebar-btn{width:22px;height:22px;padding:0;outline:0;border:none;background:0 0;cursor:pointer}.telebox-titlebar-btn~.telebox-titlebar-btn{margin-left:10px}.telebox-titlebar-btn-icon{width:22px;height:22px}.telebox-readonly .telebox-titlebar-btn{cursor:not-allowed}.telebox-titlebar-icon-minimize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPHBhdGggZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBkPSJNOSAxM2gxMHYxLjZIOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-titlebar-icon-maximize{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjh2MjhIMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxtYXNrIGlkPSJiIiBmaWxsPSIjZmZmIj4KICAgICAgICAgICAgPHVzZSB4bGluazpocmVmPSIjYSIgLz4KICAgICAgICA8L21hc2s+CiAgICAgICAgPGcgZmlsbD0iI0E3QTdDQSIgZmlsbC1ydWxlPSJub256ZXJvIiBtYXNrPSJ1cmwoI2IpIj4KICAgICAgICAgICAgPHBhdGgKICAgICAgICAgICAgICAgIGQ9Ik0yMC40ODEgMTcuMWgxLjJ2NC41ODFIMTcuMXYtMS4yaDMuMzgxVjE3LjF6bS0xNC4xOTA1LS4wMDloMS4ydjMuMzgxaDMuMzgwOXYxLjJoLTQuNTgxdi00LjU4MXpNMTcuMSA2LjE5MDVoNC41ODF2NC41ODA5aC0xLjJ2LTMuMzgxSDE3LjF2LTEuMnptLTEwLjcwMDguMTA4N2g0Ljc5ODV2MS4ySDcuNTk5MnYzLjU5ODVoLTEuMlY2LjI5OTJ6IiAvPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+Cg==)}.telebox-titlebar-icon-maximize.is-active{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjggMjgiPgogICAgPGRlZnM+CiAgICAgICAgPHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMjZ2MjZIMHoiIC8+CiAgICAgICAgPHBhdGggaWQ9ImMiIGQ9Ik0yNi44NjkgMEwyOCAxLjEzMVYyNi44N0wyNi44NjkgMjhIMS4xM0wwIDI2Ljg3VjEuMTMxTDEuMTMgMHoiIC8+CiAgICA8L2RlZnM+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEgMSkiPgogICAgICAgICAgICA8bWFzayBpZD0iYiIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNhIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tNC42NDI5LTQuNjQyOWgzNS4yODU4djM1LjI4NThILTQuNjQyOXoiIG1hc2s9InVybCgjYikiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxnPgogICAgICAgICAgICA8bWFzayBpZD0iZCIgZmlsbD0iI2ZmZiI+CiAgICAgICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNjIiAvPgogICAgICAgICAgICA8L21hc2s+CiAgICAgICAgICAgIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0tMTcuNTE2OCAxNEwxNC0xNy41MTY4IDQ1LjUxNjggMTQgMTQgNDUuNTE2OHoiIG1hc2s9InVybCgjZCkiIC8+CiAgICAgICAgPC9nPgogICAgICAgIDxwYXRoIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjIiCiAgICAgICAgICAgIGQ9Ik0xMC4wODg2IDIxLjQ4NjV2LTMuNjk2Nkg2LjM5Mk0yMS4zODU1IDEwLjE4OTVoLTMuNjk2NlY2LjQ5M00yMS40MDIgMTcuNzk4M2gtMy42OTY2djMuNjk2Nk0xMC4yNTAzIDYuMTQ5OHYzLjg5ODVINi4zNTE3IiAvPgogICAgPC9nPgo8L3N2Zz4K)}.telebox-titlebar-icon-close{background:center/cover no-repeat url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOCAyOCI+CiAgICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iI0E3QTdDQSIgc3Ryb2tlLXdpZHRoPSIxLjQiPgogICAgICAgIDxwYXRoIGQ9Ik04LjM1MyAyMC4zMzIxTDIwLjMzMiA4LjM1M00yMC4zMzIyIDIwLjMzMjFMOC4zNTMgOC4zNTMiIC8+CiAgICA8L2c+Cjwvc3ZnPgo=)}.telebox-color-scheme-dark .telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-collector{visibility:hidden;display:block;position:absolute;z-index:200;width:40px;height:40px;margin:0;padding:0;border:none;outline:0;font-size:0;border-radius:50%;background:#fff;box-shadow:0 2px 6px #2f419226;cursor:pointer;user-select:none;pointer-events:none;background-repeat:no-repeat;background-size:18px 16px;background-position:center}.telebox-collector-visible{visibility:visible;pointer-events:initial}.telebox-collector-readonly{cursor:not-allowed}.telebox-color-scheme-dark.telebox-collector{background-color:#43434d}.telebox-max-titlebar{display:none;position:absolute;top:0;left:0;z-index:50000;user-select:none}.telebox-max-titlebar .telebox-drag-area{height:100%;min-width:16px;position:static;margin:0;flex-grow:1;flex-shrink:0}.telebox-max-titlebar-maximized{display:flex}.telebox-titles{height:100%;margin:0;overflow-y:hidden;overflow-x:scroll;overflow-x:overlay;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;scrollbar-width:auto}.telebox-titles::-webkit-scrollbar{height:8px;width:8px}.telebox-titles::-webkit-scrollbar-track{background-color:transparent}.telebox-titles::-webkit-scrollbar-thumb{background-color:#eeeef7cc;background-color:transparent;border-radius:4px;transition:background-color .4s}.telebox-titles:hover::-webkit-scrollbar-thumb{background-color:#eeeef7cc}.telebox-titles::-webkit-scrollbar-thumb:hover{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:active{background-color:#eeeef7}.telebox-titles::-webkit-scrollbar-thumb:vertical{min-height:50px}.telebox-titles::-webkit-scrollbar-thumb:horizontal{min-width:50px}.telebox-titles-content{height:100%;display:flex;flex-wrap:nowrap;align-items:center;padding:0}.telebox-titles-tab{height:100%;overflow:hidden;max-width:182px;min-width:50px;padding:0 26px 0 16px;outline:0;font-size:13px;font-family:PingFangSC-Regular,PingFang SC;font-weight:400;text-overflow:ellipsis;white-space:nowrap;word-break:keep-all;border:none;border-right:1px solid #e5e5f0;color:#7b88a0;background:0 0;cursor:pointer;user-select:none}.telebox-titles-tab-focus{color:#357bf6}.telebox-readonly .telebox-titles-tab{cursor:not-allowed}.telebox-color-scheme-dark{color-scheme:dark}.telebox-color-scheme-dark.telebox-titlebar{color:#e9e9e9;background:#43434d;border-bottom:none}.telebox-color-scheme-dark .telebox-titles-tab{border-right-color:#7b88a0}.telebox-color-scheme-dark .telebox-title{color:#e9e9e9}
|
@@ -2,7 +2,7 @@ import type Emittery from "emittery";
|
|
2
2
|
import type { AnimationMode, Displayer, DisplayerState, Player, Room, SceneDefinition, SceneState, View } from "white-web-sdk";
|
3
3
|
import type { AppContext } from "./AppContext";
|
4
4
|
import type { ReadonlyTeleBox, TeleBoxRect } from "@netless/telebox-insider";
|
5
|
-
export interface NetlessApp<Attributes = any,
|
5
|
+
export interface NetlessApp<Attributes = any, MagixEventPayloads = any, AppOptions = any, SetupResult = any> {
|
6
6
|
kind: string;
|
7
7
|
config?: {
|
8
8
|
/** Box width relative to whiteboard. 0~1. Default 0.5. */
|
@@ -16,7 +16,7 @@ export interface NetlessApp<Attributes = any, SetupResult = any, AppOptions = an
|
|
16
16
|
/** App only single instance. */
|
17
17
|
singleton?: boolean;
|
18
18
|
};
|
19
|
-
setup: (context: AppContext<Attributes, AppOptions>) => SetupResult;
|
19
|
+
setup: (context: AppContext<Attributes, MagixEventPayloads, AppOptions>) => SetupResult;
|
20
20
|
}
|
21
21
|
export declare type AppEmitterEvent<T = any> = {
|
22
22
|
/**
|
package/docs/advanced.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
## 进阶使用
|
2
|
+
|
3
|
+
- 目录
|
4
|
+
- [撤销重做](#redo-undo)
|
5
|
+
- [清屏](#clean-current-scene)
|
6
|
+
|
7
|
+
|
8
|
+
<h3 id="redo-undo">撤销重做</h3>
|
9
|
+
|
10
|
+
> 以下事件和属性都会根据 `focus` 的窗口来进行自动切换应用对象
|
11
|
+
|
12
|
+
#### 获取可以撤销/重做的步数
|
13
|
+
|
14
|
+
```ts
|
15
|
+
manager.canUndoSteps
|
16
|
+
manager.canRedoSteps
|
17
|
+
```
|
18
|
+
|
19
|
+
#### 监听可以撤销/重做的步数的变化
|
20
|
+
|
21
|
+
`canRedoStepsChange` 和 `canUndoStepsChange` 会在切换窗口时重新触发
|
22
|
+
|
23
|
+
```ts
|
24
|
+
manager.emitter.on("canUndoStepsChange", (steps: number) => {
|
25
|
+
// 可以撤销的步数更新
|
26
|
+
})
|
27
|
+
manager.emitter.on("canRedoStepsChange", (steps: number) => {
|
28
|
+
// 可以重做的步数更新
|
29
|
+
})
|
30
|
+
```
|
31
|
+
|
32
|
+
#### 撤销/重做
|
33
|
+
|
34
|
+
```ts
|
35
|
+
manager.undo() //撤销
|
36
|
+
manager.redo() // 重做
|
37
|
+
```
|
38
|
+
|
39
|
+
<br>
|
40
|
+
|
41
|
+
<h3 id="clean-current-scene">清屏</h3>
|
42
|
+
|
43
|
+
因为在多窗口模式下有多个白板, 如果想要清除当前 `focus` 的白板只需要调用
|
44
|
+
|
45
|
+
```ts
|
46
|
+
manager.cleanCurrentScene()
|
47
|
+
```
|
48
|
+
|
49
|
+
只想清理主白板的笔迹则需要
|
50
|
+
|
51
|
+
```ts
|
52
|
+
manager.mainView.cleanCurrentScene()
|
53
|
+
```
|
package/docs/api.md
CHANGED
@@ -9,9 +9,16 @@
|
|
9
9
|
- [实例方法](#instance-methods)
|
10
10
|
- [`addApp`](#addApp)
|
11
11
|
- [`closeApp`](#closeApp)
|
12
|
+
- [`setMainViewSceneIndex`](#setMainViewSceneIndex)
|
13
|
+
- [`setBoxState`](#setBoxState)
|
14
|
+
- [`cleanCurrentScene`](#cleanCurrentScene)
|
15
|
+
- [`redo`](#redo)
|
16
|
+
- [`undo`](#undo)
|
12
17
|
- [实例属性](#prototypes)
|
13
18
|
- [事件回调](#events)
|
14
19
|
|
20
|
+
<br>
|
21
|
+
|
15
22
|
<h2 id="static-methods">静态方法</h2>
|
16
23
|
|
17
24
|
<h3 id="mount">WindowManager.mount</h3>
|
@@ -42,6 +49,7 @@ const manager = await WindowManager.mount(
|
|
42
49
|
| prefersColorScheme | [optional] string | light | auto, light, dark |
|
43
50
|
| debug | [optional] boolean | false | 打印日志信息
|
44
51
|
|
52
|
+
|
45
53
|
<h3 id="register">WindowManager.register</h3>
|
46
54
|
|
47
55
|
> 注册 `APP` 到 `WindowManager`
|
@@ -81,6 +89,8 @@ WindowManager.setContainer(document.getElementById("container"));
|
|
81
89
|
WindowManager.setCollectorContainer(document.getElementById("collector-container"));
|
82
90
|
```
|
83
91
|
|
92
|
+
<br>
|
93
|
+
|
84
94
|
<h2 id="instance-methods">实例方法</h2>
|
85
95
|
|
86
96
|
<h3 id="addApp">addApp</h3>
|
@@ -105,15 +115,63 @@ const appId = await manager.addApp({
|
|
105
115
|
manager.closeApp(appId)
|
106
116
|
```
|
107
117
|
|
118
|
+
<h3 id="setMainViewSceneIndex">setMainViewSceneIndex</h3>
|
119
|
+
|
120
|
+
> 设置主白板的 `SceneIndex`
|
121
|
+
|
122
|
+
```ts
|
123
|
+
manager.setMainViewSceneIndex(1)
|
124
|
+
```
|
125
|
+
|
126
|
+
<h3 id="setBoxState">setBoxState</h3>
|
127
|
+
|
128
|
+
> 设置当前的 `boxState`
|
129
|
+
|
130
|
+
```ts
|
131
|
+
manager.setBoxState("normal") // boxState: normal | maximized | minimized
|
132
|
+
```
|
133
|
+
|
134
|
+
<h3 id="cleanCurrentScene">cleanCurrentScene</h3>
|
135
|
+
|
136
|
+
> 清除当前 focus 的 view 的笔迹
|
137
|
+
|
138
|
+
```ts
|
139
|
+
manager.cleanCurrentScene()
|
140
|
+
```
|
141
|
+
|
142
|
+
<h3 id="redo">redo</h3>
|
143
|
+
|
144
|
+
> 在当前 focus 的 view 上重做上一步操作
|
145
|
+
|
146
|
+
```ts
|
147
|
+
manager.redo()
|
148
|
+
```
|
149
|
+
|
150
|
+
<h3 id="undo">undo</h3>
|
151
|
+
|
152
|
+
> 在当前 focus 的 view 上撤消上一步操作
|
153
|
+
|
154
|
+
```ts
|
155
|
+
manager.undo()
|
156
|
+
```
|
157
|
+
|
158
|
+
<br>
|
159
|
+
|
108
160
|
<h2 id="prototypes">实例属性</h2>
|
109
161
|
|
110
|
-
| name | type | default | desc
|
111
|
-
| ------------------ | ------- | ------- |
|
112
|
-
| mainView | View | | 主白板
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
162
|
+
| name | type | default | desc |
|
163
|
+
| ------------------ | ------- | ------- | ----------------- |
|
164
|
+
| mainView | View | | 主白板 |
|
165
|
+
| mainViewSceneIndex | number | | 当前主白板的 SceneIndex |
|
166
|
+
| mainViewScenesLength | number | | mainView 的 scenes 长度 |
|
167
|
+
| boxState | string | | 当前窗口状态 |
|
168
|
+
| darkMode | boolean | | 黑夜模式 |
|
169
|
+
| prefersColorScheme | string | | 颜色主题 |
|
170
|
+
| focused | string | | focus 的 app |
|
171
|
+
| canRedoSteps | number | | 当前 focus 的 view 可以重做的步数 |
|
172
|
+
| canRedoSteps | number | | 当前 focus 的 view 可以撤销的步数 |
|
116
173
|
|
174
|
+
<br>
|
117
175
|
|
118
176
|
<h2 id="events">事件回调</h2>
|
119
177
|
|
@@ -124,7 +182,22 @@ manager.callbacks.on(events, listener)
|
|
124
182
|
| name | type | default | desc |
|
125
183
|
| ------------------------ | -------------- | ------- | -------------------------- |
|
126
184
|
| mainViewModeChange | ViewVisionMode | | |
|
185
|
+
| mainViewSceneIndexChange | index: number | | |
|
127
186
|
| boxStateChange | string | | normal,minimized,maximized |
|
128
187
|
| darkModeChange | boolean | | |
|
129
188
|
| prefersColorSchemeChange | string | | auto,light,dark |
|
130
189
|
| cameraStateChange | CameraState | | |
|
190
|
+
| focusedChange | string, undefined | | 当前 focus 的 appId,主白板时为 undefined |
|
191
|
+
| mainViewScenesLengthChange | number | | mainView scenes 添加或删除时触发 |
|
192
|
+
| canRedoStepsChange | number | | 当前 focus 的 view 可重做步数改变 |
|
193
|
+
| canUndoStepsChange | number | | 当前 focus 的 view 可撤销步数改变 |
|
194
|
+
| loadApp | LoadAppEvent | | 加载远程APP 事件 |
|
195
|
+
|
196
|
+
|
197
|
+
```ts
|
198
|
+
type LoadAppEvent = {
|
199
|
+
kind: string;
|
200
|
+
status: "start" | "success" | "failed";
|
201
|
+
reason?: string;
|
202
|
+
}
|
203
|
+
```
|
package/docs/concept.md
ADDED
package/docs/replay.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
## 回放
|
2
|
+
|
3
|
+
> 注意: 多窗口的回放只支持从创建房间开始就是多窗口的房间
|
4
|
+
|
5
|
+
> 如果是一开始作为单窗口模式使用,又转变成多窗口模式使用, 则会造成回放渲染空白
|
6
|
+
|
7
|
+
<br>
|
8
|
+
|
9
|
+
|
10
|
+
```typescript
|
11
|
+
import { WhiteWebSdk } from "white-web-sdk";
|
12
|
+
import { WindowManager, BuiltinApps } from "@netless/window-manager";
|
13
|
+
import "@netless/window-manager/dist/style.css";
|
14
|
+
|
15
|
+
const sdk = new WhiteWebSdk({
|
16
|
+
appIdentifier: "appIdentifier",
|
17
|
+
useMobXState: true // 请确保打开这个选项
|
18
|
+
});
|
19
|
+
|
20
|
+
let manager: WindowManager;
|
21
|
+
|
22
|
+
sdk.replayRoom({
|
23
|
+
uuid: "room uuid",
|
24
|
+
roomToken: "room token",
|
25
|
+
invisiblePlugins: [WindowManager],
|
26
|
+
useMultiViews: true, // 多窗口必须用开启 useMultiViews
|
27
|
+
}).then(player => {
|
28
|
+
player.callbacks.on("onPhaseChanged", async (phase) => {
|
29
|
+
if (phase === PlayerPhase.Playing) {
|
30
|
+
if (manager) return;
|
31
|
+
manager = await WindowManager.mount({
|
32
|
+
room: player,
|
33
|
+
container: document.getElementById("container")
|
34
|
+
});
|
35
|
+
}
|
36
|
+
})
|
37
|
+
});
|
38
|
+
|
39
|
+
player.play(); // WindowManager 只有在播放之后才能挂载
|
40
|
+
```
|
package/package.json
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
{
|
2
2
|
"name": "@netless/window-manager",
|
3
|
-
"version": "0.4.
|
3
|
+
"version": "0.4.1-canary.0",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/index.es.js",
|
6
6
|
"module": "dist/index.es.js",
|
7
7
|
"types": "dist/index.d.ts",
|
8
|
+
"repository": "netless-io/window-manager",
|
8
9
|
"scripts": {
|
9
10
|
"prettier": "prettier --write .",
|
10
11
|
"build": "vite build && yarn type-gen",
|
@@ -17,14 +18,10 @@
|
|
17
18
|
"author": "",
|
18
19
|
"license": "ISC",
|
19
20
|
"peerDependencies": {
|
20
|
-
"
|
21
|
-
"white-web-sdk": "^2.13.16"
|
21
|
+
"white-web-sdk": "^2.16.0"
|
22
22
|
},
|
23
23
|
"dependencies": {
|
24
24
|
"@juggle/resize-observer": "^3.3.1",
|
25
|
-
"@netless/app-docs-viewer": "0.2.0",
|
26
|
-
"@netless/app-media-player": "0.1.0-beta.5",
|
27
|
-
"@netless/telebox-insider": "0.2.18",
|
28
25
|
"emittery": "^0.9.2",
|
29
26
|
"lodash": "^4.17.21",
|
30
27
|
"p-retry": "^4.6.1",
|
@@ -33,6 +30,9 @@
|
|
33
30
|
"video.js": ">=7"
|
34
31
|
},
|
35
32
|
"devDependencies": {
|
33
|
+
"@netless/app-docs-viewer": "^0.2.6",
|
34
|
+
"@netless/app-media-player": "0.1.0-beta.5",
|
35
|
+
"@netless/telebox-insider": "0.2.22",
|
36
36
|
"@rollup/plugin-commonjs": "^20.0.0",
|
37
37
|
"@rollup/plugin-node-resolve": "^13.0.4",
|
38
38
|
"@rollup/plugin-url": "^6.1.0",
|
@@ -55,8 +55,7 @@
|
|
55
55
|
"rollup-plugin-styles": "^3.14.1",
|
56
56
|
"svelte": "^3.42.4",
|
57
57
|
"typescript": "^4.3.5",
|
58
|
-
"video.js": "^7.14.3",
|
59
58
|
"vite": "^2.5.3",
|
60
|
-
"white-web-sdk": "
|
59
|
+
"white-web-sdk": "2.16.3"
|
61
60
|
}
|
62
61
|
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import type {
|
2
|
+
MagixEventListenerOptions as WhiteMagixListenerOptions,
|
3
|
+
Event as WhiteEvent,
|
4
|
+
EventPhase as WhiteEventPhase,
|
5
|
+
Scope as WhiteScope,
|
6
|
+
} from "white-web-sdk";
|
7
|
+
|
8
|
+
export interface MagixEventListenerOptions extends WhiteMagixListenerOptions {
|
9
|
+
/**
|
10
|
+
* Rapid emitted callbacks will be slowed down to this interval (in ms).
|
11
|
+
*/
|
12
|
+
fireInterval?: number;
|
13
|
+
/**
|
14
|
+
* If `true`, sent events will reach self-listeners after committed to server.
|
15
|
+
* Otherwise the events will reach self-listeners immediately.
|
16
|
+
*/
|
17
|
+
fireSelfEventAfterCommit?: boolean;
|
18
|
+
}
|
19
|
+
|
20
|
+
export interface MagixEventMessage<
|
21
|
+
TPayloads = any,
|
22
|
+
TEvent extends MagixEventTypes<TPayloads> = MagixEventTypes<TPayloads>
|
23
|
+
> extends Omit<WhiteEvent, "scope" | "phase"> {
|
24
|
+
/** Event name */
|
25
|
+
event: TEvent;
|
26
|
+
/** Event Payload */
|
27
|
+
payload: TPayloads[TEvent];
|
28
|
+
/** Whiteboard ID of the client who dispatched the event. It will be AdminObserverId for system events. */
|
29
|
+
authorId: number;
|
30
|
+
scope: `${WhiteScope}`;
|
31
|
+
phase: `${WhiteEventPhase}`;
|
32
|
+
}
|
33
|
+
|
34
|
+
export type MagixEventTypes<TPayloads = any> = Extract<keyof TPayloads, string>;
|
35
|
+
|
36
|
+
export type MagixEventPayload<
|
37
|
+
TPayloads = any,
|
38
|
+
TEvent extends MagixEventTypes<TPayloads> = MagixEventTypes<TPayloads>
|
39
|
+
> = TPayloads[TEvent];
|
40
|
+
|
41
|
+
export type MagixEventDispatcher<TPayloads = any> = <
|
42
|
+
TEvent extends MagixEventTypes<TPayloads> = MagixEventTypes<TPayloads>
|
43
|
+
>(
|
44
|
+
event: TEvent,
|
45
|
+
payload: TPayloads[TEvent]
|
46
|
+
) => void;
|
47
|
+
|
48
|
+
export type MagixEventHandler<
|
49
|
+
TPayloads = any,
|
50
|
+
TEvent extends MagixEventTypes<TPayloads> = MagixEventTypes<TPayloads>
|
51
|
+
> = (message: MagixEventMessage<TPayloads, TEvent>) => void;
|
52
|
+
|
53
|
+
export type MagixEventListenerDisposer = () => void
|
54
|
+
|
55
|
+
export type MagixEventAddListener<TPayloads = any> = <
|
56
|
+
TEvent extends MagixEventTypes<TPayloads> = MagixEventTypes<TPayloads>
|
57
|
+
>(
|
58
|
+
event: TEvent,
|
59
|
+
handler: MagixEventHandler<TPayloads, TEvent>,
|
60
|
+
options?: MagixEventListenerOptions | undefined
|
61
|
+
) => MagixEventListenerDisposer;
|
62
|
+
|
63
|
+
export type MagixEventRemoveListener<TPayloads = any> = <
|
64
|
+
TEvent extends MagixEventTypes<TPayloads> = MagixEventTypes<TPayloads>
|
65
|
+
>(
|
66
|
+
event: TEvent,
|
67
|
+
handler?: MagixEventHandler<TPayloads, TEvent>
|
68
|
+
) => void;
|
package/src/App/Storage/index.ts
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
import type { AkkoObjectUpdatedProperty } from "white-web-sdk";
|
2
|
-
import { get, has, isObject } from "lodash";
|
2
|
+
import { get, has, mapValues, isObject, size, noop } from "lodash";
|
3
3
|
import { SideEffectManager } from "side-effect-manager";
|
4
4
|
import type { AppContext } from "../../AppContext";
|
5
5
|
import { safeListenPropsUpdated } from "../../Utils/Reactive";
|
6
6
|
import { isRef, makeRef, plainObjectKeys } from "./utils";
|
7
|
-
import type { Diff, MaybeRefValue, RefValue, StorageStateChangedEvent } from "./typings";
|
7
|
+
import type { Diff, MaybeRefValue, RefValue, StorageStateChangedEvent, StorageStateChangedListener, StorageStateChangedListenerDisposer } from "./typings";
|
8
8
|
import { StorageEvent } from "./StorageEvent";
|
9
9
|
|
10
10
|
export * from './typings';
|
11
11
|
|
12
|
-
const STORAGE_NS = "_WM-STORAGE_";
|
12
|
+
export const STORAGE_NS = "_WM-STORAGE_";
|
13
13
|
|
14
|
-
export class Storage<TState = any> implements Storage<TState> {
|
15
|
-
readonly id: string;
|
14
|
+
export class Storage<TState extends Record<string, any> = any> implements Storage<TState> {
|
15
|
+
readonly id: string | null;
|
16
16
|
|
17
|
-
private readonly _context: AppContext
|
17
|
+
private readonly _context: AppContext;
|
18
18
|
private readonly _sideEffect = new SideEffectManager();
|
19
19
|
private _state: TState;
|
20
20
|
private _destroyed = false;
|
@@ -26,54 +26,52 @@ export class Storage<TState = any> implements Storage<TState> {
|
|
26
26
|
*/
|
27
27
|
private _lastValue = new Map<string | number | symbol, TState[Extract<keyof TState, string>]>();
|
28
28
|
|
29
|
-
constructor(context: AppContext
|
30
|
-
if (id == null) {
|
31
|
-
throw new Error("Cannot create Storage with empty id.");
|
32
|
-
}
|
33
|
-
|
29
|
+
constructor(context: AppContext, id?: string, defaultState?: TState) {
|
34
30
|
if (defaultState && !isObject(defaultState)) {
|
35
31
|
throw new Error(`Default state for Storage ${id} is not an object.`);
|
36
32
|
}
|
37
33
|
|
38
34
|
this._context = context;
|
39
|
-
this.id = id;
|
35
|
+
this.id = id || null;
|
40
36
|
|
41
|
-
const attrs = context.getAttributes();
|
42
37
|
this._state = {} as TState;
|
43
|
-
const rawState =
|
38
|
+
const rawState = this._getRawState(this._state);
|
44
39
|
|
45
|
-
if (this._context.getIsWritable()) {
|
46
|
-
if (
|
47
|
-
if (!
|
40
|
+
if (this.id !== null && this._context.getIsWritable()) {
|
41
|
+
if (rawState === this._state || !isObject(rawState)) {
|
42
|
+
if (!get(this._context.getAttributes(), [STORAGE_NS])) {
|
48
43
|
this._context.updateAttributes([STORAGE_NS], {});
|
49
44
|
}
|
50
45
|
this._context.updateAttributes([STORAGE_NS, this.id], this._state);
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
} else {
|
55
|
-
// strip mobx
|
56
|
-
plainObjectKeys(rawState).forEach(key => {
|
57
|
-
try {
|
58
|
-
const rawValue = isObject(rawState[key]) ? JSON.parse(JSON.stringify(rawState[key])) : rawState[key];
|
59
|
-
if (isRef<TState[Extract<keyof TState, string>]>(rawValue)) {
|
60
|
-
this._state[key] = rawValue.v;
|
61
|
-
if (isObject(rawValue.v)) {
|
62
|
-
this._refMap.set(rawValue.v, rawValue);
|
63
|
-
}
|
64
|
-
} else {
|
65
|
-
this._state[key] = rawValue;
|
66
|
-
}
|
67
|
-
} catch (e) {
|
68
|
-
console.error(e);
|
69
|
-
}
|
70
|
-
});
|
46
|
+
}
|
47
|
+
if (defaultState) {
|
48
|
+
this.setState(defaultState);
|
71
49
|
}
|
72
50
|
}
|
73
51
|
|
52
|
+
// strip mobx
|
53
|
+
plainObjectKeys(rawState).forEach(key => {
|
54
|
+
if (this.id === null && key === STORAGE_NS) {
|
55
|
+
return;
|
56
|
+
}
|
57
|
+
try {
|
58
|
+
const rawValue = isObject(rawState[key]) ? JSON.parse(JSON.stringify(rawState[key])) : rawState[key];
|
59
|
+
if (isRef<TState[Extract<keyof TState, string>]>(rawValue)) {
|
60
|
+
this._state[key] = rawValue.v;
|
61
|
+
if (isObject(rawValue.v)) {
|
62
|
+
this._refMap.set(rawValue.v, rawValue);
|
63
|
+
}
|
64
|
+
} else {
|
65
|
+
this._state[key] = rawValue;
|
66
|
+
}
|
67
|
+
} catch (e) {
|
68
|
+
console.error(e);
|
69
|
+
}
|
70
|
+
});
|
71
|
+
|
74
72
|
this._sideEffect.addDisposer(
|
75
73
|
safeListenPropsUpdated(
|
76
|
-
() => get(context.getAttributes(), [STORAGE_NS, this.id]),
|
74
|
+
() => this.id === null ? context.getAttributes() : get(context.getAttributes(), [STORAGE_NS, this.id]),
|
77
75
|
this._updateProperties.bind(this),
|
78
76
|
this.destroy.bind(this)
|
79
77
|
)
|
@@ -88,6 +86,11 @@ export class Storage<TState = any> implements Storage<TState> {
|
|
88
86
|
}
|
89
87
|
|
90
88
|
readonly onStateChanged = new StorageEvent<StorageStateChangedEvent<TState>>();
|
89
|
+
|
90
|
+
addStateChangedListener(handler: StorageStateChangedListener<TState>): StorageStateChangedListenerDisposer {
|
91
|
+
this.onStateChanged.addListener(handler);
|
92
|
+
return () => this.onStateChanged.removeListener(handler);
|
93
|
+
}
|
91
94
|
|
92
95
|
ensureState(state: Partial<TState>): void {
|
93
96
|
return this.setState(
|
@@ -122,7 +125,7 @@ export class Storage<TState = any> implements Storage<TState> {
|
|
122
125
|
if (value === void 0) {
|
123
126
|
this._lastValue.set(key, this._state[key]);
|
124
127
|
delete this._state[key];
|
125
|
-
this.
|
128
|
+
this._setRawState(key, value);
|
126
129
|
} else {
|
127
130
|
this._lastValue.set(key, this._state[key]);
|
128
131
|
this._state[key] = value as TState[Extract<keyof TState, string>];
|
@@ -137,13 +140,20 @@ export class Storage<TState = any> implements Storage<TState> {
|
|
137
140
|
payload = refValue;
|
138
141
|
}
|
139
142
|
|
140
|
-
this.
|
143
|
+
this._setRawState(key, payload)
|
141
144
|
}
|
142
145
|
});
|
143
146
|
}
|
144
147
|
}
|
145
148
|
|
146
|
-
|
149
|
+
/**
|
150
|
+
* Empty storage data.
|
151
|
+
*/
|
152
|
+
emptyStorage(): void {
|
153
|
+
if (size(this._state) <= 0) {
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
|
147
157
|
if (this._destroyed) {
|
148
158
|
console.error(new Error(`Cannot empty destroyed Storage "${this.id}".`));
|
149
159
|
return;
|
@@ -154,10 +164,17 @@ export class Storage<TState = any> implements Storage<TState> {
|
|
154
164
|
return;
|
155
165
|
}
|
156
166
|
|
157
|
-
this.
|
167
|
+
this.setState(mapValues(this._state, noop as () => undefined));
|
158
168
|
}
|
159
169
|
|
160
|
-
|
170
|
+
/**
|
171
|
+
* Delete storage index with all of its data and destroy the Storage instance.
|
172
|
+
*/
|
173
|
+
deleteStorage(): void {
|
174
|
+
if (this.id === null) {
|
175
|
+
throw new Error(`Cannot delete main Storage`);
|
176
|
+
}
|
177
|
+
|
161
178
|
if (!this._context.getIsWritable()) {
|
162
179
|
console.error(new Error(`Cannot delete Storage "${this.id}" without writable access.`));
|
163
180
|
return;
|
@@ -172,11 +189,35 @@ export class Storage<TState = any> implements Storage<TState> {
|
|
172
189
|
return this._destroyed;
|
173
190
|
}
|
174
191
|
|
192
|
+
/**
|
193
|
+
* Destroy the Storage instance. The data will be kept.
|
194
|
+
*/
|
175
195
|
destroy() {
|
176
196
|
this._destroyed = true;
|
177
197
|
this._sideEffect.flushAll();
|
178
198
|
}
|
179
199
|
|
200
|
+
private _getRawState(): TState | undefined
|
201
|
+
private _getRawState(defaultValue: TState): TState
|
202
|
+
private _getRawState(defaultValue?: TState): TState | undefined {
|
203
|
+
if (this.id === null) {
|
204
|
+
return get(this._context.getAttributes(), [], defaultValue);
|
205
|
+
} else {
|
206
|
+
return get(this._context.getAttributes(), [STORAGE_NS, this.id], defaultValue);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
private _setRawState(key: string, value: any): void {
|
211
|
+
if (this.id === null) {
|
212
|
+
if (key === STORAGE_NS) {
|
213
|
+
throw new Error(`Cannot set attribute internal filed "${STORAGE_NS}"`)
|
214
|
+
}
|
215
|
+
return this._context.updateAttributes([key], value);
|
216
|
+
} else {
|
217
|
+
return this._context.updateAttributes([STORAGE_NS, this.id, key], value);
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
180
221
|
private _updateProperties(actions: ReadonlyArray<AkkoObjectUpdatedProperty<TState, string>>): void {
|
181
222
|
if (this._destroyed) {
|
182
223
|
console.error(new Error(`Cannot call _updateProperties on destroyed Storage "${this.id}".`));
|
@@ -190,6 +231,11 @@ export class Storage<TState = any> implements Storage<TState> {
|
|
190
231
|
try {
|
191
232
|
const action = actions[i]
|
192
233
|
const key = action.key as Extract<keyof TState, string>;
|
234
|
+
|
235
|
+
if (this.id === null && key === STORAGE_NS) {
|
236
|
+
continue
|
237
|
+
}
|
238
|
+
|
193
239
|
const value = isObject(action.value) ? JSON.parse(JSON.stringify(action.value)) : action.value;
|
194
240
|
let oldValue: TState[Extract<keyof TState, string>] | undefined;
|
195
241
|
if (this._lastValue.has(key)) {
|
@@ -16,6 +16,8 @@ export type StorageOnSetStatePayload<TState = unknown> = {
|
|
16
16
|
[K in keyof TState]?: MaybeRefValue<TState[K]>;
|
17
17
|
};
|
18
18
|
|
19
|
-
export type StorageStateChangedEvent<TState = any> = Diff<TState
|
19
|
+
export type StorageStateChangedEvent<TState = any> = Diff<TState>;
|
20
20
|
|
21
|
-
export type StorageStateChangedListener<TState = any> = StorageEventListener<StorageStateChangedEvent<TState
|
21
|
+
export type StorageStateChangedListener<TState = any> = StorageEventListener<StorageStateChangedEvent<TState>>;
|
22
|
+
|
23
|
+
export type StorageStateChangedListenerDisposer = () => void;
|