diff --git a/src/controllers/lyrics.types.ts b/src/apps/stable/features/lyrics/constants/autoScroll.ts
similarity index 100%
rename from src/controllers/lyrics.types.ts
rename to src/apps/stable/features/lyrics/constants/autoScroll.ts
diff --git a/src/controllers/lyrics.html b/src/controllers/lyrics.html
index d1e7b662c..79b923678 100644
--- a/src/controllers/lyrics.html
+++ b/src/controllers/lyrics.html
@@ -1,6 +1,6 @@
diff --git a/src/controllers/lyrics.js b/src/controllers/lyrics.js
index 36ae408bc..74f674140 100644
--- a/src/controllers/lyrics.js
+++ b/src/controllers/lyrics.js
@@ -1,20 +1,21 @@
+import { getLyricsApi } from '@jellyfin/sdk/lib/utils/api/lyrics-api';
import escapeHtml from 'escape-html';
+import { AutoScroll } from 'apps/stable/features/lyrics/constants/autoScroll';
import autoFocuser from 'components/autoFocuser';
-import { appRouter } from '../components/router/appRouter';
+import { appRouter } from 'components/router/appRouter';
import layoutManager from 'components/layoutManager';
-import { playbackManager } from '../components/playback/playbackmanager';
+import { playbackManager } from 'components/playback/playbackmanager';
import scrollManager from 'components/scrollManager';
import focusManager from 'components/focusManager';
-
-import keyboardNavigation from 'scripts/keyboardNavigation';
import globalize from 'lib/globalize';
import { ServerConnections } from 'lib/jellyfin-apiclient';
+import keyboardNavigation from 'scripts/keyboardNavigation';
import LibraryMenu from 'scripts/libraryMenu';
import Events from 'utils/events';
+import { toApi } from 'utils/jellyfin-apiclient/compat';
import '../styles/lyrics.scss';
-import { AutoScroll } from './lyrics.types';
let currentPlayer;
let currentItem;
@@ -23,21 +24,17 @@ let savedLyrics;
let isDynamicLyric = false;
let autoScroll = AutoScroll.Instant;
-function dynamicLyricHtmlReducer(htmlAccumulator, lyric, index) {
- if (layoutManager.tv) {
- htmlAccumulator += `
`;
- } else {
- htmlAccumulator += `
${escapeHtml(lyric.Text)}
`;
- }
- return htmlAccumulator;
-}
+function lyricHtmlReducer(htmlAccumulator, lyric, index) {
+ const elem = layoutManager.tv ? 'button' : 'div';
+ const classes = [];
+ if (isDynamicLyric) classes.push('dynamicLyric');
+ if (layoutManager.tv) classes.push('listItem', 'show-focus');
+ const lyricTime = typeof lyric.Start !== 'undefined' ? `data-lyrictime="${lyric.Start}"` : '';
+
+ htmlAccumulator += `<${elem} class="lyricsLine ${classes.join(' ')}" id="lyricPosition${index}" ${lyricTime}>
+
${escapeHtml(lyric.Text)}
+${elem}>`;
-function staticLyricHtmlReducer(htmlAccumulator, lyric, index) {
- if (layoutManager.tv) {
- htmlAccumulator += `
`;
- } else {
- htmlAccumulator += `
${escapeHtml(lyric.Text)}
`;
- }
return htmlAccumulator;
}
@@ -96,37 +93,31 @@ export default function (view) {
}
function renderNoLyricMessage() {
- const itemsContainer = view.querySelector('.dynamicLyricsContainer');
+ const itemsContainer = view.querySelector('.lyricsContainer');
if (itemsContainer) {
- const html = `
${globalize.translate('HeaderNoLyrics')}
`;
+ const html = `
${globalize.translate('HeaderNoLyrics')}
`;
itemsContainer.innerHTML = html;
}
autoFocuser.autoFocus();
}
- function renderDynamicLyrics(lyrics) {
- const itemsContainer = view.querySelector('.dynamicLyricsContainer');
+ function renderLyrics(lyrics) {
+ const itemsContainer = view.querySelector('.lyricsContainer');
if (itemsContainer) {
- const html = lyrics.reduce(dynamicLyricHtmlReducer, '');
+ const html = lyrics.reduce(lyricHtmlReducer, '');
itemsContainer.innerHTML = html;
}
- const lyricLineArray = itemsContainer.querySelectorAll('.lyricsLine');
+ if (isDynamicLyric) {
+ const lyricLineArray = itemsContainer.querySelectorAll('.lyricsLine');
- // attaches click event listener to change playtime to lyric start
- lyricLineArray.forEach(element => {
- element.addEventListener('click', () => onLyricClick(element.getAttribute('data-lyrictime')));
- });
+ // attaches click event listener to change playtime to lyric start
+ lyricLineArray.forEach(element => {
+ element.addEventListener('click', () => onLyricClick(element.getAttribute('data-lyrictime')));
+ });
- const currentIndex = getLyricIndex(getCurrentPlayTime(), lyrics);
- updateAllLyricLines(currentIndex, savedLyrics);
- }
-
- function renderStaticLyrics(lyrics) {
- const itemsContainer = view.querySelector('.dynamicLyricsContainer');
- if (itemsContainer) {
- const html = lyrics.reduce(staticLyricHtmlReducer, '');
- itemsContainer.innerHTML = html;
+ const currentIndex = getLyricIndex(getCurrentPlayTime(), lyrics);
+ updateAllLyricLines(currentIndex, savedLyrics);
}
}
@@ -135,28 +126,22 @@ export default function (view) {
isDynamicLyric = Object.prototype.hasOwnProperty.call(lyrics[0], 'Start');
- if (isDynamicLyric) {
- renderDynamicLyrics(savedLyrics);
- } else {
- renderStaticLyrics(savedLyrics);
- }
+ renderLyrics(savedLyrics);
autoFocuser.autoFocus(view);
}
function getLyrics(serverId, itemId) {
const apiClient = ServerConnections.getApiClient(serverId);
+ const lyricsApi = getLyricsApi(toApi(apiClient));
- return apiClient.ajax({
- url: apiClient.getUrl('Audio/' + itemId + '/Lyrics'),
- type: 'GET',
- dataType: 'json'
- }).then((response) => {
- if (!response.Lyrics) {
- throw new Error();
- }
- return response.Lyrics;
- });
+ return lyricsApi.getLyrics({ itemId })
+ .then(({ data }) => {
+ if (!data.Lyrics?.length) {
+ throw new Error('No lyrics returned');
+ }
+ return data.Lyrics;
+ });
}
function bindToPlayer(player) {
diff --git a/src/styles/lyrics.scss b/src/styles/lyrics.scss
index 0adf81ebd..4e9a7128e 100644
--- a/src/styles/lyrics.scss
+++ b/src/styles/lyrics.scss
@@ -6,7 +6,7 @@
justify-content: center;
}
-.dynamicLyricsContainer {
+.lyricsContainer {
display: flex;
flex-direction: column;
}