buzzbandit commited on
Commit
48d8ce0
·
verified ·
1 Parent(s): 08aea85

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -22
app.py CHANGED
@@ -393,38 +393,49 @@ with gr.Blocks(title="🧳 Torn Foreign Stocks") as iface:
393
  gr.HTML("""
394
  <script>
395
  (function () {
396
- // Convert any ISO-UTC (…Z) timestamp found in component text/values to the browser's local time
397
- function convertTimesToLocal() {
398
- const isoRe = /\\b\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z\\b/g;
399
- const fmt = new Intl.DateTimeFormat([], {
400
- year: "numeric", month: "2-digit", day: "2-digit",
401
- hour: "2-digit", minute: "2-digit", second: "2-digit"
 
 
 
 
 
 
 
 
402
  });
 
403
 
404
- function processRoot(root) {
405
- const elems = root.querySelectorAll("td, textarea, input, div, span");
406
- elems.forEach(el => {
407
- // Prefer .value for inputs/textareas; otherwise use textContent
408
- if (typeof el.value === "string") {
409
- const v = el.value;
410
- if (isoRe.test(v)) {
411
- el.value = v.replace(isoRe, m => fmt.format(new Date(m)));
412
- }
413
- } else if (el.textContent && isoRe.test(el.textContent)) {
414
- el.textContent = el.textContent.replace(isoRe, m => fmt.format(new Date(m)));
415
  }
416
  });
417
- }
 
418
 
419
- // Handle regular DOM and Gradio's shadow DOM
420
  const roots = [document];
421
  const app = document.querySelector("gradio-app");
422
  if (app && app.shadowRoot) roots.push(app.shadowRoot);
423
- roots.forEach(processRoot);
 
 
 
424
  }
425
 
426
- // Run periodically to catch re-renders
427
- setInterval(convertTimesToLocal, 800);
 
 
428
  })();
429
  </script>
430
  """)
 
393
  gr.HTML("""
394
  <script>
395
  (function () {
396
+ // Match ISO UTC timestamps (e.g., 2025-10-25T02:05:36Z)
397
+ const isoRe = /\\b\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z\\b/g;
398
+ const fmt = new Intl.DateTimeFormat([], {
399
+ year: "numeric", month: "2-digit", day: "2-digit",
400
+ hour: "2-digit", minute: "2-digit", second: "2-digit"
401
+ });
402
+
403
+ function convertInInputs(root) {
404
+ // Only update values for inputs/textareas (e.g., your "Last update" textbox)
405
+ const fields = root.querySelectorAll('input[type="text"], textarea');
406
+ fields.forEach(el => {
407
+ if (typeof el.value === "string" && isoRe.test(el.value)) {
408
+ el.value = el.value.replace(isoRe, m => fmt.format(new Date(m)));
409
+ }
410
  });
411
+ }
412
 
413
+ function convertInTableCells(root) {
414
+ // Only touch <td> text nodes, not container divs/spans
415
+ const tds = root.querySelectorAll("td");
416
+ tds.forEach(td => {
417
+ td.childNodes.forEach(node => {
418
+ if (node.nodeType === Node.TEXT_NODE && isoRe.test(node.nodeValue)) {
419
+ node.nodeValue = node.nodeValue.replace(isoRe, m => fmt.format(new Date(m)));
 
 
 
 
420
  }
421
  });
422
+ });
423
+ }
424
 
425
+ function runOnce() {
426
  const roots = [document];
427
  const app = document.querySelector("gradio-app");
428
  if (app && app.shadowRoot) roots.push(app.shadowRoot);
429
+ roots.forEach(r => {
430
+ convertInInputs(r);
431
+ convertInTableCells(r);
432
+ });
433
  }
434
 
435
+ // Convert initially and on any UI updates without clobbering DOM
436
+ runOnce();
437
+ const obs = new MutationObserver(() => runOnce());
438
+ obs.observe(document.documentElement, { childList: true, subtree: true, characterData: true });
439
  })();
440
  </script>
441
  """)