k-l-lambda commited on
Commit
cc88aa8
·
1 Parent(s): b2172ef

added author line.

Browse files
Files changed (3) hide show
  1. app.py +6 -10
  2. lilyscript/lang.py +2 -2
  3. web/score-player.js +27 -0
app.py CHANGED
@@ -443,16 +443,12 @@ def build_head ():
443
 
444
  _JS_HELPERS = '''
445
  function () {
446
- // poll until the score player + its #ls-score mount exist, then mount once.
447
- const tryMount = () => {
448
- const root = document.getElementById('ls-score');
449
- if (window.LilyScore && root) { window.LilyScore.mount(root); return true; }
450
- return false;
451
- };
452
- if (!tryMount()) {
453
- const iv = setInterval(() => { if (tryMount()) clearInterval(iv); }, 200);
454
- setTimeout(() => clearInterval(iv), 20000);
455
- }
456
 
457
  // Initial render on RELOAD/restore. Gradio repopulates the hidden #ls-editor-state
458
  // textbox with the previous score on a page reload but does NOT fire a `change`
 
443
 
444
  _JS_HELPERS = '''
445
  function () {
446
+ // NB: mounting the score player into #ls-score is handled by score-player.js
447
+ // itself (event-driven self-mount via MutationObserver — see web/score-player.js).
448
+ // We deliberately do NOT poll-and-mount here: on a cold load over a slow link the
449
+ // 7.6MB verovio.bundle.js ahead of score-player.js in <head> can take well over a
450
+ // minute to arrive, so any fixed-deadline poll here would expire before LilyScore
451
+ // is even defined and leave the loading spinner stuck forever.
 
 
 
 
452
 
453
  // Initial render on RELOAD/restore. Gradio repopulates the hidden #ls-editor-state
454
  // textbox with the previous score on a page reload but does NOT fire a `change`
lilyscript/lang.py CHANGED
@@ -45,7 +45,7 @@ LANG = _resolve_lang()
45
  # identical to the original literals).
46
  _STRINGS = {
47
  'en': {
48
- 'app_title': '## 🎼 LilyScript — symbolic music generation with Lilylet',
49
  'compose': '## Compose',
50
  'style_options': '- Style Options',
51
  'composer': 'composer',
@@ -71,7 +71,7 @@ _STRINGS = {
71
  'loading_renderer': 'Loading score renderer…',
72
  },
73
  'zh': {
74
- 'app_title': '## 🎼 LilyScript — 基于 Lilylet 的符号音乐生成',
75
  'compose': '## 创作',
76
  'style_options': '- 风格选项',
77
  'composer': '作曲家',
 
45
  # identical to the original literals).
46
  _STRINGS = {
47
  'en': {
48
+ 'app_title': '## 🎼 LilyScript — symbolic music generation with Lilylet\n\nBy [K.L. Λ](https://k-l-lambda.github.io/), about [Lilylet](https://github.com/k-l-lambda/lilylet)',
49
  'compose': '## Compose',
50
  'style_options': '- Style Options',
51
  'composer': 'composer',
 
71
  'loading_renderer': 'Loading score renderer…',
72
  },
73
  'zh': {
74
+ 'app_title': '## 🎼 LilyScript — 基于 Lilylet 的符号音乐生成\n\n作者 [K.L. Λ](https://k-l-lambda.github.io/), 关于 [Lilylet](https://github.com/k-l-lambda/lilylet)',
75
  'compose': '## 创作',
76
  'style_options': '- 风格选项',
77
  'composer': '作曲家',
web/score-player.js CHANGED
@@ -621,4 +621,31 @@
621
  isReady: function () { return state.verovioReady; },
622
  };
623
  log('score-player.js loaded');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
624
  })();
 
621
  isReady: function () { return state.verovioReady; },
622
  };
623
  log('score-player.js loaded');
624
+
625
+ // ---- self-mount (event-driven) ------------------------------------------
626
+ // Mount as soon as BOTH this script has executed (window.LilyScore defined —
627
+ // which only happens after the 7.6MB verovio.bundle.js ahead of us in <head>
628
+ // finishes downloading + parsing) AND Gradio has inserted the #ls-score node.
629
+ // We own the mounting here rather than relying on app.py's injected poller:
630
+ // on a cold load over a slow link, verovio can take well over a minute, so any
631
+ // fixed-deadline poll on the app side would have already given up by the time
632
+ // we run, leaving the loading spinner stuck forever (the bug this replaces).
633
+ // A MutationObserver has no deadline, so it cannot expire early.
634
+ function selfMount () {
635
+ const root = document.getElementById('ls-score');
636
+ if (root) { mount(root); return true; }
637
+ return false;
638
+ }
639
+ if (!selfMount()) {
640
+ // #ls-score not in the DOM yet (Gradio still building the UI). Watch for it.
641
+ const mo = new MutationObserver(function () {
642
+ if (selfMount()) mo.disconnect();
643
+ });
644
+ const startObserving = function () {
645
+ mo.observe(document.documentElement, { childList: true, subtree: true });
646
+ selfMount(); // re-check in case it appeared between the miss and observe()
647
+ };
648
+ if (document.documentElement) startObserving();
649
+ else document.addEventListener('DOMContentLoaded', startObserving);
650
+ }
651
  })();