pinokiod 3.92.0 → 3.93.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.92.0",
3
+ "version": "3.93.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -105,6 +105,11 @@ body.dark .capture-modal-button.secondary{background:rgba(148,163,184,0.2);color
105
105
  this.overlayHidden = false;
106
106
  this.floatingControls = null;
107
107
  this.floatingStatus = null;
108
+ this.floatingDrag = null;
109
+ this.onFloatingPointerDown = this.startFloatingDrag.bind(this);
110
+ this.onFloatingPointerMove = this.handleFloatingPointerMove.bind(this);
111
+ this.onFloatingPointerUp = (event) => this.stopFloatingDrag(event);
112
+ this.onFloatingWindowResize = this.handleFloatingResize.bind(this);
108
113
  this.resolveFn = null;
109
114
  this.rejectFn = null;
110
115
  this.colorDefault = '#ddd';
@@ -991,7 +996,7 @@ body.dark .capture-modal-button.secondary{background:rgba(148,163,184,0.2);color
991
996
  color:#fff; padding:10px 14px; border-radius:12px;
992
997
  box-shadow:0 8px 24px rgba(0,0,0,0.35);
993
998
  font-size:14px; font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
994
- pointer-events:auto;
999
+ pointer-events:auto; cursor:grab; touch-action:none;
995
1000
  `;
996
1001
 
997
1002
  const status = document.createElement('div');
@@ -1012,11 +1017,25 @@ body.dark .capture-modal-button.secondary{background:rgba(148,163,184,0.2);color
1012
1017
 
1013
1018
  controls.append(status, stopBtn);
1014
1019
  document.body.appendChild(controls);
1020
+ const rect = controls.getBoundingClientRect();
1021
+ const initial = this.clampFloatingPosition(rect);
1022
+ controls.style.left = `${initial.left}px`;
1023
+ controls.style.top = `${initial.top}px`;
1024
+ controls.style.right = 'auto';
1025
+ controls.style.bottom = 'auto';
1015
1026
  this.floatingControls = controls;
1016
1027
  this.floatingStatus = status;
1028
+
1029
+ controls.addEventListener('pointerdown', this.onFloatingPointerDown);
1030
+ window.addEventListener('resize', this.onFloatingWindowResize, { passive: true });
1017
1031
  }
1018
1032
 
1019
1033
  removeFloatingControls() {
1034
+ this.stopFloatingDrag();
1035
+ if (this.floatingControls) {
1036
+ this.floatingControls.removeEventListener('pointerdown', this.onFloatingPointerDown);
1037
+ }
1038
+ window.removeEventListener('resize', this.onFloatingWindowResize);
1020
1039
  if (this.floatingControls && this.floatingControls.parentNode) {
1021
1040
  this.floatingControls.parentNode.removeChild(this.floatingControls);
1022
1041
  }
@@ -1024,6 +1043,90 @@ body.dark .capture-modal-button.secondary{background:rgba(148,163,184,0.2);color
1024
1043
  this.floatingStatus = null;
1025
1044
  }
1026
1045
 
1046
+ clampFloatingPosition(rect) {
1047
+ const margin = 8;
1048
+ const maxLeft = Math.max(margin, window.innerWidth - rect.width - margin);
1049
+ const maxTop = Math.max(margin, window.innerHeight - rect.height - margin);
1050
+ const left = Math.min(Math.max(rect.left, margin), maxLeft);
1051
+ const top = Math.min(Math.max(rect.top, margin), maxTop);
1052
+ return { left, top };
1053
+ }
1054
+
1055
+ startFloatingDrag(event) {
1056
+ if (!this.floatingControls || event.button !== 0) return;
1057
+ if (event.target && event.target.closest('button')) return;
1058
+ const rect = this.floatingControls.getBoundingClientRect();
1059
+ const { left, top } = this.clampFloatingPosition(rect);
1060
+ this.floatingControls.style.left = `${left}px`;
1061
+ this.floatingControls.style.top = `${top}px`;
1062
+ this.floatingControls.style.right = 'auto';
1063
+ this.floatingControls.style.bottom = 'auto';
1064
+
1065
+ this.floatingDrag = {
1066
+ pointerId: event.pointerId,
1067
+ startX: event.clientX,
1068
+ startY: event.clientY,
1069
+ baseLeft: left,
1070
+ baseTop: top
1071
+ };
1072
+
1073
+ if (this.floatingControls.setPointerCapture) {
1074
+ try {
1075
+ this.floatingControls.setPointerCapture(event.pointerId);
1076
+ } catch (_) {
1077
+ // Ignore inability to capture pointer (e.g., already captured).
1078
+ }
1079
+ }
1080
+ this.floatingControls.style.cursor = 'grabbing';
1081
+ window.addEventListener('pointermove', this.onFloatingPointerMove);
1082
+ window.addEventListener('pointerup', this.onFloatingPointerUp);
1083
+ window.addEventListener('pointercancel', this.onFloatingPointerUp);
1084
+ }
1085
+
1086
+ handleFloatingPointerMove(event) {
1087
+ if (!this.floatingDrag || event.pointerId !== this.floatingDrag.pointerId || !this.floatingControls) return;
1088
+ const dx = event.clientX - this.floatingDrag.startX;
1089
+ const dy = event.clientY - this.floatingDrag.startY;
1090
+ const proposed = {
1091
+ left: this.floatingDrag.baseLeft + dx,
1092
+ top: this.floatingDrag.baseTop + dy,
1093
+ width: this.floatingControls.offsetWidth,
1094
+ height: this.floatingControls.offsetHeight
1095
+ };
1096
+ const clamped = this.clampFloatingPosition(proposed);
1097
+ this.floatingControls.style.left = `${clamped.left}px`;
1098
+ this.floatingControls.style.top = `${clamped.top}px`;
1099
+ }
1100
+
1101
+ stopFloatingDrag(event) {
1102
+ if (!this.floatingDrag) return;
1103
+ if (event && this.floatingDrag.pointerId !== event.pointerId) return;
1104
+ window.removeEventListener('pointermove', this.onFloatingPointerMove);
1105
+ window.removeEventListener('pointerup', this.onFloatingPointerUp);
1106
+ window.removeEventListener('pointercancel', this.onFloatingPointerUp);
1107
+ if (this.floatingControls && this.floatingControls.releasePointerCapture && this.floatingDrag.pointerId != null) {
1108
+ try {
1109
+ this.floatingControls.releasePointerCapture(this.floatingDrag.pointerId);
1110
+ } catch (_) {
1111
+ // Ignore release errors (e.g., pointer already released).
1112
+ }
1113
+ }
1114
+ if (this.floatingControls) {
1115
+ this.floatingControls.style.cursor = 'grab';
1116
+ }
1117
+ this.floatingDrag = null;
1118
+ }
1119
+
1120
+ handleFloatingResize() {
1121
+ if (!this.floatingControls) return;
1122
+ const rect = this.floatingControls.getBoundingClientRect();
1123
+ const clamped = this.clampFloatingPosition(rect);
1124
+ this.floatingControls.style.left = `${clamped.left}px`;
1125
+ this.floatingControls.style.top = `${clamped.top}px`;
1126
+ this.floatingControls.style.right = 'auto';
1127
+ this.floatingControls.style.bottom = 'auto';
1128
+ }
1129
+
1027
1130
  formatDuration(ms) {
1028
1131
  const totalSeconds = Math.floor(ms / 1000);
1029
1132
  const minutes = String(Math.floor(totalSeconds / 60)).padStart(2, '0');