@netless/window-manager 0.4.0-canary.1 → 0.4.0-canary.5

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/style.css CHANGED
@@ -1 +1 @@
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 .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}.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 .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}.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}.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}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/window-manager",
3
- "version": "0.4.0-canary.1",
3
+ "version": "0.4.0-canary.5",
4
4
  "description": "",
5
5
  "main": "dist/index.es.js",
6
6
  "module": "dist/index.es.js",
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@juggle/resize-observer": "^3.3.1",
25
- "@netless/app-docs-viewer": "0.1.26",
25
+ "@netless/app-docs-viewer": "0.2.0",
26
26
  "@netless/app-media-player": "0.1.0-beta.5",
27
27
  "@netless/telebox-insider": "0.2.17",
28
28
  "emittery": "^0.9.2",
package/src/AppManager.ts CHANGED
@@ -1,21 +1,22 @@
1
1
  import pRetry from "p-retry";
2
- import { sortBy } from "lodash";
3
2
  import { AppAttributes, AppStatus, Events, MagixEventName } from "./constants";
4
3
  import { AppListeners } from "./AppListener";
5
4
  import { AppProxy } from "./AppProxy";
6
- import { store } from "./AttributesDelegate";
7
5
  import { autorun, isPlayer, isRoom, ScenePathType, ViewVisionMode } from "white-web-sdk";
8
- import { callbacks, emitter, WindowManager } from "./index";
6
+ import { callbacks, emitter, WindowManager, reconnectRefresher } from "./index";
9
7
  import { CameraStore } from "./Utils/CameraStore";
10
8
  import { genAppId, makeValidScenePath, setScenePath } from "./Utils/Common";
11
9
  import { log } from "./Utils/log";
12
10
  import { MainViewProxy } from "./MainView";
13
11
  import { onObjectRemoved, safeListenPropsUpdated } from "./Utils/Reactive";
14
- import { ReconnectRefresher } from "./ReconnectRefresher";
12
+ import { sortBy } from "lodash";
13
+ import { store } from "./AttributesDelegate";
15
14
  import { ViewManager } from "./ViewManager";
15
+ import type { ReconnectRefresher } from "./ReconnectRefresher";
16
16
  import type { BoxManager } from "./BoxManager";
17
17
  import type { Displayer, DisplayerState, Room } from "white-web-sdk";
18
18
  import type { AddAppParams, BaseInsertParams, TeleBoxRect, EmitterEvent } from "./index";
