@vite-plugin-opencode-assistant/components 1.0.26 → 1.0.27
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/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/open-code-widget/composables/use-inspector.js +118 -79
- package/es/open-code-widget/composables/use-persist-state.d.ts +24 -0
- package/es/open-code-widget/composables/use-persist-state.js +59 -0
- package/es/open-code-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -1
- package/es/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +2 -2
- package/es/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.js +37 -21
- package/es/open-code-widget/src/components/Trigger.vue.d.ts +0 -2
- package/es/open-code-widget/src/components/Trigger.vue.js +10 -27
- package/es/open-code-widget/src/context.d.ts +3 -0
- package/es/open-code-widget/src/index-sfc.css +1 -1
- package/es/open-code-widget/src/index.vue.d.ts +10 -10
- package/es/open-code-widget/src/index.vue.js +107 -29
- package/lib/@vite-plugin-opencode-assistant/components.cjs.js +304 -140
- package/lib/@vite-plugin-opencode-assistant/components.es.js +305 -141
- package/lib/components.css +2 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/open-code-widget/composables/use-inspector.js +118 -79
- package/lib/open-code-widget/composables/use-persist-state.d.ts +24 -0
- package/lib/open-code-widget/composables/use-persist-state.js +78 -0
- package/lib/open-code-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -1
- package/lib/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +2 -2
- package/lib/open-code-widget/src/components/FloatingBubble/FloatingBubble.vue.js +37 -21
- package/lib/open-code-widget/src/components/Trigger.vue.d.ts +0 -2
- package/lib/open-code-widget/src/components/Trigger.vue.js +10 -27
- package/lib/open-code-widget/src/context.d.ts +3 -0
- package/lib/open-code-widget/src/index-sfc.css +1 -1
- package/lib/open-code-widget/src/index.vue.d.ts +10 -10
- package/lib/open-code-widget/src/index.vue.js +106 -28
- package/lib/web-types.json +1 -1
- package/package.json +2 -2
package/lib/components.css
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
.opencode-widget{--oc-bg-main: #ffffff;--oc-bg-secondary: #f8f9fa;--oc-bg-tertiary: #f3f4f6;--oc-overlay-bg: rgba(255, 255, 255, .9);--oc-bg-inverse: #1e1e1e;--oc-text-primary: #282828;--oc-text-secondary: #4b5563;--oc-text-tertiary: #6b7280;--oc-text-placeholder: #9ca3af;--oc-text-inverse: #ffffff;--oc-border-primary: #e5e7eb;--oc-border-secondary: #d1d5db;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .1);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(0, 0, 0, .5);--oc-tooltip-bg: #1e1e1e;--oc-dialog-overlay: rgba(0, 0, 0, .5);--oc-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--oc-skeleton-bg: #e5e7eb;--oc-skeleton-gradient: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .1);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .15);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .12);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .3);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .2);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .3);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .3);--oc-trigger-bg: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);position:fixed;z-index:999999;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-widget.opencode-theme-dark{--oc-bg-main: #1a1a1a;--oc-bg-secondary: #1e1e1e;--oc-bg-tertiary: #282828;--oc-overlay-bg: rgba(26, 26, 26, .9);--oc-bg-inverse: #ffffff;--oc-text-primary: #f3f4f6;--oc-text-secondary: #d1d5db;--oc-text-tertiary: #9ca3af;--oc-text-placeholder: #6b7280;--oc-text-inverse: #282828;--oc-border-primary: #282828;--oc-border-secondary: #4b5563;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .15);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(26, 26, 26, .9);--oc-tooltip-bg: #282828;--oc-dialog-overlay: rgba(0, 0, 0, .7);--oc-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--oc-skeleton-bg: #151515;--oc-skeleton-gradient: linear-gradient(90deg, #282828 25%, #4b5563 50%, #282828 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .3);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .4);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .4);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .6);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .3);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .4);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .4);--oc-trigger-bg: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translate3d(var(---chatAnimationOrigin\.x),var(---chatAnimationOrigin\.y),0) scale(.95);transition:all .3s ease;display:flex;flex-direction:column;z-index:99999}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-
|
|
1
|
+
.opencode-widget{--oc-bg-main: #ffffff;--oc-bg-secondary: #f8f9fa;--oc-bg-tertiary: #f3f4f6;--oc-overlay-bg: rgba(255, 255, 255, .9);--oc-bg-inverse: #1e1e1e;--oc-text-primary: #282828;--oc-text-secondary: #4b5563;--oc-text-tertiary: #6b7280;--oc-text-placeholder: #9ca3af;--oc-text-inverse: #ffffff;--oc-border-primary: #e5e7eb;--oc-border-secondary: #d1d5db;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .1);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(0, 0, 0, .5);--oc-tooltip-bg: #1e1e1e;--oc-dialog-overlay: rgba(0, 0, 0, .5);--oc-thinking-gradient-1: #10b981;--oc-thinking-gradient-2: #059669;--oc-thinking-glow: rgba(16, 185, 129, .3);--oc-thinking-glow-strong: rgba(16, 185, 129, .6);--oc-skeleton-bg: #e5e7eb;--oc-skeleton-gradient: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .1);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .15);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .12);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .3);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .2);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .3);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .3);--oc-trigger-bg: #3b82f6;--oc-trigger-bg-hover: #2563eb;--oc-trigger-bg-active: #1d4ed8;--oc-trigger-shadow: 0 2px 8px rgba(59, 130, 246, .3);--oc-trigger-shadow-hover: 0 4px 12px rgba(59, 130, 246, .4);--oc-trigger-shadow-active: 0 4px 12px rgba(59, 130, 246, .5);position:fixed;z-index:999999;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-widget.opencode-theme-dark{--oc-bg-main: #1a1a1a;--oc-bg-secondary: #1e1e1e;--oc-bg-tertiary: #282828;--oc-overlay-bg: rgba(26, 26, 26, .9);--oc-bg-inverse: #ffffff;--oc-text-primary: #f3f4f6;--oc-text-secondary: #d1d5db;--oc-text-tertiary: #9ca3af;--oc-text-placeholder: #6b7280;--oc-text-inverse: #282828;--oc-border-primary: #282828;--oc-border-secondary: #4b5563;--oc-primary: #3b82f6;--oc-primary-hover: #2563eb;--oc-primary-bg: rgba(59, 130, 246, .15);--oc-danger: #ef4444;--oc-danger-hover: #dc2626;--oc-danger-active: #b91c1c;--oc-success: #10b981;--oc-overlay: rgba(26, 26, 26, .9);--oc-tooltip-bg: #282828;--oc-dialog-overlay: rgba(0, 0, 0, .7);--oc-thinking-gradient-1: #34d399;--oc-thinking-gradient-2: #10b981;--oc-thinking-glow: rgba(52, 211, 153, .3);--oc-thinking-glow-strong: rgba(52, 211, 153, .6);--oc-skeleton-bg: #151515;--oc-skeleton-gradient: linear-gradient(90deg, #282828 25%, #4b5563 50%, #282828 75%);--oc-shadow-sm: 0 2px 4px rgba(0, 0, 0, .3);--oc-shadow-md: 0 4px 12px rgba(0, 0, 0, .4);--oc-shadow-lg: 0 8px 32px rgba(0, 0, 0, .4);--oc-shadow-xl: 0 20px 60px rgba(0, 0, 0, .6);--oc-shadow-primary: 0 2px 4px rgba(59, 130, 246, .3);--oc-shadow-primary-hover: 0 4px 6px rgba(59, 130, 246, .4);--oc-shadow-danger: 0 4px 12px rgba(239, 68, 68, .4);--oc-trigger-bg: #60a5fa;--oc-trigger-bg-hover: #3b82f6;--oc-trigger-bg-active: #2563eb;--oc-trigger-shadow: 0 2px 8px rgba(96, 165, 250, .4);--oc-trigger-shadow-hover: 0 4px 12px rgba(96, 165, 250, .5);--oc-trigger-shadow-active: 0 4px 12px rgba(96, 165, 250, .6)}.opencode-chat{position:fixed;bottom:20px;width:700px;height:86vh;max-height:calc(100vh - 40px);background:var(--oc-bg-main);border-radius:16px;box-shadow:var(--oc-shadow-lg);overflow:hidden;opacity:0;visibility:hidden;transform:translate3d(var(---chatAnimationOrigin\.x),var(---chatAnimationOrigin\.y),0) scale(.95);transition:all .3s ease;display:flex;flex-direction:column;z-index:99999}.opencode-chat.open{opacity:1;visibility:visible;transform:translateZ(0) scale(1)}.opencode-chat.no-transition,.opencode-chat.no-transition.open{transition:none!important}.opencode-chat.minimized{width:300px;height:300px}.opencode-chat.minimized .opencode-iframe-container{margin-top:-146px}.opencode-chat-content{display:flex;flex:1;overflow:hidden}.opencode-notification{position:absolute;top:20px;left:50%;transform:translate(-50%);padding:12px 24px;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;border-radius:10px;font-size:14px;font-weight:500;box-shadow:0 4px 16px rgba(59,130,246,.4),0 0 0 2px rgba(59,130,246,.2);animation:slideDown .3s ease;z-index:10000000;display:flex;align-items:center;gap:10px}.opencode-notification:before{content:"\1f4a1";font-size:16px}.opencode-dialog-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:var(--oc-dialog-overlay);display:flex;align-items:center;justify-content:center;z-index:9999999;animation:fadeIn .2s ease}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.opencode-dialog{background:var(--oc-bg-main);border-radius:12px;padding:24px;min-width:320px;max-width:400px;box-shadow:var(--oc-shadow-xl);animation:scaleIn .2s ease}@keyframes scaleIn{0%{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}.opencode-dialog-content{margin-bottom:20px}.opencode-dialog-message{font-size:15px;color:var(--oc-text-primary);line-height:1.5}.opencode-dialog-actions{display:flex;gap:12px;justify-content:flex-end}.opencode-dialog-btn{padding:10px 20px;border-radius:8px;border:none;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s}.opencode-dialog-btn.cancel{background:var(--oc-bg-tertiary);color:var(--oc-text-primary)}.opencode-dialog-btn.cancel:hover{background:var(--oc-text-primary);color:var(--oc-bg-main)}.opencode-dialog-btn.confirm{background:var(--oc-danger);color:#fff}.opencode-dialog-btn.confirm:hover{background:var(--oc-danger-hover)}@keyframes slideDown{0%{transform:translate(-50%) translateY(-100%);opacity:0}to{transform:translate(-50%) translateY(0);opacity:1}}.opencode-page-notification{position:fixed;top:20px;left:50%;transform:translate(-50%);padding:12px 24px;background:linear-gradient(135deg,#3b82f6,#2563eb);color:#fff;border-radius:10px;font-size:14px;font-weight:500;box-shadow:0 4px 16px rgba(59,130,246,.4),0 0 0 2px rgba(59,130,246,.2);animation:slideDown .3s ease;z-index:2147483647;display:flex;align-items:center;gap:10px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}.opencode-page-notification:before{content:"\1f4a1";font-size:16px}.opencode-element-highlight{position:fixed;pointer-events:none;z-index:999998;border-radius:4px}#vue-inspector-container{display:none!important}.opencode-element-tooltip{position:fixed;background:var(--oc-tooltip-bg);color:#fff;padding:8px 12px;border-radius:6px;font-size:12px;z-index:9999998;box-shadow:var(--oc-shadow-md);max-width:300px;pointer-events:none}.opencode-tooltip-tag{font-weight:500;margin-bottom:4px;word-break:break-all}.opencode-tooltip-file{font-size:11px;color:var(--oc-text-placeholder);word-break:break-all}.opencode-element-highlight-temp{position:absolute;pointer-events:none;z-index:999998;border-radius:4px;animation:highlight-pulse 2s ease-out forwards}@keyframes highlight-pulse{0%{opacity:1;transform:scale(1)}50%{opacity:.8;transform:scale(1.02)}to{opacity:0;transform:scale(1)}}@media(max-width:768px){.opencode-chat{width:calc(100vw - 40px);height:calc(100vh - 100px)}}
|
|
2
2
|
.opencode-iframe-container{flex:1;position:relative;overflow:hidden;display:flex;flex-direction:column;margin-top:-42px}.opencode-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:10;transition:opacity .3s ease}.opencode-loading-overlay.visible{display:flex}.opencode-loading-spinner{width:40px;height:40px;border:3px solid var(--oc-border-primary);border-top-color:var(--oc-primary);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.opencode-loading-text{margin-top:12px;font-size:14px;color:var(--oc-text-placeholder)}.opencode-error-overlay{position:absolute;top:0;left:0;right:0;bottom:0;z-index:15;margin-top:42px;display:none}.opencode-error-overlay.visible{display:flex}.opencode-empty-state-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-bg-secondary);display:none;flex-direction:column;align-items:center;justify-content:center;z-index:5;transition:opacity .3s ease;margin-top:42px}.opencode-empty-state-overlay.visible{display:flex}.opencode-empty-state-icon{color:var(--oc-text-placeholder);margin-bottom:16px}.opencode-empty-state-text{color:var(--oc-text-primary);font-size:16px;font-weight:500;margin-bottom:24px}.opencode-empty-state-btn{padding:10px 24px;border-radius:8px;border:none;background:var(--oc-primary);color:#fff;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;box-shadow:var(--oc-shadow-primary)}.opencode-empty-state-btn:hover{background:var(--oc-primary-hover);transform:translateY(-1px);box-shadow:var(--oc-shadow-primary-hover)}.opencode-empty-state-btn:active{transform:translateY(0)}.opencode-iframe{width:100%;height:100%;border:none}
|
|
3
3
|
.opencode-chat-header{position:relative;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;padding:0 12px;height:40px;background:var(--oc-bg-secondary);border-bottom:1px solid var(--oc-border-primary);z-index:5}.opencode-chat-header-left{display:flex;align-items:center;gap:4px}.opencode-chat-header-title{font-size:14px;font-weight:600;color:var(--oc-text-primary);position:absolute;left:50%;transform:translate(-50%)}.opencode-chat-header-actions{display:flex;gap:4px}.opencode-header-btn{width:28px;height:28px;border-radius:6px;border:none;background:transparent;color:var(--oc-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.opencode-header-btn:hover{background:var(--oc-bg-tertiary);color:var(--oc-text-primary)}.opencode-header-btn.close:hover{background:var(--oc-danger);color:#fff}.opencode-header-btn.select-btn.active,.opencode-header-btn.session-toggle.active{background:var(--oc-primary);color:#fff}
|
|
4
4
|
.opencode-select-mode-hint{position:fixed;top:20px;left:50%;transform:translate(-50%);padding:10px;background:linear-gradient(135deg,#ef4444,#dc2626);color:#fff;border-radius:12px;font-size:14px;font-weight:500;box-shadow:0 6px 20px rgba(239,68,68,.5),0 0 0 3px rgba(239,68,68,.3);z-index:9999999;display:none;align-items:center;gap:12px;border:1px solid rgba(255,255,255,.3)}.opencode-select-mode-hint.visible{display:flex;animation:slideDown .3s ease,pulseHint 2s ease-in-out infinite}.opencode-hint-shortcut{padding:4px 10px;background:rgba(255,255,255,.25);border-radius:6px;font-size:13px;font-weight:600;border:1px solid rgba(255,255,255,.4)}@keyframes pulseHint{0%,to{box-shadow:0 6px 20px rgba(239,68,68,.5),0 0 0 3px rgba(239,68,68,.3)}50%{box-shadow:0 6px 20px rgba(239,68,68,.6),0 0 0 6px rgba(239,68,68,.4)}}
|
|
5
5
|
.opencode-right-toolbar{width:140px;background:var(--oc-bg-secondary);border-left:1px solid var(--oc-border-primary);display:flex;flex-direction:column;flex-shrink:0;transition:width .2s ease;overflow:hidden}.opencode-right-toolbar.collapsed{width:0;overflow:hidden}.opencode-right-toolbar.collapsed .opencode-selected-nodes-header,.opencode-right-toolbar.collapsed .opencode-selected-nodes,.opencode-right-toolbar.collapsed .opencode-clear-all-btn{display:none}.opencode-selected-nodes-header{padding:12px 8px 8px;border-bottom:1px solid var(--oc-border-primary)}.opencode-selected-nodes-title{font-size:14px;font-weight:600;color:var(--oc-text-primary);margin-bottom:4px}.opencode-selected-nodes-desc{font-size:11px;color:var(--oc-text-placeholder);line-height:1.4}.opencode-selected-nodes{flex:1;display:flex;flex-direction:column;padding:8px;gap:6px;overflow-y:auto;overflow-x:hidden}.opencode-selected-nodes:empty:before{content:"\6682\65e0\9009\4e2d\5143\7d20";color:var(--oc-text-placeholder);font-size:12px;text-align:center;padding:20px 10px}.opencode-selected-node{display:flex;align-items:center;gap:8px;padding:8px 10px;background:var(--oc-bg-main);border:1px solid var(--oc-border-primary);border-radius:6px;font-size:12px;transition:all .2s}.opencode-selected-node:hover{border-color:var(--oc-primary);box-shadow:var(--oc-shadow-primary)}.opencode-node-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.opencode-node-text{color:var(--oc-text-primary);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-node-file{color:var(--oc-text-placeholder);font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-node-remove{width:18px;height:18px;border-radius:4px;border:none;background:transparent;color:var(--oc-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;transition:all .2s;flex-shrink:0}.opencode-node-remove:hover{background:var(--oc-danger);color:#fff}.opencode-clear-all-btn{width:calc(100% - 16px);margin:8px;padding:8px 12px;border-radius:6px;border:none;background:var(--oc-danger);color:#fff;font-size:12px;font-weight:500;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:4px;transition:all .2s}.opencode-clear-all-btn:hover{background:var(--oc-danger-hover);transform:scale(1.02)}
|
|
6
6
|
.opencode-session-list{width:240px;background:var(--oc-bg-secondary);border-right:1px solid var(--oc-border-primary);display:flex;flex-direction:column;flex-shrink:0;transition:width .2s ease}.opencode-session-list.collapsed{width:0;overflow:hidden}.opencode-session-list.collapsed .opencode-session-list-header,.opencode-session-list.collapsed .opencode-session-list-content{display:none}.opencode-session-list-header{padding:16px;border-bottom:1px solid var(--oc-border-primary);display:flex;justify-content:space-between;align-items:center;font-weight:600;font-size:14px;color:var(--oc-text-primary)}.opencode-new-session-btn{width:28px;height:28px;border-radius:6px;border:none;background:var(--oc-primary);color:#fff;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.opencode-new-session-btn:hover{background:var(--oc-primary-hover);transform:scale(1.05)}.opencode-session-list-content{flex:1;overflow-y:auto;padding:8px;position:relative}.opencode-session-list-loading-overlay{position:absolute;top:0;left:0;right:0;bottom:0;background:var(--oc-overlay-bg);display:flex;align-items:center;justify-content:center;z-index:10;border-radius:8px}.opencode-loading-spinner.small{width:24px;height:24px;border-width:2px}.opencode-session-item{padding:12px;border-radius:8px;cursor:pointer;transition:transform .2s;margin-bottom:4px;color:var(--oc-text-primary)}.opencode-session-item:hover{background:var(--oc-bg-tertiary)}.opencode-session-item.active{background:var(--oc-primary);color:#fff;transition:none}.opencode-session-title{font-size:14px;font-weight:500;margin-bottom:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opencode-session-meta{font-size:12px;opacity:.6}.opencode-session-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.opencode-session-delete-btn{width:20px;height:20px;border-radius:4px;border:none;background:transparent;color:var(--oc-text-placeholder);font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s;opacity:0;flex-shrink:0}.opencode-session-item:hover .opencode-session-delete-btn{opacity:1}.opencode-session-delete-btn:hover{background:var(--oc-danger);color:#fff}.opencode-session-item.active .opencode-session-delete-btn{color:rgba(255,255,255,.7)}.opencode-session-item.active .opencode-session-delete-btn:hover{background:rgba(255,255,255,.2);color:#fff}.opencode-session-header-skeleton{padding:16px;border-bottom:1px solid var(--oc-border-primary);display:none;justify-content:space-between;align-items:center}.opencode-session-header-skeleton.visible{display:flex}.opencode-skeleton-header-title{height:18px;width:80px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px}.opencode-skeleton-header-btn{width:28px;height:28px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:6px}.opencode-session-skeleton{flex:1;overflow-y:auto;padding:8px;display:none}.opencode-session-skeleton.visible{display:block}.opencode-skeleton-item{padding:12px;border-radius:8px;margin-bottom:4px;background:var(--oc-skeleton-bg)}.opencode-skeleton-title{height:16px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px;margin-bottom:8px;width:70%}.opencode-skeleton-meta{height:12px;background:var(--oc-skeleton-gradient);background-size:200% 100%;animation:skeleton-loading 1.5s ease-in-out infinite;border-radius:4px;width:50%}.opencode-session-empty{padding:32px 16px;text-align:center;color:var(--oc-text-placeholder);font-size:13px}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}
|
|
7
7
|
.opencode-button{width:42px;height:42px;border-radius:50%;background:#fff;border:none;cursor:pointer;box-shadow:0 4px 12px rgba(102,126,234,.4);transition:all .3s ease;display:flex;align-items:center;justify-content:center;padding:0;position:relative}.opencode-button svg{transform:rotate(180deg) scale(1.1);transition:transform .3s ease;width:100%;height:100%;display:block}.opencode-button:hover svg{transform:rotate(180deg) scale(1.1)}.opencode-button:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(102,126,234,.5)}.opencode-button.thinking{background:linear-gradient(135deg,#667eea,#764ba2);animation:thinking-glow 1.5s ease-in-out infinite,thinking-pulse 1.5s ease-in-out infinite;box-shadow:0 0 20px rgba(102,126,234,.6),0 0 40px rgba(118,75,162,.4),0 0 60px rgba(102,126,234,.2)}.opencode-button.thinking svg path{fill:#fff}.opencode-button.thinking:before{content:"";position:absolute;top:-2px;right:-2px;bottom:-2px;left:-2px;border-radius:50%;background:linear-gradient(135deg,#8b9cf5,#9d6bc7);z-index:-1}.opencode-button.thinking:after{content:"";position:absolute;top:-3px;right:-3px;bottom:-3px;left:-3px;border-radius:50%;background:conic-gradient(from 180deg,transparent,rgba(102,126,234,.3),transparent,rgba(118,75,162,.3),transparent);z-index:-2;animation:thinking-rotate 2s linear infinite reverse;filter:blur(8px)}@keyframes thinking-glow{0%,to{box-shadow:0 0 20px rgba(102,126,234,.6),0 0 40px rgba(118,75,162,.4),0 0 60px rgba(102,126,234,.2)}50%{box-shadow:0 0 30px rgba(102,126,234,.8),0 0 60px rgba(118,75,162,.6),0 0 90px rgba(102,126,234,.3)}}@keyframes thinking-rotate{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes thinking-pulse{0%,to{transform:scale(1)}50%{transform:scale(.95)}}.opencode-button.opencode-theme-dark{background:linear-gradient(135deg,#667eea,#764ba2);box-shadow:0 4px 12px rgba(102,126,234,.3)}.opencode-button.opencode-theme-dark:before{content:"";position:absolute;top:-2px;right:-2px;bottom:-2px;left:-2px;border-radius:50%;background:linear-gradient(135deg,#8b9cf5,#9d6bc7);z-index:-1}.opencode-button.opencode-theme-dark:hover{box-shadow:0 6px 16px rgba(102,126,234,.4)}.opencode-button.opencode-theme-dark svg path{fill:#fff}
|
|
8
|
-
.floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;will-change:transform}.floating-bubble:active{cursor:grabbing}
|
|
8
|
+
.floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;will-change:transform}.floating-bubble:active{cursor:grabbing}body.floating-bubble-dragging *{pointer-events:none!important}body.floating-bubble-dragging .floating-bubble,body.floating-bubble-dragging .floating-bubble *{pointer-events:auto!important}
|
|
9
9
|
/*$vite$:1*/
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import OpenCodeWidget from './open-code-widget';
|
|
2
2
|
import type { App } from 'vue';
|
|
3
|
-
declare const version = "1.0.
|
|
3
|
+
declare const version = "1.0.27";
|
|
4
4
|
declare function install(app: App<any>, options?: any): void;
|
|
5
5
|
export { install, version, OpenCodeWidget };
|
|
6
6
|
export default install;
|
package/lib/index.js
CHANGED
|
@@ -34,7 +34,7 @@ __export(lib_exports, {
|
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(lib_exports);
|
|
36
36
|
var import_open_code_widget = __toESM(require("./open-code-widget"));
|
|
37
|
-
const version = "1.0.
|
|
37
|
+
const version = "1.0.27";
|
|
38
38
|
function install(app, options) {
|
|
39
39
|
const components = [
|
|
40
40
|
import_open_code_widget.default
|
|
@@ -234,35 +234,20 @@ function findFileInfo(element, inspector) {
|
|
|
234
234
|
return fallbackFileInfo || { file: null, line: null, column: null };
|
|
235
235
|
}
|
|
236
236
|
function getPreciseElementAtPoint(x, y, boundary) {
|
|
237
|
-
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
try {
|
|
246
|
-
const elements = document.elementsFromPoint(x, y);
|
|
247
|
-
for (const el of elements) {
|
|
248
|
-
if (el.closest("#vue-inspector-container")) continue;
|
|
249
|
-
if (el.closest(".opencode-widget")) continue;
|
|
250
|
-
if (el.hasAttribute("data-v-inspector-ignore")) continue;
|
|
251
|
-
if (boundary) {
|
|
252
|
-
if (boundary.contains(el) || el === boundary) {
|
|
253
|
-
element = el;
|
|
254
|
-
break;
|
|
255
|
-
}
|
|
256
|
-
} else {
|
|
257
|
-
element = el;
|
|
258
|
-
break;
|
|
237
|
+
const elements = document.elementsFromPoint(x, y);
|
|
238
|
+
for (const el of elements) {
|
|
239
|
+
if (el.closest("#vue-inspector-container")) continue;
|
|
240
|
+
if (el.closest(".opencode-widget")) continue;
|
|
241
|
+
if (el.hasAttribute("data-v-inspector-ignore")) continue;
|
|
242
|
+
if (boundary) {
|
|
243
|
+
if (boundary.contains(el) || el === boundary) {
|
|
244
|
+
return el;
|
|
259
245
|
}
|
|
246
|
+
} else {
|
|
247
|
+
return el;
|
|
260
248
|
}
|
|
261
|
-
} finally {
|
|
262
|
-
if (highlight) highlight.style.display = highlightDisplay;
|
|
263
|
-
if (tooltip) tooltip.style.display = tooltipDisplay;
|
|
264
249
|
}
|
|
265
|
-
return
|
|
250
|
+
return null;
|
|
266
251
|
}
|
|
267
252
|
function useInspector(options) {
|
|
268
253
|
const highlightVisible = (0, import_vue.ref)(false);
|
|
@@ -277,67 +262,99 @@ function useInspector(options) {
|
|
|
277
262
|
const tooltipContent = (0, import_vue.ref)({ description: "", fileInfo: "" });
|
|
278
263
|
const INSPECTOR_CHECK_INTERVAL = 500;
|
|
279
264
|
let inspectorCheckTimer = null;
|
|
265
|
+
let currentHighlightElement = null;
|
|
266
|
+
let currentFileInfo = { file: null, line: null, column: null };
|
|
267
|
+
let currentPrimary = "#3b82f6";
|
|
268
|
+
let currentPrimaryBg = "rgba(59, 130, 246, 0.1)";
|
|
269
|
+
let currentDescription = "";
|
|
270
|
+
let currentFileInfoText = "";
|
|
280
271
|
function handleMouseMoveCore(e) {
|
|
281
272
|
var _a, _b;
|
|
282
273
|
if (!options.selectMode.value) return;
|
|
283
274
|
const inspector = window.__VUE_INSPECTOR__;
|
|
275
|
+
const highlight = document.querySelector(".opencode-element-highlight");
|
|
276
|
+
const tooltip = document.querySelector(".opencode-element-tooltip");
|
|
277
|
+
if (highlight) highlight.style.pointerEvents = "none";
|
|
278
|
+
if (tooltip) tooltip.style.pointerEvents = "none";
|
|
284
279
|
let elementToHighlight = null;
|
|
280
|
+
let targetNode = null;
|
|
285
281
|
let fileInfo = { file: null, line: null, column: null };
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
if (
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
282
|
+
try {
|
|
283
|
+
if (inspector) {
|
|
284
|
+
const result = inspector.getTargetNode(e);
|
|
285
|
+
targetNode = result.targetNode;
|
|
286
|
+
const params = result.params;
|
|
287
|
+
if (targetNode) {
|
|
288
|
+
const preciseElement = getPreciseElementAtPoint(e.clientX, e.clientY, targetNode);
|
|
289
|
+
elementToHighlight = preciseElement || targetNode;
|
|
290
|
+
if (params && params.file) {
|
|
291
|
+
fileInfo = {
|
|
292
|
+
file: params.file,
|
|
293
|
+
line: (_a = params.line) != null ? _a : null,
|
|
294
|
+
column: (_b = params.column) != null ? _b : null
|
|
295
|
+
};
|
|
296
|
+
} else {
|
|
297
|
+
fileInfo = findFileInfo(targetNode, inspector);
|
|
298
|
+
}
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
301
|
+
if (!elementToHighlight) {
|
|
302
|
+
elementToHighlight = getPreciseElementAtPoint(e.clientX, e.clientY, null);
|
|
303
|
+
}
|
|
304
|
+
if (elementToHighlight && !fileInfo.file) {
|
|
305
|
+
fileInfo = getFileInfoFromVueInstance(elementToHighlight) || fileInfo;
|
|
306
|
+
}
|
|
307
|
+
} finally {
|
|
308
|
+
if (highlight) highlight.style.pointerEvents = "";
|
|
309
|
+
if (tooltip) tooltip.style.pointerEvents = "";
|
|
307
310
|
}
|
|
308
311
|
if (elementToHighlight) {
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
312
|
+
const elementChanged = currentHighlightElement !== elementToHighlight;
|
|
313
|
+
if (elementChanged) {
|
|
314
|
+
currentHighlightElement = elementToHighlight;
|
|
315
|
+
currentFileInfo = fileInfo;
|
|
316
|
+
const widget = document.querySelector(".opencode-widget");
|
|
317
|
+
if (widget) {
|
|
318
|
+
const style = getComputedStyle(widget);
|
|
319
|
+
currentPrimary = style.getPropertyValue("--oc-primary").trim() || currentPrimary;
|
|
320
|
+
currentPrimaryBg = style.getPropertyValue("--oc-primary-bg").trim() || currentPrimaryBg;
|
|
321
|
+
}
|
|
322
|
+
currentDescription = getElementDescription(elementToHighlight);
|
|
323
|
+
} else if (!currentFileInfo.file && fileInfo.file) {
|
|
324
|
+
currentFileInfo = fileInfo;
|
|
317
325
|
}
|
|
318
|
-
|
|
319
|
-
highlightStyle.value = {
|
|
320
|
-
top: `${rect.top}px`,
|
|
321
|
-
left: `${rect.left}px`,
|
|
322
|
-
width: `${rect.width}px`,
|
|
323
|
-
height: `${rect.height}px`,
|
|
324
|
-
border: `2px solid ${primary}`,
|
|
325
|
-
background: primaryBg
|
|
326
|
-
};
|
|
327
|
-
const description = getElementDescription(elementToHighlight);
|
|
328
|
-
const fileName = fileInfo.file ? fileInfo.file.split("/").pop() : "";
|
|
326
|
+
const fileName = currentFileInfo.file ? currentFileInfo.file.split("/").pop() : "";
|
|
329
327
|
let lineInfo = "";
|
|
330
|
-
if (
|
|
331
|
-
lineInfo = `:${
|
|
332
|
-
if (
|
|
333
|
-
lineInfo += `:${
|
|
328
|
+
if (currentFileInfo.line) {
|
|
329
|
+
lineInfo = `:${currentFileInfo.line}`;
|
|
330
|
+
if (currentFileInfo.column) {
|
|
331
|
+
lineInfo += `:${currentFileInfo.column}`;
|
|
334
332
|
}
|
|
335
333
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
334
|
+
const newFileInfoText = fileName ? `${fileName}${lineInfo}` : "";
|
|
335
|
+
const fileInfoChanged = currentFileInfoText !== newFileInfoText;
|
|
336
|
+
if (elementChanged || fileInfoChanged) {
|
|
337
|
+
currentFileInfoText = newFileInfoText;
|
|
338
|
+
tooltipContent.value = {
|
|
339
|
+
description: currentDescription,
|
|
340
|
+
fileInfo: currentFileInfoText
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
const rect = elementToHighlight.getBoundingClientRect();
|
|
344
|
+
const newTop = `${rect.top}px`;
|
|
345
|
+
const newLeft = `${rect.left}px`;
|
|
346
|
+
const newWidth = `${rect.width}px`;
|
|
347
|
+
const newHeight = `${rect.height}px`;
|
|
348
|
+
if (highlightStyle.value.top !== newTop || highlightStyle.value.left !== newLeft || highlightStyle.value.width !== newWidth || highlightStyle.value.height !== newHeight) {
|
|
349
|
+
highlightStyle.value = {
|
|
350
|
+
top: newTop,
|
|
351
|
+
left: newLeft,
|
|
352
|
+
width: newWidth,
|
|
353
|
+
height: newHeight,
|
|
354
|
+
border: `2px solid ${currentPrimary}`,
|
|
355
|
+
background: currentPrimaryBg
|
|
356
|
+
};
|
|
357
|
+
}
|
|
341
358
|
const tooltipHeight = 50;
|
|
342
359
|
const tooltipWidth = 200;
|
|
343
360
|
let tooltipTop = rect.top - tooltipHeight - 8;
|
|
@@ -348,13 +365,31 @@ function useInspector(options) {
|
|
|
348
365
|
if (tooltipLeft + tooltipWidth > window.innerWidth - 10) {
|
|
349
366
|
tooltipLeft = window.innerWidth - tooltipWidth - 10;
|
|
350
367
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
368
|
+
const newTooltipTop = `${tooltipTop}px`;
|
|
369
|
+
const newTooltipLeft = `${tooltipLeft}px`;
|
|
370
|
+
if (tooltipStyle.value.top !== newTooltipTop || tooltipStyle.value.left !== newTooltipLeft) {
|
|
371
|
+
tooltipStyle.value = {
|
|
372
|
+
top: newTooltipTop,
|
|
373
|
+
left: newTooltipLeft
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
if (!highlightVisible.value) {
|
|
377
|
+
highlightVisible.value = true;
|
|
378
|
+
}
|
|
379
|
+
if (!tooltipVisible.value) {
|
|
380
|
+
tooltipVisible.value = true;
|
|
381
|
+
}
|
|
355
382
|
} else {
|
|
356
|
-
|
|
357
|
-
|
|
383
|
+
currentHighlightElement = null;
|
|
384
|
+
currentDescription = "";
|
|
385
|
+
currentFileInfoText = "";
|
|
386
|
+
currentFileInfo = { file: null, line: null, column: null };
|
|
387
|
+
if (highlightVisible.value) {
|
|
388
|
+
highlightVisible.value = false;
|
|
389
|
+
}
|
|
390
|
+
if (tooltipVisible.value) {
|
|
391
|
+
tooltipVisible.value = false;
|
|
392
|
+
}
|
|
358
393
|
}
|
|
359
394
|
}
|
|
360
395
|
const handleMouseMove = throttle(handleMouseMoveCore, 16);
|
|
@@ -426,6 +461,10 @@ function useInspector(options) {
|
|
|
426
461
|
}
|
|
427
462
|
document.removeEventListener("mousemove", handleMouseMove);
|
|
428
463
|
document.removeEventListener("keydown", handleKeydown, true);
|
|
464
|
+
currentHighlightElement = null;
|
|
465
|
+
currentDescription = "";
|
|
466
|
+
currentFileInfoText = "";
|
|
467
|
+
currentFileInfo = { file: null, line: null, column: null };
|
|
429
468
|
highlightVisible.value = false;
|
|
430
469
|
tooltipVisible.value = false;
|
|
431
470
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Ref } from "vue";
|
|
2
|
+
import type { FloatingBubbleOffset } from "../src/components/FloatingBubble/types";
|
|
3
|
+
import type { OpenCodeWidgetTheme } from "../src/types";
|
|
4
|
+
export interface WidgetPersistState {
|
|
5
|
+
open: boolean;
|
|
6
|
+
minimized: boolean;
|
|
7
|
+
promptDockVisible: boolean;
|
|
8
|
+
bubbleOffset?: FloatingBubbleOffset;
|
|
9
|
+
theme: OpenCodeWidgetTheme;
|
|
10
|
+
sessionListCollapsed: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface UsePersistStateOptions {
|
|
13
|
+
open: Ref<boolean>;
|
|
14
|
+
minimized: Ref<boolean>;
|
|
15
|
+
promptDockVisible: Ref<boolean>;
|
|
16
|
+
bubbleOffset: Ref<FloatingBubbleOffset | undefined>;
|
|
17
|
+
theme: Ref<OpenCodeWidgetTheme>;
|
|
18
|
+
sessionListCollapsed: Ref<boolean>;
|
|
19
|
+
onRestore?: (state: Partial<WidgetPersistState>) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare function usePersistState(options: UsePersistStateOptions): {
|
|
22
|
+
restoreState: () => Partial<WidgetPersistState> | null;
|
|
23
|
+
persistState: () => void;
|
|
24
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var use_persist_state_exports = {};
|
|
19
|
+
__export(use_persist_state_exports, {
|
|
20
|
+
usePersistState: () => usePersistState
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(use_persist_state_exports);
|
|
23
|
+
var import_vue = require("vue");
|
|
24
|
+
const STORAGE_KEY = "opencode-widget-state";
|
|
25
|
+
function loadState() {
|
|
26
|
+
if (typeof window === "undefined") return null;
|
|
27
|
+
try {
|
|
28
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
29
|
+
if (stored) {
|
|
30
|
+
return JSON.parse(stored);
|
|
31
|
+
}
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.warn("[OpenCodeWidget] Failed to load persisted state:", e);
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
function saveState(state) {
|
|
38
|
+
if (typeof window === "undefined") return;
|
|
39
|
+
try {
|
|
40
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
|
|
41
|
+
} catch (e) {
|
|
42
|
+
console.warn("[OpenCodeWidget] Failed to save state:", e);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function usePersistState(options) {
|
|
46
|
+
const restoreState = () => {
|
|
47
|
+
const saved = loadState();
|
|
48
|
+
if (options.onRestore) {
|
|
49
|
+
options.onRestore(saved || {});
|
|
50
|
+
}
|
|
51
|
+
return saved;
|
|
52
|
+
};
|
|
53
|
+
const getCurrentState = () => ({
|
|
54
|
+
open: options.open.value,
|
|
55
|
+
minimized: options.minimized.value,
|
|
56
|
+
promptDockVisible: options.promptDockVisible.value,
|
|
57
|
+
bubbleOffset: options.bubbleOffset.value,
|
|
58
|
+
theme: options.theme.value,
|
|
59
|
+
sessionListCollapsed: options.sessionListCollapsed.value
|
|
60
|
+
});
|
|
61
|
+
const persistState = () => {
|
|
62
|
+
saveState(getCurrentState());
|
|
63
|
+
};
|
|
64
|
+
(0, import_vue.onMounted)(() => {
|
|
65
|
+
restoreState();
|
|
66
|
+
(0, import_vue.watch)(
|
|
67
|
+
[options.open, options.minimized, options.promptDockVisible, options.bubbleOffset, options.theme, options.sessionListCollapsed],
|
|
68
|
+
() => {
|
|
69
|
+
persistState();
|
|
70
|
+
},
|
|
71
|
+
{ deep: true }
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
restoreState,
|
|
76
|
+
persistState
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;will-change:transform}.floating-bubble:active{cursor:grabbing}
|
|
1
|
+
.floating-bubble{position:fixed;top:0;left:0;z-index:999999;cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none;touch-action:none;will-change:transform}.floating-bubble:active{cursor:grabbing}body.floating-bubble-dragging *{pointer-events:none!important}body.floating-bubble-dragging .floating-bubble,body.floating-bubble-dragging .floating-bubble *{pointer-events:auto!important}
|
|
@@ -16,14 +16,14 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {
|
|
|
16
16
|
y: number;
|
|
17
17
|
}>;
|
|
18
18
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
19
|
-
click: (event: MouseEvent) => any;
|
|
20
19
|
"update:offset": (value: FloatingBubbleOffset) => any;
|
|
20
|
+
click: (event: MouseEvent) => any;
|
|
21
21
|
"offset-change": (offset: FloatingBubbleOffset) => any;
|
|
22
22
|
"drag-start": () => any;
|
|
23
23
|
"drag-end": () => any;
|
|
24
24
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
25
|
-
onClick?: ((event: MouseEvent) => any) | undefined;
|
|
26
25
|
"onUpdate:offset"?: ((value: FloatingBubbleOffset) => any) | undefined;
|
|
26
|
+
onClick?: ((event: MouseEvent) => any) | undefined;
|
|
27
27
|
"onOffset-change"?: ((offset: FloatingBubbleOffset) => any) | undefined;
|
|
28
28
|
"onDrag-start"?: (() => any) | undefined;
|
|
29
29
|
"onDrag-end"?: (() => any) | undefined;
|
|
@@ -78,6 +78,27 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
78
78
|
bottom: windowHeight.value - state.value.height - gapY.value,
|
|
79
79
|
left: gapX.value
|
|
80
80
|
}));
|
|
81
|
+
const closest = (arr, target) => {
|
|
82
|
+
return arr.reduce(
|
|
83
|
+
(pre, cur) => Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
const applyMagnetic = () => {
|
|
87
|
+
if (props.magnetic === "x") {
|
|
88
|
+
const nextX = closest(
|
|
89
|
+
[boundary.value.left, boundary.value.right],
|
|
90
|
+
state.value.x
|
|
91
|
+
);
|
|
92
|
+
state.value.x = nextX;
|
|
93
|
+
}
|
|
94
|
+
if (props.magnetic === "y") {
|
|
95
|
+
const nextY = closest(
|
|
96
|
+
[boundary.value.top, boundary.value.bottom],
|
|
97
|
+
state.value.y
|
|
98
|
+
);
|
|
99
|
+
state.value.y = nextY;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
81
102
|
const dragging = (0, import_vue2.ref)(false);
|
|
82
103
|
const initialized = (0, import_vue2.ref)(false);
|
|
83
104
|
const rootStyle = (0, import_vue2.computed)(() => {
|
|
@@ -104,12 +125,22 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
104
125
|
if (x > maxX) x = maxX;
|
|
105
126
|
if (y < gapY.value) y = gapY.value;
|
|
106
127
|
if (y > maxY) y = maxY;
|
|
128
|
+
const oldX = state.value.x;
|
|
129
|
+
const oldY = state.value.y;
|
|
107
130
|
state.value = {
|
|
108
131
|
x,
|
|
109
132
|
y,
|
|
110
133
|
width: rect.width,
|
|
111
134
|
height: rect.height
|
|
112
135
|
};
|
|
136
|
+
if (!dragging.value) {
|
|
137
|
+
applyMagnetic();
|
|
138
|
+
if (state.value.x !== oldX || state.value.y !== oldY) {
|
|
139
|
+
const offset2 = { x: state.value.x, y: state.value.y };
|
|
140
|
+
emit("update:offset", offset2);
|
|
141
|
+
emit("offset-change", offset2);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
113
144
|
};
|
|
114
145
|
const touch = {
|
|
115
146
|
startX: (0, import_vue2.ref)(0),
|
|
@@ -148,6 +179,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
148
179
|
dragging.value = true;
|
|
149
180
|
prevX = state.value.x;
|
|
150
181
|
prevY = state.value.y;
|
|
182
|
+
document.body.classList.add("floating-bubble-dragging");
|
|
151
183
|
if (!("touches" in e)) {
|
|
152
184
|
window.addEventListener("mousemove", onTouchMove, { passive: false });
|
|
153
185
|
window.addEventListener("mouseup", onTouchEnd);
|
|
@@ -180,32 +212,15 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
180
212
|
emit("update:offset", offset);
|
|
181
213
|
}
|
|
182
214
|
};
|
|
183
|
-
const closest = (arr, target) => {
|
|
184
|
-
return arr.reduce(
|
|
185
|
-
(pre, cur) => Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
|
|
186
|
-
);
|
|
187
|
-
};
|
|
188
215
|
const onTouchEnd = (e) => {
|
|
189
216
|
dragging.value = false;
|
|
217
|
+
document.body.classList.remove("floating-bubble-dragging");
|
|
190
218
|
if (e && !("touches" in e) && e.type === "mouseup") {
|
|
191
219
|
window.removeEventListener("mousemove", onTouchMove);
|
|
192
220
|
window.removeEventListener("mouseup", onTouchEnd);
|
|
193
221
|
}
|
|
194
222
|
requestAnimationFrame(() => {
|
|
195
|
-
|
|
196
|
-
const nextX = closest(
|
|
197
|
-
[boundary.value.left, boundary.value.right],
|
|
198
|
-
state.value.x
|
|
199
|
-
);
|
|
200
|
-
state.value.x = nextX;
|
|
201
|
-
}
|
|
202
|
-
if (props.magnetic === "y") {
|
|
203
|
-
const nextY = closest(
|
|
204
|
-
[boundary.value.top, boundary.value.bottom],
|
|
205
|
-
state.value.y
|
|
206
|
-
);
|
|
207
|
-
state.value.y = nextY;
|
|
208
|
-
}
|
|
223
|
+
applyMagnetic();
|
|
209
224
|
if (!touch.isTap.value) {
|
|
210
225
|
emit("drag-end");
|
|
211
226
|
const offset = { x: state.value.x, y: state.value.y };
|
|
@@ -244,6 +259,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
244
259
|
}
|
|
245
260
|
});
|
|
246
261
|
(0, import_vue2.onUnmounted)(() => {
|
|
262
|
+
document.body.classList.remove("floating-bubble-dragging");
|
|
247
263
|
if (typeof window !== "undefined") {
|
|
248
264
|
window.removeEventListener("resize", handleResize);
|
|
249
265
|
window.removeEventListener("mousemove", onTouchMove);
|
|
@@ -261,7 +277,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
261
277
|
__expose({
|
|
262
278
|
offset: (0, import_vue2.computed)(() => ({ x: state.value.x, y: state.value.y }))
|
|
263
279
|
});
|
|
264
|
-
const __returned__ = { props, emit, rootRef, state, isObject, gapX, gapY, windowWidth, windowHeight, boundary, dragging, initialized, rootStyle, updateState, touch, get prevX() {
|
|
280
|
+
const __returned__ = { props, emit, rootRef, state, isObject, gapX, gapY, windowWidth, windowHeight, boundary, closest, applyMagnetic, dragging, initialized, rootStyle, updateState, touch, get prevX() {
|
|
265
281
|
return prevX;
|
|
266
282
|
}, set prevX(v) {
|
|
267
283
|
prevX = v;
|
|
@@ -269,7 +285,7 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)(__spreadProp
|
|
|
269
285
|
return prevY;
|
|
270
286
|
}, set prevY(v) {
|
|
271
287
|
prevY = v;
|
|
272
|
-
}, onTouchStart, onTouchMove,
|
|
288
|
+
}, onTouchStart, onTouchMove, onTouchEnd, onClick, handleResize };
|
|
273
289
|
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
|
|
274
290
|
return __returned__;
|
|
275
291
|
}
|
|
@@ -12,11 +12,9 @@ declare const __VLS_component: import("vue").DefineComponent<{}, {
|
|
|
12
12
|
y: number;
|
|
13
13
|
} | undefined>;
|
|
14
14
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
15
|
-
"offset-change": (offset: FloatingBubbleOffset | undefined) => any;
|
|
16
15
|
"drag-start": () => any;
|
|
17
16
|
"drag-end": () => any;
|
|
18
17
|
}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
|
|
19
|
-
"onOffset-change"?: ((offset: FloatingBubbleOffset | undefined) => any) | undefined;
|
|
20
18
|
"onDrag-start"?: (() => any) | undefined;
|
|
21
19
|
"onDrag-end"?: (() => any) | undefined;
|
|
22
20
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -36,10 +36,9 @@ var import_vue2 = require("vue");
|
|
|
36
36
|
var import_context = require("../context");
|
|
37
37
|
var import_FloatingBubble_vue = __toESM(require("./FloatingBubble/FloatingBubble.vue.js"));
|
|
38
38
|
var import_vue3 = require("vue");
|
|
39
|
-
const STORAGE_KEY = "opencode-bubble-offset";
|
|
40
39
|
const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)({
|
|
41
40
|
__name: "Trigger",
|
|
42
|
-
emits: ["
|
|
41
|
+
emits: ["drag-start", "drag-end"],
|
|
43
42
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
44
43
|
const {
|
|
45
44
|
buttonActive: active,
|
|
@@ -47,39 +46,23 @@ const __vue_sfc__ = /* @__PURE__ */ (0, import_vue.defineComponent)({
|
|
|
47
46
|
hotkeyLabel,
|
|
48
47
|
thinking,
|
|
49
48
|
resolvedTheme,
|
|
50
|
-
handleToggle
|
|
49
|
+
handleToggle,
|
|
50
|
+
bubbleOffset,
|
|
51
|
+
handleBubbleOffsetChange
|
|
51
52
|
} = (0, import_context.useOpenCodeWidgetContext)();
|
|
52
|
-
const
|
|
53
|
-
try {
|
|
54
|
-
const saved = localStorage.getItem(STORAGE_KEY);
|
|
55
|
-
if (saved) {
|
|
56
|
-
const parsed = JSON.parse(saved);
|
|
57
|
-
if (parsed && (parsed.x !== 0 || parsed.y !== 0)) {
|
|
58
|
-
return parsed;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
} catch (e) {
|
|
62
|
-
}
|
|
63
|
-
return void 0;
|
|
64
|
-
};
|
|
65
|
-
const offset = (0, import_vue2.ref)(loadOffset());
|
|
53
|
+
const offset = (0, import_vue2.ref)(bubbleOffset.value);
|
|
66
54
|
const emit = __emit;
|
|
67
|
-
const saveOffset = (value) => {
|
|
68
|
-
try {
|
|
69
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(value));
|
|
70
|
-
} catch (e) {
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
55
|
const handleOffsetChange = (value) => {
|
|
74
56
|
offset.value = value;
|
|
75
|
-
|
|
76
|
-
emit("offset-change", value);
|
|
57
|
+
handleBubbleOffsetChange(value);
|
|
77
58
|
};
|
|
78
|
-
(0, import_vue2.watch)(
|
|
59
|
+
(0, import_vue2.watch)(bubbleOffset, (newOffset) => {
|
|
60
|
+
offset.value = newOffset;
|
|
61
|
+
});
|
|
79
62
|
__expose({
|
|
80
63
|
offset
|
|
81
64
|
});
|
|
82
|
-
const __returned__ = { active, open, hotkeyLabel, thinking, resolvedTheme, handleToggle,
|
|
65
|
+
const __returned__ = { active, open, hotkeyLabel, thinking, resolvedTheme, handleToggle, bubbleOffset, handleBubbleOffsetChange, offset, emit, handleOffsetChange, FloatingBubble: import_FloatingBubble_vue.default };
|
|
83
66
|
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
|
|
84
67
|
return __returned__;
|
|
85
68
|
}
|