contactsheet 0.1.9 → 0.1.10

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.
@@ -363,10 +363,50 @@ ${board.entry.kind} \xB7 ${board.entry.id}`);
363
363
  }
364
364
  }
365
365
  var UPLOADING = "__uploading__";
366
- function removeRefToken(text, idx1) {
367
- return text.replace(new RegExp(`\\[\u56FE\u7247 ${idx1}\\]`, "g"), "").replace(/\[图片 (\d+)\]/g, (m, d) => {
366
+ function renumberAfter(text, removed) {
367
+ return text.replace(/\[图片 (\d+)\]/g, (m, d) => {
368
368
  const n = Number(d);
369
- return n > idx1 ? `[\u56FE\u7247 ${n - 1}]` : m;
369
+ return n > removed ? `[\u56FE\u7247 ${n - 1}]` : m;
370
+ });
371
+ }
372
+ function removeRefToken(text, idx1) {
373
+ return renumberAfter(text.replace(new RegExp(`\\[\u56FE\u7247 ${idx1}\\]`, "g"), ""), idx1);
374
+ }
375
+ function bindTokenAtomics(ta, refs, redraw) {
376
+ ta.addEventListener("keydown", (e) => {
377
+ if (e.key !== "Backspace" && e.key !== "Delete") return;
378
+ const tokens = [...ta.value.matchAll(/\[图片 (\d+)\]/g)].map((m) => ({
379
+ n: Number(m[1]),
380
+ start: m.index ?? 0,
381
+ end: (m.index ?? 0) + m[0].length
382
+ }));
383
+ if (tokens.length === 0) return;
384
+ const s = ta.selectionStart ?? 0;
385
+ const t = ta.selectionEnd ?? s;
386
+ const dropRefs = (nums) => {
387
+ for (const n of [...nums].sort((a, b) => b - a)) {
388
+ refs.splice(n - 1, 1);
389
+ ta.value = renumberAfter(ta.value, n);
390
+ }
391
+ redraw();
392
+ };
393
+ if (s === t) {
394
+ const hit = tokens.find((k) => e.key === "Backspace" ? s > k.start && s <= k.end : s >= k.start && s < k.end);
395
+ if (!hit) return;
396
+ e.preventDefault();
397
+ ta.setRangeText("", hit.start, hit.end, "start");
398
+ dropRefs([hit.n]);
399
+ ta.setSelectionRange(hit.start, hit.start);
400
+ return;
401
+ }
402
+ const touched = tokens.filter((k) => k.start < t && k.end > s);
403
+ if (touched.length === 0) return;
404
+ e.preventDefault();
405
+ const ns = Math.min(s, ...touched.map((k) => k.start));
406
+ const ne = Math.max(t, ...touched.map((k) => k.end));
407
+ ta.setRangeText("", ns, ne, "start");
408
+ dropRefs(touched.map((k) => k.n));
409
+ ta.setSelectionRange(ns, ns);
370
410
  });
371
411
  }
372
412
  function insertAtCursor(ta, token) {
@@ -748,6 +788,7 @@ ${board.entry.kind} \xB7 ${board.entry.id}`);
748
788
  function renderPins() {
749
789
  for (const board of state.boards.values()) renderBoardPins(board);
750
790
  }
791
+ var orphanRetries = /* @__PURE__ */ new Map();
751
792
  function renderBoardPins(board) {
752
793
  const layer = board.pinLayerEl;
753
794
  layer.textContent = "";
@@ -796,6 +837,21 @@ ${board.entry.kind} \xB7 ${board.entry.id}`);
796
837
  attachHoverGrace(pin);
797
838
  layer.appendChild(pin);
798
839
  });
840
+ const id = board.entry.id;
841
+ if (layer.querySelector(".cs-pin.is-orphan")) {
842
+ const n = orphanRetries.get(id) ?? 0;
843
+ if (n < 8) {
844
+ orphanRetries.set(id, n + 1);
845
+ setTimeout(() => {
846
+ const b = state.boards.get(id);
847
+ if (!b) return;
848
+ if (b.pinLayerEl.querySelector(".is-editing")) return;
849
+ renderBoardPins(b);
850
+ }, 600 * (n + 1));
851
+ }
852
+ } else {
853
+ orphanRetries.delete(id);
854
+ }
799
855
  }
800
856
  var selectedPinId = null;
801
857
  function selectedPin() {
@@ -928,6 +984,7 @@ ${board.entry.kind} \xB7 ${board.entry.id}`);
928
984
  strip = next;
929
985
  };
930
986
  redrawStrip();
987
+ bindTokenAtomics(ta, refs, redrawStrip);
931
988
  setPasteTarget({
932
989
  el: box,
933
990
  onFile: (file) => attachInline(ta, refs, file, redrawStrip)
@@ -1101,6 +1158,7 @@ ${board.entry.kind} \xB7 ${board.entry.id}`);
1101
1158
  stripEl.replaceWith(next);
1102
1159
  stripEl = next;
1103
1160
  };
1161
+ bindTokenAtomics(ta, refs, redrawStrip);
1104
1162
  setPasteTarget({
1105
1163
  el: box,
1106
1164
  onFile: (file) => attachInline(ta, refs, file, redrawStrip)