19
+
19
20
  export class AppManager {
20
21
  public displayer: Displayer;
21
22
  public cameraStore: CameraStore;
@@ -44,12 +45,12 @@ export class AppManager {
44
45
  this.displayer.callbacks.on(this.eventName, this.displayerStateListener);
45
46
  this.appListeners.addListeners();
46
47
 
47
- this.refresher = new ReconnectRefresher(this.room, {
48
- notifyReconnected: () => this.notifyReconnected(),
49
- });
48
+ this.refresher = reconnectRefresher;
49
+ this.refresher.setRoom(this.room);
50
+ this.refresher.setContext({ emitter });
50
51
 
51
52
  emitter.once("onCreated").then(() => this.onCreated());
52
-
53
+ emitter.on("onReconnected", () => this.onReconnected());
53
54
  if (isPlayer(this.displayer)) {
54
55
  emitter.on("seek", time => {
55
56
  this.appProxies.forEach(appProxy => {
@@ -433,7 +434,7 @@ export class AppManager {
433
434
  }
434
435
  }
435
436
 
436
- public async notifyReconnected() {
437
+ public async onReconnected() {
437
438
  const appProxies = Array.from(this.appProxies.values());
438
439
  const reconnected = appProxies.map(appProxy => {
439
440
  return appProxy.onReconnected();
@@ -1,7 +1,6 @@
1
1
  import App from './Cursor.svelte';
2
- import pRetry from 'p-retry';
3
2
  import { ApplianceMap } from './icons';
4
- import { ApplianceNames, autorun } from 'white-web-sdk';
3
+ import { ApplianceNames } from 'white-web-sdk';
5
4
  import { CursorState } from '../constants';
6
5
  import { Fields } from '../AttributesDelegate';
7
6
  import { get, omit } from 'lodash';
@@ -19,54 +18,44 @@ export type Payload = {
19
18
 
20
19
  export class Cursor extends Base {
21
20
  private member?: RoomMember;
22
- private disposer: any;
23
21
  private timer?: number;
24
22
  private component?: SvelteComponent;
25
23
 
26
24
  constructor(
27
25
  manager: AppManager,
26
+ addCursorChangeListener: (uid: string, callback: (position: Position, state: CursorState) => void) => void,
28
27
  private cursors: any,
29
28
  private memberId: string,
30
29
  private cursorManager: CursorManager,
31
- private wrapper?: HTMLElement
30
+ private wrapper?: HTMLElement,
32
31
  ) {
33
32
  super(manager);
34
33
  this.setMember();
35
34
  this.createCursor();
36
- pRetry(() => {
37
- this.disposer && this.disposer();
38
- if (!this.cursorPosition) {
39
- console.warn(`${memberId} not exist`);
40
- }
41
- this.startReaction();
42
- }, { retries: 3 });
35
+ addCursorChangeListener(this.memberId, this.onCursorChange);
43
36
  this.autoHidden();
44
37
  }
45
38
 
46
- private startReaction() {
47
- this.disposer = autorun(() => {
48
- const cursor = this.cursorPosition;
49
- const state = this.cursorState;
50
- if (!cursor) return;
51
- if (cursor.type === "main") {
52
- const rect = this.cursorManager.wrapperRect;
53
- if (this.component && rect) {
54
- this.autoHidden();
55
- this.moveCursor(cursor, rect, this.manager.mainView);
56
- }
57
- } else {
58
- const focusView = this.cursorManager.focusView;
59
- const viewRect = focusView?.divElement?.getBoundingClientRect();
60
- const viewCamera = focusView?.camera;
61
- if (focusView && viewRect && viewCamera && this.component) {
62
- this.autoHidden();
63
- this.moveCursor(cursor, viewRect, focusView);
64
- }
39
+ private onCursorChange = (position: Position, state: CursorState) => {
40
+ if (position.type === "main") {
41
+ const rect = this.cursorManager.wrapperRect;
42
+ if (this.component && rect) {
43
+ this.autoHidden();
44
+ this.moveCursor(position, rect, this.manager.mainView);
65
45
  }
66
- if (state && state === CursorState.Leave) {
67
- this.hide();
46
+ } else {
47
+ const focusView = this.cursorManager.focusView;
48
+ // TODO 可以存一个当前 focusView 的 Rect 这样只有 focus 切换的时候才调用 getBoundingClientRect
49
+ const viewRect = focusView?.divElement?.getBoundingClientRect();
50
+ const viewCamera = focusView?.camera;
51
+ if (focusView && viewRect && viewCamera && this.component) {
52
+ this.autoHidden();
53
+ this.moveCursor(position, viewRect, focusView);
68
54
  }
69
- });
55
+ }
56
+ if (state && state === CursorState.Leave) {
57
+ this.hide();
58
+ }
70
59
  }
71
60
 
72
61
  private moveCursor(cursor: Position, rect: DOMRect, view: any) {
@@ -196,10 +185,10 @@ export class Cursor extends Base {
196
185
  }
197
186
 
198
187
  public destroy() {
199
- this.disposer && this.disposer();
200
188
  if (this.component) {
201
189
  this.component.$destroy();
202
190
  }
191
+ this.manager.refresher?.remove(this.memberId);
203
192
  this.cursorManager.cursorInstances.delete(this.memberId);
204
193
  }
205
194
 
@@ -1,11 +1,13 @@
1
- import { Base } from '../Base';
2
- import { Cursor } from './Cursor';
3
- import { CursorState } from '../constants';
4
- import { compact, debounce, uniq } from 'lodash';
5
- import { Fields } from '../AttributesDelegate';
6
- import { onObjectInserted } from '../Utils/Reactive';
7
- import { WindowManager } from '../index';
8
- import type { PositionType } from "../AttributesDelegate";
1
+ import { autorun } from "white-web-sdk";
2
+ import { Base } from "../Base";
3
+ import { compact, debounce, get, uniq } from "lodash";
4
+ import { Cursor } from "./Cursor";
5
+ import { CursorState } from "../constants";
6
+ import { emitter, WindowManager } from "../index";
7
+ import { Fields } from "../AttributesDelegate";
8
+ import { onObjectInserted } from "../Utils/Reactive";
9
+ import { SideEffectManager } from "side-effect-manager";
10
+ import type { PositionType, Position } from "../AttributesDelegate";
9
11
  import type { Point, RoomMember, View } from "white-web-sdk";
10
12
  import type { AppManager } from "../AppManager";
11
13
 
@@ -18,32 +20,42 @@ export type MoveCursorParams = {
18
20
  uid: string;
19
21
  x: number;
20
22
  y: number;
21
- }
23
+ };
22
24
  export class CursorManager extends Base {
23
25
  public containerRect?: DOMRect;
24
26
  public wrapperRect?: DOMRect;
25
27
  public cursorInstances: Map<string, Cursor> = new Map();
26
28
  public roomMembers?: readonly RoomMember[];
27
29
  private mainViewElement?: HTMLDivElement;
30
+ private sideEffectManager = new SideEffectManager();
28
31
 
29
32
  constructor(private appManager: AppManager) {
30
33
  super(appManager);
31
34
  this.roomMembers = this.appManager.room?.state.roomMembers;
32
35
  const wrapper = WindowManager.wrapper;
33
36
  if (wrapper) {
34
- this.setupWrapper(wrapper);
37
+ this.setupWrapper(wrapper);
35
38
  }
39
+ emitter.on("onReconnected", () => {
40
+ this.onReconnect();
41
+ });
36
42
  }
37
43
 
38
44
  public setupWrapper(wrapper: HTMLElement) {
39
45
  if (this.manager.refresher?.hasReactor("cursors")) {
40
46
  this.destroy();
41
47
  }
42
- wrapper.addEventListener("mousemove", this.mouseMoveListener);
43
- wrapper.addEventListener("touchstart", this.touchMoveListener);
44
- wrapper.addEventListener("touchmove", this.touchMoveListener);
45
- wrapper.addEventListener("mouseleave", this.mouseLeaveListener);
46
- wrapper.addEventListener("touchend", this.mouseLeaveListener);
48
+ this.sideEffectManager.add(() => {
49
+ wrapper.addEventListener("pointerenter", this.mouseMoveListener);
50
+ wrapper.addEventListener("pointermove", this.mouseMoveListener);
51
+ wrapper.addEventListener("pointerleave", this.mouseLeaveListener);
52
+ return () => {
53
+ wrapper.removeEventListener("pointerenter", this.mouseMoveListener);
54
+ wrapper.removeEventListener("pointermove", this.mouseMoveListener);
55
+ wrapper.removeEventListener("pointerleave", this.mouseLeaveListener);
56
+ };
57
+ });
58
+
47
59
  this.initCursorAttributes();
48
60
  this.wrapperRect = wrapper.getBoundingClientRect();
49
61
  this.startReaction(wrapper);
@@ -58,27 +70,25 @@ export class CursorManager extends Base {
58
70
  return onObjectInserted(this.cursors, () => {
59
71
  this.handleRoomMembersChange(wrapper);
60
72
  });
61
- })
73
+ });
62
74
  }
63
75
 
64
76
  private getUids = (members: readonly RoomMember[] | undefined) => {
65
77
  return compact(uniq(members?.map(member => member.payload?.uid)));
66
- }
78
+ };
67
79
 
68
80
  private handleRoomMembersChange = debounce((wrapper: HTMLElement) => {
69
81
  const uids = this.getUids(this.roomMembers);
70
82
  const cursors = Object.keys(this.cursors);
71
83
  if (uids?.length) {
72
84
  cursors.map(uid => {
73
- if (
74
- uids.includes(uid) &&
75
- !this.cursorInstances.has(uid)
76
- ) {
85
+ if (uids.includes(uid) && !this.cursorInstances.has(uid)) {
77
86
  if (uid === this.context.uid) {
78
87
  return;
79
88
  }
80
89
  const component = new Cursor(
81
90
  this.appManager,
91
+ this.addCursorChangeListener,
82
92
  this.cursors,
83
93
  uid,
84
94
  this,
@@ -86,7 +96,7 @@ export class CursorManager extends Base {
86
96
  );
87
97
  this.cursorInstances.set(uid, component);
88
98
  }
89
- })
99
+ });
90
100
  }
91
101
  }, 100);
92
102
 
@@ -106,13 +116,6 @@ export class CursorManager extends Base {
106
116
  this.updateCursor(this.getType(event), event.clientX, event.clientY);
107
117
  }, 5);
108
118
 
109
- private touchMoveListener = debounce((event: TouchEvent) => {
110
- if (event.touches.length === 1) {
111
- const touchEvent = event.touches[0];
112
- this.updateCursor(this.getType(touchEvent), touchEvent.clientX, touchEvent.clientY);
113
- }
114
- }, 5);
115
-
116
119
  private updateCursor(event: EventType, clientX: number, clientY: number) {
117
120
  if (this.wrapperRect && this.manager.canOperate) {
118
121
  const view = event.type === "main" ? this.appManager.mainView : this.focusView;
@@ -128,7 +131,11 @@ export class CursorManager extends Base {
128
131
  }
129
132
  }
130
133
 
131
- private getPoint = (view: View | undefined, clientX: number, clientY: number): Point | undefined => {
134
+ private getPoint = (
135
+ view: View | undefined,
136
+ clientX: number,
137
+ clientY: number
138
+ ): Point | undefined => {
132
139
  const rect = view?.divElement?.getBoundingClientRect();
133
140
  if (rect) {
134
141
  const point = view?.convertToPointInWorld({
@@ -137,7 +144,7 @@ export class CursorManager extends Base {
137
144
  });
138
145
  return point;
139
146
  }
140
- }
147
+ };
141
148
 
142
149
  /**
143
150
  * 因为窗口内框在不同分辨率下的大小不一样,所以这里通过来鼠标事件的 target 来判断是在主白板还是在 APP 中
@@ -147,7 +154,7 @@ export class CursorManager extends Base {
147
154
  const focusApp = this.appManager.focusApp;
148
155
  switch (target.parentElement) {
149
156
  case this.mainViewElement: {
150
- return { type: "main" };
157
+ return { type: "main" };
151
158
  }
152
159
  case focusApp?.view?.divElement: {
153
160
  return { type: "app" };
@@ -224,19 +231,41 @@ export class CursorManager extends Base {
224
231
  });
225
232
  }
226
233
 
227
- public destroy() {
228
- const wrapper = WindowManager.wrapper;
229
- if (wrapper) {
230
- wrapper.removeEventListener("mousemove", this.mouseMoveListener);
231
- wrapper.removeEventListener("touchstart", this.touchMoveListener);
232
- wrapper.removeEventListener("touchmove", this.touchMoveListener);
233
- wrapper.removeEventListener("mouseleave", this.mouseLeaveListener);
234
- wrapper.removeEventListener("touchend", this.mouseLeaveListener);
235
- }
234
+ public onReconnect() {
236
235
  if (this.cursorInstances.size) {
237
236
  this.cursorInstances.forEach(cursor => cursor.destroy());
238
237
  this.cursorInstances.clear();
239
238
  }
239
+ this.roomMembers = this.appManager.room?.state.roomMembers;
240
+ if (WindowManager.wrapper) {
241
+ this.handleRoomMembersChange(WindowManager.wrapper);
242
+ }
243
+ }
244
+
245
+ public addCursorChangeListener = (
246
+ uid: string,
247
+ callback: (position: Position, state: CursorState) => void
248
+ ) => {
249
+ this.manager.refresher?.add(uid, () => {
250
+ const disposer = autorun(() => {
251
+ const position = get(this.cursors, [uid, Fields.Position]);
252
+ const state = get(this.cursors, [uid, Fields.CursorState]);
253
+ if (position) {
254
+ callback(position, state);
255
+ }
256
+ });
257
+ return disposer;
258
+ });
259
+ };
260
+
261
+ public destroy() {
262
+ this.sideEffectManager.flushAll();
263
+ if (this.cursorInstances.size) {
264
+ this.cursorInstances.forEach(cursor => {
265
+ cursor.destroy();
266
+ });
267
+ this.cursorInstances.clear();
268
+ }
240
269
  this.manager.refresher?.remove("cursors");
241
270
  }
242
271
  }
@@ -1,11 +1,13 @@
1
- import { isFunction, debounce } from "lodash";
1
+ import { debounce, isFunction } from "lodash";
2
+ import { emitter } from "./index";
2
3
  import { log } from "./Utils/log";
3
4
  import { RoomPhase } from "white-web-sdk";
4
5
  import type { Room } from "white-web-sdk";
6
+ import type { EmitterType } from "./index";
5
7
 
6
8
  export type ReconnectRefresherContext = {
7
- notifyReconnected: () => void;
8
- }
9
+ emitter: EmitterType;
10
+ };
9
11
 
10
12
  // 白板重连之后会刷新所有的对象,导致 listener 失效, 所以这里在重连之后重新对所有对象进行监听
11
13
  export class ReconnectRefresher {
@@ -14,12 +16,19 @@ export class ReconnectRefresher {
14
16
  private reactors: Map<string, any> = new Map();
15
17
  private disposers: Map<string, any> = new Map();
16
18
 
17
- constructor(room: Room | undefined, private ctx: ReconnectRefresherContext) {
19
+ constructor(private ctx: ReconnectRefresherContext) {}
20
+
21
+ public setRoom(room: Room | undefined) {
18
22
  this.room = room;
19
23
  this.phase = room?.phase;
24
+ room?.callbacks.off("onPhaseChanged", this.onPhaseChanged);
20
25
  room?.callbacks.on("onPhaseChanged", this.onPhaseChanged);
21
26
  }
22
27
 
28
+ public setContext(ctx: ReconnectRefresherContext) {
29
+ this.ctx = ctx;
30
+ }
31
+
23
32
  private onPhaseChanged = (phase: RoomPhase) => {
24
33
  if (phase === RoomPhase.Connected && this.phase === RoomPhase.Reconnecting) {
25
34
  this.onReconnected();
@@ -35,7 +44,7 @@ export class ReconnectRefresher {
35
44
  this.disposers.set(id, func());
36
45
  }
37
46
  });
38
- this.ctx.notifyReconnected();
47
+ this.ctx.emitter.emit("onReconnected", undefined);
39
48
  }, 3000);
40
49
 
41
50
  private releaseDisposers() {
package/src/index.ts CHANGED
@@ -16,6 +16,7 @@ import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observe
16
16
  import { setupWrapper } from "./ViewManager";
17
17
  import "./style.css";
18
18
  import "@netless/telebox-insider/dist/style.css";
19
+ import "@netless/app-docs-viewer/dist/style.css";
19
20
  import {
20
21
  addEmitterOnceListener,
21
22
  ensureValidScenePath,
@@ -58,6 +59,7 @@ import type { AppListeners } from "./AppListener";
58
59
  import type { NetlessApp, RegisterParams } from "./typings";
59
60
  import type { TeleBoxColorScheme, TeleBoxState } from "@netless/telebox-insider";
60
61
  import type { AppProxy } from "./AppProxy";
62
+ import { ReconnectRefresher } from "./ReconnectRefresher";
61
63
 
62
64
  const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
63
65
 
@@ -81,14 +83,14 @@ export type AddAppOptions = {
81
83
 
82
84
  export type setAppOptions = AddAppOptions & { appOptions?: any };
83
85
 
84
- export type AddAppParams = {
86
+ export type AddAppParams<TAttributes = any> = {
85
87
  kind: string;
86
88
  // app 地址(本地 app 不需要传)
87
89
  src?: string;
88
90
  // 窗口配置
89
91
  options?: AddAppOptions;
90
92
  // 初始化 attributes
91
- attributes?: any;
93
+ attributes?: TAttributes;
92
94
  };
93
95
 
94
96
  export type BaseInsertParams = {
@@ -139,6 +141,7 @@ export type EmitterEvent = {
139
141
  observerIdChange: number;
140
142
  boxStateChange: string;
141
143
  playgroundSizeChange: DOMRect;
144
+ onReconnected: void;
142
145
  };
143
146
 
144
147
  export type EmitterType = Emittery<EmitterEvent>;
@@ -171,6 +174,8 @@ export type MountParams = {
171
174
  export type CallbacksType = Emittery<PublicEvent>;
172
175
  export const callbacks: CallbacksType = new Emittery();
173
176
 
177
+ export const reconnectRefresher = new ReconnectRefresher({ emitter });
178
+
174
179
  export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
175
180
  public static kind = "WindowManager";
176
181
  public static displayer: Displayer;
@@ -181,7 +186,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
181
186
  public static containerSizeRatio = DEFAULT_CONTAINER_RATIO;
182
187
  private static isCreated = false;
183
188
 
184
- public version = "0.4.0-canary.1";
189
+ public version = "0.4.0-canary.5";
185
190
 
186
191
  public appListeners?: AppListeners;
187
192
 
@@ -254,7 +259,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
254
259
  }
255
260
 
256
261
  if (params.container) {
257
- manager.bindContainer(params.container, params.collectorContainer);
262
+ manager.bindContainer(params.container);
258
263
  }
259
264
 
260
265
  replaceRoomFunction(room, manager);
@@ -321,7 +326,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
321
326
  return mainViewElement;
322
327
  }
323
328
 
324
- public bindContainer(container: HTMLElement, collectorContainer?: HTMLElement) {
329
+ public bindContainer(container: HTMLElement) {
325
330
  if (WindowManager.isCreated && WindowManager.container) {
326
331
  if (WindowManager.container.firstChild) {
327
332
  container.appendChild(WindowManager.container.firstChild);
@@ -336,7 +341,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
336
341
  params.overwriteStyles
337
342
  );
338
343
  const boxManager = createBoxManager(this, callbacks, emitter, {
339
- collectorContainer: collectorContainer,
344
+ collectorContainer: params.collectorContainer,
340
345
  collectorStyles: params.collectorStyles,
341
346
  prefersColorScheme: params.prefersColorScheme,
342
347
  });
@@ -355,6 +360,16 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
355
360
  WindowManager.container = container;
356
361
  }
357
362
 
363
+ public bindCollectorContainer(container: HTMLElement) {
364
+ if (WindowManager.isCreated && this.boxManager) {
365
+ this.boxManager.setCollectorContainer(container);
366
+ } else {
367
+ if (WindowManager.params) {
368
+ WindowManager.params.collectorContainer = container;
369
+ }
370
+ }
371
+ }
372
+
358
373
  /**
359
374
  * 注册插件
360
375
  */
@@ -364,21 +379,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
364
379
  return appRegister.register(params);
365
380
  }
366
381
 
367
- public static setCollectorContainer(container: HTMLElement) {
368
- const manager = this.displayer.getInvisiblePlugin(this.kind) as WindowManager;
369
- if (this.isCreated && manager) {
370
- manager.boxManager?.setCollectorContainer(container);
371
- } else {
372
- if (this.params) {
373
- this.params.collectorContainer = container;
374
- }
375
- }
376
- }
377
-
378
382
  /**
379
383
  * 创建一个 app 至白板
380
384
  */
381
- public async addApp(params: AddAppParams): Promise<string | undefined> {
385
+ public async addApp<T = any>(params: AddAppParams<T>): Promise<string | undefined> {
382
386
  if (this.appManager) {
383
387
  if (!params.kind || typeof params.kind !== "string") {
384
388
  throw new ParamsInvalidError();