hh-shipments 0.3.6 → 0.3.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.
package/package.json CHANGED
@@ -18,7 +18,7 @@
18
18
  "test": "node test/run-tests.js && node test/run-carriers-tests.js"
19
19
  },
20
20
  "type": "commonjs",
21
- "version": "0.3.6",
21
+ "version": "0.3.7",
22
22
  "bin": {
23
23
  "hh-shipments": "server.js"
24
24
  },
package/public/app.js CHANGED
@@ -169,7 +169,10 @@ async function ocrFile(file, statusEl) {
169
169
  }
170
170
 
171
171
  async function handlePhotoFile(f) {
172
+ const target = $('photo-result');
172
173
  try {
174
+ const url = URL.createObjectURL(f);
175
+ target.innerHTML = `<div class="review"><img src="${url}" style="max-width:100%;border-radius:10px"><p class="muted">📖 Reading screenshot…</p></div>`;
173
176
  const text = await ocrFile(f, $('ocr-status'));
174
177
  // Upload original for reference, then run the quick flow on OCR text
175
178
  const fd = new FormData();
@@ -203,25 +206,31 @@ function pastedImageFiles(e) {
203
206
  return files;
204
207
  }
205
208
 
206
- // Paste-text tab: pasting a screenshot runs OCR and extracts tracking numbers;
207
- // pasting plain text behaves normally
209
+ // Paste-text tab: pasting a screenshot runs OCR and extracts automatically —
210
+ // no "Extract" tap needed. Plain text paste still lands in the textarea.
208
211
  async function handlePastedImageFile(f) {
212
+ const target = $('quick-result');
209
213
  try {
214
+ // Instant feedback: show a thumbnail + progress the moment the image lands
215
+ const url = URL.createObjectURL(f);
216
+ target.innerHTML = `<div class="review"><img src="${url}" style="max-width:100%;border-radius:10px"><p class="muted" id="ocr-live">📖 Reading screenshot…</p></div>`;
210
217
  const text = await ocrFile(f, $('ocr-status-paste'));
218
+ const live = $('ocr-live');
219
+ if (live) live.textContent = '🔍 Finding tracking number…';
211
220
  const fd = new FormData();
212
221
  fd.append('image', f);
213
222
  const up = await fetch('/api/intake/image', { method: 'POST', body: fd });
214
223
  if (!up.ok) throw new Error('upload failed');
215
- const r = await runQuick(text, $('quick-result'));
216
- if (r && !r.added.length && !r.needs_review.length && !r.duplicates.length) showOcrRead($('quick-result'), text);
217
- } catch (err) { $('ocr-status-paste').textContent = ''; $('quick-result').innerHTML = `<p class="error">${esc(err.message)}</p>`; }
224
+ const r = await runQuick(text, target);
225
+ if (r && !r.added.length && !r.needs_review.length && !r.duplicates.length) showOcrRead(target, text);
226
+ } catch (err) { $('ocr-status-paste').textContent = ''; target.innerHTML = `<p class="error">${esc(err.message)}</p>`; }
218
227
  }
219
228
 
220
229
  $('tab-paste').addEventListener('paste', async (e) => {
221
230
  const files = pastedImageFiles(e);
222
231
  if (!files.length) return; // text paste — let it land in the textarea
223
232
  e.preventDefault();
224
- $('paste-box').innerHTML = '📋 <span class="muted">or tap here, then paste a screenshot</span>';
233
+ $('paste-box').innerHTML = '📋 <span class="muted">or tap here and paste a screenshot</span>';
225
234
  for (const f of files) await handlePastedImageFile(f);
226
235
  });
227
236
 
@@ -383,7 +392,11 @@ let searchT;
383
392
  $('search').addEventListener('input', () => { clearTimeout(searchT); searchT = setTimeout(loadDash, 400); });
384
393
  let searchAT;
385
394
  $('search-arch').addEventListener('input', () => { clearTimeout(searchAT); searchAT = setTimeout(loadArchive, 400); });
386
- $('btn-quick').onclick = () => runQuick($('paste-text').value, $('quick-result'));
395
+ $('btn-quick').onclick = () => {
396
+ const t = $('paste-text').value.trim();
397
+ if (!t) { $('quick-result').innerHTML = '<p class="muted">Paste the seller\'s text above first — or tap <b>📋 Paste screenshot</b>, screenshots extract on their own.</p>'; return; }
398
+ runQuick(t, $('quick-result'));
399
+ };
387
400
  $('btn-manual').onclick = async () => {
388
401
  $('manual-err').textContent = '';
389
402
  try {
package/public/index.html CHANGED
@@ -61,11 +61,11 @@
61
61
  <button class="tab" data-tab="manual">Manual</button>
62
62
  </div>
63
63
  <div id="tab-paste" class="tabpanel">
64
- <textarea id="paste-text" rows="6" placeholder="Paste the seller's message here…"></textarea>
65
- <div id="paste-box" class="pastebox" contenteditable="true" spellcheck="false">📋 <span class="muted">or tap here, then paste a screenshot</span></div>
66
- <div class="row" style="margin-top:8px"><button id="btn-clipboard" class="secondary">📋 Grab screenshot from clipboard</button></div>
64
+ <textarea id="paste-text" rows="4" placeholder="Paste the seller's message here…"></textarea>
65
+ <div class="row" style="margin:8px 0"><button id="btn-clipboard" class="primary">📋 Paste screenshot — extracts automatically</button></div>
66
+ <div id="paste-box" class="pastebox" contenteditable="true" spellcheck="false">📋 <span class="muted">or tap here and paste a screenshot</span></div>
67
67
  <div id="ocr-status-paste" class="muted"></div>
68
- <button id="btn-quick" class="primary">Extract &amp; add</button>
68
+ <button id="btn-quick" class="secondary">Extract from text above</button>
69
69
  <div id="quick-result"></div>
70
70
  </div>
71
71
  <div id="tab-photo" class="tabpanel" hidden>