Skip to content

Commit 5e93cce

Browse files
committed
basic chapter list for audiobook items
1 parent 4797498 commit 5e93cce

2 files changed

Lines changed: 68 additions & 2 deletions

File tree

src/apps/legacy/controllers/itemDetails/index.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import mediaInfo from 'components/mediainfo/mediainfo';
2222
import layoutManager from 'components/layoutManager';
2323
import listView from 'components/listview/listview';
2424
import loading from 'components/loading/loading';
25+
import ItemDetailsChapterList from 'components/itemDetails/ItemDetailsChapterList';
2526
import ItemDetailsMetadataList from 'components/itemDetails/ItemDetailsMetadataList';
2627
import { playbackManager } from 'components/playback/playbackmanager';
2728
import { appRouter } from 'components/router/appRouter';
@@ -577,7 +578,7 @@ function reloadFromItem(instance, page, params, item, user) {
577578

578579
renderSeriesTimerEditor(page, item, apiClient, user);
579580
renderTimerEditor(page, item, apiClient, user);
580-
setInitialCollapsibleState(page, item, apiClient, params.context, user);
581+
setInitialCollapsibleState(page, instance, item, apiClient, params.context, user);
581582
const canPlay = reloadPlayButtons(page, item);
582583

583584
setTrailerButtonVisibility(page, item);
@@ -818,7 +819,7 @@ function renderNextUp(page, item, user) {
818819
});
819820
}
820821

821-
function setInitialCollapsibleState(page, item, apiClient, context, user) {
822+
function setInitialCollapsibleState(page, instance, item, apiClient, context, user) {
822823
page.querySelector('.collectionItems').innerHTML = '';
823824

824825
if (item.Type == 'Playlist') {
@@ -848,6 +849,7 @@ function setInitialCollapsibleState(page, item, apiClient, context, user) {
848849
page.querySelector('.nextUpSection').classList.add('hide');
849850
}
850851

852+
renderChapters(page, instance, item);
851853
renderScenes(page, item);
852854

853855
if (item.SpecialFeatureCount > 0) {
@@ -1782,6 +1784,17 @@ function renderAdditionalParts(page, item, user) {
17821784
});
17831785
}
17841786

1787+
function renderChapters(page, instance, item) {
1788+
if (item.Type !== BaseItemKind.AudioBook || !item.Chapters?.length) return;
1789+
1790+
const container = page.querySelector('#childrenCollapsible');
1791+
const element = container.querySelector('.itemsContainer');
1792+
1793+
instance._unmount.push(renderComponent(ItemDetailsChapterList, { item }, element));
1794+
container.classList.remove('hide');
1795+
element.classList.add('vertical-list');
1796+
}
1797+
17851798
function renderScenes(page, item) {
17861799
let chapters = item.Chapters || [];
17871800

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React, { type FC } from 'react';
2+
import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client';
3+
import type { ChapterInfo } from '@jellyfin/sdk/lib/generated-client/models/chapter-info';
4+
import Box from '@mui/material/Box';
5+
import Typography from '@mui/material/Typography';
6+
7+
import { playbackManager } from 'components/playback/playbackmanager';
8+
import globalize from 'lib/globalize';
9+
import datetime from 'scripts/datetime';
10+
11+
interface ItemDetailsChapterListProps {
12+
item: BaseItemDto;
13+
}
14+
15+
const ItemDetailsChapterList: FC<ItemDetailsChapterListProps> = ({ item }) => {
16+
const onClickPlay = (chapter: ChapterInfo) => () => {
17+
playbackManager.play({
18+
items: [item],
19+
startPositionTicks: chapter.StartPositionTicks
20+
}).catch(error => {
21+
console.error('playback failure', error);
22+
});
23+
};
24+
25+
return (
26+
<Box>
27+
{item.Chapters?.map((chapter, index) => (
28+
<Box
29+
key={chapter.StartPositionTicks}
30+
className='listItem-border'
31+
onClick={onClickPlay(chapter)}
32+
sx={{ cursor: 'pointer', display: 'flex', flexWrap: 'wrap', alignItems: 'center' }}
33+
>
34+
<Box style={{ margin: '0 1em' }}>
35+
{index + 1}
36+
</Box>
37+
38+
<Box className='listItemBody'>
39+
<Typography>
40+
{chapter.Name ?? `${globalize.translate('HeaderChapter')} ${index + 1}`}
41+
</Typography>
42+
</Box>
43+
44+
<Typography className='secondary' style={{ margin: '0 1em' }}>
45+
{datetime.getDisplayRunningTime(chapter.StartPositionTicks)}
46+
</Typography>
47+
</Box>
48+
))}
49+
</Box>
50+
);
51+
};
52+
53+
export default ItemDetailsChapterList;

0 commit comments

Comments
 (0)