@uimaxbai/am-lyrics 1.1.4 → 1.1.6

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.
@@ -1 +1 @@
1
- {"version":3,"file":"AmLyrics.d.ts","sourceRoot":"","sources":["../../src/AmLyrics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AmLyrics.d.ts","sourceRoot":"","sources":["../../src/AmLyrics.ts"],"names":[],"mappings":"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"}
@@ -309,7 +309,7 @@ class GoogleService {
309
309
  }
310
310
  }
311
311
 
312
- const VERSION = '1.1.4';
312
+ const VERSION = '1.1.6';
313
313
  const INSTRUMENTAL_THRESHOLD_MS = 7000; // Show dots for gaps >= 7s
314
314
  const KPOE_SERVERS = [
315
315
  'https://lyricsplus.binimum.org',
@@ -576,28 +576,32 @@ class AmLyrics extends i {
576
576
  return 4;
577
577
  if (lower.includes('lrclib') && hasWordSync)
578
578
  return 5;
579
- if (lower.includes('apple') && !hasWordSync && !isUnsynced)
579
+ if (hasWordSync)
580
580
  return 6;
581
- if (isQQ && !hasWordSync && !isUnsynced)
581
+ if (lower.includes('apple') && !hasWordSync && !isUnsynced)
582
582
  return 7;
583
- if (lower.includes('musixmatch') && !hasWordSync && !isUnsynced)
583
+ if (isQQ && !hasWordSync && !isUnsynced)
584
584
  return 8;
585
- if (lower.includes('tidal') && !hasWordSync && !isUnsynced)
585
+ if (lower.includes('musixmatch') && !hasWordSync && !isUnsynced)
586
586
  return 9;
587
- if (lower.includes('lrclib') && !hasWordSync && !isUnsynced)
587
+ if (lower.includes('tidal') && !hasWordSync && !isUnsynced)
588
588
  return 10;
589
- if (lower.includes('apple') && isUnsynced)
589
+ if (lower.includes('lrclib') && !hasWordSync && !isUnsynced)
590
590
  return 11;
591
- if (isQQ && isUnsynced)
591
+ if (!hasWordSync && !isUnsynced)
592
592
  return 12;
593
- if (lower.includes('musixmatch') && isUnsynced)
593
+ if (lower.includes('apple') && isUnsynced)
594
594
  return 13;
595
- if (lower.includes('tidal') && isUnsynced)
595
+ if (isQQ && isUnsynced)
596
596
  return 14;
597
- if (lower.includes('lrclib') && isUnsynced)
597
+ if (lower.includes('musixmatch') && isUnsynced)
598
598
  return 15;
599
- if (lower.includes('genius'))
599
+ if (lower.includes('tidal') && isUnsynced)
600
600
  return 16;
601
+ if (lower.includes('lrclib') && isUnsynced)
602
+ return 17;
603
+ if (lower.includes('genius'))
604
+ return 18;
601
605
  return 20;
602
606
  }
603
607
  static mergeAndSortSources(collectedSources) {
@@ -836,19 +840,23 @@ class AmLyrics extends i {
836
840
  return 2;
837
841
  if (lower.includes('musixmatch') && hasWordSync)
838
842
  return 3;
839
- if (lower.includes('apple') && !hasWordSync && !isUnsynced)
843
+ if (hasWordSync)
840
844
  return 4;
841
- if (isQQ && !hasWordSync && !isUnsynced)
845
+ if (lower.includes('apple') && !hasWordSync && !isUnsynced)
842
846
  return 5;
843
- if (lower.includes('musixmatch') && !hasWordSync && !isUnsynced)
847
+ if (isQQ && !hasWordSync && !isUnsynced)
844
848
  return 6;
845
- if (lower.includes('apple') && isUnsynced)
849
+ if (lower.includes('musixmatch') && !hasWordSync && !isUnsynced)
846
850
  return 7;
847
- if (isQQ && isUnsynced)
851
+ if (!hasWordSync && !isUnsynced)
848
852
  return 8;
849
- if (lower.includes('musixmatch') && isUnsynced)
853
+ if (lower.includes('apple') && isUnsynced)
850
854
  return 9;
851
- return 10;
855
+ if (isQQ && isUnsynced)
856
+ return 10;
857
+ if (lower.includes('musixmatch') && isUnsynced)
858
+ return 11;
859
+ return 20;
852
860
  };
853
861
  const allResults = [];
854
862
  // Try cache API first
@@ -881,28 +889,30 @@ class AmLyrics extends i {
881
889
  }
882
890
  }
883
891
  else {
884
- // Not word type, try QQ
885
- const qqParams = new URLSearchParams(params);
886
- qqParams.set('source', 'qq');
887
- const qqUrl = `https://lyricsplus.binimum.org/v2/lyrics/get?${qqParams.toString()}`;
892
+ // Not word type, try fetching any word synced lyrics from lyricsplus
893
+ const fallbackParams = new URLSearchParams(params);
894
+ const fallbackUrl = `https://lyricsplus.binimum.org/v2/lyrics/get?${fallbackParams.toString()}`;
888
895
  try {
889
- const qqRes = await fetch(qqUrl);
890
- if (qqRes.ok) {
891
- const payload = await qqRes.json();
896
+ const fallbackRes = await fetch(fallbackUrl);
897
+ if (fallbackRes.ok) {
898
+ const payload = await fallbackRes.json();
892
899
  const lines = AmLyrics.convertKPoeLyrics(payload);
893
900
  const hasWordSync = lines?.some((line) => line.text &&
894
901
  Array.isArray(line.text) &&
895
902
  line.text.length > 1);
896
903
  if (lines && lines.length > 0 && hasWordSync) {
897
- allResults.push({ lines, source: 'QQ (Cache Fallback)' });
904
+ const sourceLabel = payload?.metadata?.source ||
905
+ payload?.metadata?.provider ||
906
+ 'LyricsPlus (KPoe)';
907
+ allResults.push({ lines, source: sourceLabel });
898
908
  return allResults;
899
909
  }
900
910
  }
901
911
  }
902
- catch (qqError) {
903
- // Ignore QQ fetch error
912
+ catch (fallbackError) {
913
+ // Ignore fallback fetch error
904
914
  }
905
- // If QQ fails or has no word sync, fall back to bini lyrics
915
+ // If fallback fails or has no word sync, fall back to bini lyrics
906
916
  if (result.lyricsUrl) {
907
917
  const ttmlRes = await fetch(result.lyricsUrl);
908
918
  if (ttmlRes.ok) {
@@ -911,7 +921,7 @@ class AmLyrics extends i {
911
921
  if (lines && lines.length > 0) {
912
922
  allResults.push({
913
923
  lines,
914
- source: 'Apple Music (Cache Fallback)',
924
+ source: 'BiniLyrics',
915
925
  });
916
926
  return allResults;
917
927
  }
@@ -961,14 +971,13 @@ class AmLyrics extends i {
961
971
  }
962
972
  }
963
973
  }
964
- // If we haven't found a completely synced Apple/QQ result (rank 1 or 2) among the servers,
965
- // force an explicit query against lyricsplus.binimum.org looking for QQ
974
+ // If we haven't found a completely synced result (rank 1 or 2) among the servers,
975
+ // force an explicit query against lyricsplus.binimum.org looking for word lyrics
966
976
  const hasHighRankResult = allResults.some(r => getRank(r.source, r.lines) <= 2);
967
977
  if (!hasHighRankResult) {
968
978
  try {
969
- const qqParams = new URLSearchParams(params);
970
- qqParams.set('source', 'qq');
971
- const url = `https://lyricsplus.binimum.org/v2/lyrics/get?${qqParams.toString()}`;
979
+ const fallbackParams = new URLSearchParams(params);
980
+ const url = `https://lyricsplus.binimum.org/v2/lyrics/get?${fallbackParams.toString()}`;
972
981
  const response = await fetch(url);
973
982
  if (response.ok) {
974
983
  const payload = await response.json();
@@ -977,14 +986,15 @@ class AmLyrics extends i {
977
986
  const sourceLabel = payload?.metadata?.source ||
978
987
  payload?.metadata?.provider ||
979
988
  'LyricsPlus (KPoe)';
980
- if (lines && lines.length > 0) {
989
+ const hasWordSync = lines?.some((line) => line.text && Array.isArray(line.text) && line.text.length > 1);
990
+ if (lines && lines.length > 0 && hasWordSync) {
981
991
  allResults.push({ lines, source: sourceLabel });
982
992
  }
983
993
  }
984
994
  }
985
995
  }
986
996
  catch (error) {
987
- // Explicit QQ fallback failed, ignore
997
+ // Explicit fallback failed, ignore
988
998
  }
989
999
  }
990
1000
  return allResults;
@@ -1661,15 +1671,32 @@ class AmLyrics extends i {
1661
1671
  // Entering gap: remove any leftover exit state, add active
1662
1672
  gap.classList.remove('gap-exiting');
1663
1673
  gap.classList.add('active');
1664
- // Mark any dots whose time has already passed as finished
1665
- // (prevents skipping the first dot when lyrics load mid-gap)
1674
+ // Mark dots whose time has already passed as finished, and
1675
+ // trigger highlight on the dot currently in its time window
1676
+ // so the first dot always lights up even on late load.
1666
1677
  const dotSyllables = gap.querySelectorAll('.lyrics-syllable');
1667
1678
  dotSyllables.forEach(dot => {
1679
+ const dotStart = parseFloat(dot.getAttribute('data-start-time') || '0');
1668
1680
  const dotEnd = parseFloat(dot.getAttribute('data-end-time') || '0');
1669
1681
  if (newTime > dotEnd) {
1670
1682
  dot.classList.add('finished');
1683
+ // Also ensure the highlight + animation fired so CSS state is correct
1684
+ if (!dot.classList.contains('highlight')) {
1685
+ AmLyrics.updateSyllableAnimation(dot);
1686
+ }
1687
+ }
1688
+ else if (newTime >= dotStart && newTime <= dotEnd) {
1689
+ // Currently within this dot's window — trigger its highlight
1690
+ AmLyrics.updateSyllableAnimation(dot);
1671
1691
  }
1672
1692
  });
1693
+ // Scroll to the gap element so dots animate in with
1694
+ // the staggered scroll rather than popping in.
1695
+ if (this.autoScroll &&
1696
+ !this.isUserScrolling &&
1697
+ !this.isClickSeeking) {
1698
+ this.scrollToActiveLineYouLy(gap);
1699
+ }
1673
1700
  }
1674
1701
  else if (shouldStartExiting) {
1675
1702
  // Exiting gap: keep visible while dots animate out