@marsaude/devtools-shell 0.1.6 → 0.1.7

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.
@@ -220,7 +220,8 @@ class DevtoolsShellComponent {
220
220
  cursor: this.dragging() ? 'grabbing' : 'grab',
221
221
  };
222
222
  }, ...(ngDevMode ? [{ debugName: "fabStyle" }] : []));
223
- /** Radial speed-dial geometry — ported verbatim (R=268, 5°→87°). */
223
+ /** Radial speed-dial geometry — items fan along a 5°→87° arc; the radius
224
+ * scales with the item count (clamped to the viewport) so they never pile up. */
224
225
  this.dialItems = computed(() => {
225
226
  const S = FAB_SIZE;
226
227
  const W = this.winW();
@@ -233,12 +234,26 @@ class DevtoolsShellComponent {
233
234
  const vy = cy < H * 0.42 ? 1 : -1;
234
235
  const acts = this.actions();
235
236
  const N = acts.length;
236
- const R = 268;
237
237
  const a0 = (5 * Math.PI) / 180;
238
238
  const a1 = (87 * Math.PI) / 180;
239
+ const span = a1 - a0;
240
+ // Tile box + the center-to-center spacing we want between adjacent items.
241
+ // Smaller SPACING pulls the whole fan in closer to the FAB (since every
242
+ // item sits at the same radius R), while staying just above the tile size
243
+ // so they don't overlap.
244
+ const TILE_W = 50;
245
+ const TILE_H = 44;
246
+ const SPACING = 52;
247
+ // Radius that yields that spacing across N items, clamped so the farthest
248
+ // tile still fits the viewport in the fan direction. Scaling R with N is
249
+ // what keeps the items from piling on top of each other as more are added.
250
+ const desiredR = N > 1 ? (SPACING * (N - 1)) / span : 200;
251
+ const availH = (hx > 0 ? W - cx : cx) - TILE_W / 2 - 12;
252
+ const availV = (vy > 0 ? H - cy : cy) - TILE_H / 2 - 12;
253
+ const R = Math.max(160, Math.min(desiredR, availH, availV));
239
254
  return acts.map((action, i) => {
240
255
  const t = N === 1 ? 0.5 : i / (N - 1);
241
- const ang = a0 + (a1 - a0) * t;
256
+ const ang = a0 + span * t;
242
257
  const dx = hx * Math.cos(ang) * R;
243
258
  const dy = vy * Math.sin(ang) * R;
244
259
  return {
@@ -246,10 +261,10 @@ class DevtoolsShellComponent {
246
261
  style: {
247
262
  position: 'fixed',
248
263
  zIndex: '41',
249
- width: '58px',
250
- height: '50px',
251
- left: cx - 29 + 'px',
252
- top: cy - 25 + 'px',
264
+ width: TILE_W + 'px',
265
+ height: TILE_H + 'px',
266
+ left: cx - TILE_W / 2 + 'px',
267
+ top: cy - TILE_H / 2 + 'px',
253
268
  display: 'flex',
254
269
  flexDirection: 'column',
255
270
  alignItems: 'center',
@@ -1701,6 +1716,22 @@ class DevtoolsTelemetryService {
1701
1716
  return {};
1702
1717
  }
1703
1718
  }
1719
+ /** Decode an arraybuffer response to text/JSON; fall back to a size label if binary. */
1720
+ decodeArrayBuffer(buf) {
1721
+ if (!buf)
1722
+ return null;
1723
+ try {
1724
+ const text = new TextDecoder().decode(buf);
1725
+ const parsed = this.tryParse(text);
1726
+ if (typeof parsed !== 'string')
1727
+ return parsed; // parsed JSON object/array/number
1728
+ // Raw string: keep only if it looks like text, otherwise it's binary.
1729
+ return /[\u0000-\u0008\u000e-\u001f]/.test(parsed) ? `[arraybuffer ${buf.byteLength}b]` : parsed;
1730
+ }
1731
+ catch {
1732
+ return `[arraybuffer ${buf.byteLength ?? '?'}b]`;
1733
+ }
1734
+ }
1704
1735
  tryParse(text) {
1705
1736
  if (text == null || text === '')
1706
1737
  return null;
@@ -1811,6 +1842,10 @@ class DevtoolsTelemetryService {
1811
1842
  responseBody = self.tryParse(this.responseText);
1812
1843
  else if (type === 'json')
1813
1844
  responseBody = this.response;
1845
+ else if (type === 'arraybuffer')
1846
+ responseBody = self.decodeArrayBuffer(this.response);
1847
+ else if (type === 'blob')
1848
+ responseBody = `[blob ${this.response?.size ?? '?'}b]`;
1814
1849
  else
1815
1850
  responseBody = `[${type}]`;
1816
1851
  }