Merge pull request #6936 from thornbill/bdi-lyrics
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<div id="lyricPage" data-role="page" class="page lyricPage" data-backbutton="true">
|
||||
<div>
|
||||
<div class="dynamicLyricsContainer padded-bottom-page">
|
||||
<div class="lyricsContainer padded-bottom-page">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+38
-53
@@ -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 += `<button class="lyricsLine dynamicLyric listItem show-focus" id="lyricPosition${index}" data-lyrictime="${lyric.Start}">${escapeHtml(lyric.Text)}</button>`;
|
||||
} else {
|
||||
htmlAccumulator += `<div class="lyricsLine dynamicLyric" id="lyricPosition${index}" data-lyrictime="${lyric.Start}">${escapeHtml(lyric.Text)}</div>`;
|
||||
}
|
||||
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}>
|
||||
<bdi>${escapeHtml(lyric.Text)}</bdi>
|
||||
</${elem}>`;
|
||||
|
||||
function staticLyricHtmlReducer(htmlAccumulator, lyric, index) {
|
||||
if (layoutManager.tv) {
|
||||
htmlAccumulator += `<button class="lyricsLine listItem show-focus" id="lyricPosition${index}">${escapeHtml(lyric.Text)}</button>`;
|
||||
} else {
|
||||
htmlAccumulator += `<div class="lyricsLine" id="lyricPosition${index}">${escapeHtml(lyric.Text)}</div>`;
|
||||
}
|
||||
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 = `<h1> ${globalize.translate('HeaderNoLyrics')} </h1>`;
|
||||
const html = `<h1>${globalize.translate('HeaderNoLyrics')}</h1>`;
|
||||
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) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dynamicLyricsContainer {
|
||||
.lyricsContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user