mirror of
https://github.com/Readarr/Readarr
synced 2025-12-14 20:36:18 +01:00
New: Show book file details in interactive import and unmapped files
This commit is contained in:
parent
9f37b1c484
commit
110e867bd3
4 changed files with 82 additions and 13 deletions
|
|
@ -6,7 +6,7 @@ import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'
|
|||
import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription';
|
||||
import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle';
|
||||
import Link from 'Components/Link/Link';
|
||||
import formatTimeSpan from 'Utilities/Date/formatTimeSpan';
|
||||
import stripHtml from 'Utilities/String/stripHtml';
|
||||
import styles from './FileDetails.css';
|
||||
|
||||
function renderRejections(rejections) {
|
||||
|
|
@ -90,6 +90,20 @@ function FileDetails(props) {
|
|||
data={audioTags.authorTitle}
|
||||
/>
|
||||
}
|
||||
{
|
||||
audioTags.seriesTitle !== undefined &&
|
||||
<DescriptionListItem
|
||||
title="Series"
|
||||
data={audioTags.seriesTitle}
|
||||
/>
|
||||
}
|
||||
{
|
||||
audioTags.seriesIndex !== undefined &&
|
||||
<DescriptionListItem
|
||||
title="Series Number"
|
||||
data={audioTags.seriesIndex}
|
||||
/>
|
||||
}
|
||||
{
|
||||
audioTags.country !== undefined &&
|
||||
<DescriptionListItem
|
||||
|
|
@ -97,6 +111,13 @@ function FileDetails(props) {
|
|||
data={audioTags.country.name}
|
||||
/>
|
||||
}
|
||||
{
|
||||
audioTags.language !== undefined && audioTags.language !== 'UND' &&
|
||||
<DescriptionListItem
|
||||
title="Language"
|
||||
data={audioTags.language}
|
||||
/>
|
||||
}
|
||||
{
|
||||
audioTags.year > 0 &&
|
||||
<DescriptionListItem
|
||||
|
|
@ -111,6 +132,13 @@ function FileDetails(props) {
|
|||
data={audioTags.label}
|
||||
/>
|
||||
}
|
||||
{
|
||||
audioTags.publisher !== undefined &&
|
||||
<DescriptionListItem
|
||||
title="Publisher"
|
||||
data={audioTags.publisher}
|
||||
/>
|
||||
}
|
||||
{
|
||||
audioTags.catalogNumber !== undefined &&
|
||||
<DescriptionListItem
|
||||
|
|
@ -121,18 +149,24 @@ function FileDetails(props) {
|
|||
{
|
||||
audioTags.disambiguation !== undefined &&
|
||||
<DescriptionListItem
|
||||
title="Disambiguation"
|
||||
data={audioTags.disambiguation}
|
||||
title="Overview"
|
||||
data={stripHtml(audioTags.disambiguation)}
|
||||
/>
|
||||
}
|
||||
{
|
||||
audioTags.duration !== undefined &&
|
||||
audioTags.isbn !== undefined &&
|
||||
<DescriptionListItem
|
||||
title="Duration"
|
||||
data={formatTimeSpan(audioTags.duration)}
|
||||
title="ISBN"
|
||||
data={audioTags.isbn}
|
||||
/>
|
||||
}
|
||||
{
|
||||
audioTags.asin !== undefined &&
|
||||
<DescriptionListItem
|
||||
title="ASIN"
|
||||
data={audioTags.asin}
|
||||
/>
|
||||
} {
|
||||
audioTags.authorMBId !== undefined &&
|
||||
<Link
|
||||
to={`https://musicbrainz.org/author/${audioTags.authorMBId}`}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
word-break: break-all;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.quality {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import BookQuality from 'Book/BookQuality';
|
||||
import FileDetails from 'BookFile/FileDetails';
|
||||
import Icon from 'Components/Icon';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableRowCellButton from 'Components/Table/Cells/TableRowCellButton';
|
||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import Popover from 'Components/Tooltip/Popover';
|
||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props';
|
||||
import SelectAuthorModal from 'InteractiveImport/Author/SelectAuthorModal';
|
||||
import SelectBookModal from 'InteractiveImport/Book/SelectBookModal';
|
||||
import SelectQualityModal from 'InteractiveImport/Quality/SelectQualityModal';
|
||||
|
|
@ -25,6 +27,7 @@ class InteractiveImportRow extends Component {
|
|||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
isDetailsModalOpen: false,
|
||||
isSelectAuthorModalOpen: false,
|
||||
isSelectBookModalOpen: false,
|
||||
isSelectQualityModalOpen: false
|
||||
|
|
@ -97,6 +100,14 @@ class InteractiveImportRow extends Component {
|
|||
//
|
||||
// Listeners
|
||||
|
||||
onDetailsPress = () => {
|
||||
this.setState({ isDetailsModalOpen: true });
|
||||
}
|
||||
|
||||
onDetailsModalClose = () => {
|
||||
this.setState({ isDetailsModalOpen: false });
|
||||
}
|
||||
|
||||
onSelectAuthorPress = () => {
|
||||
this.setState({ isSelectAuthorModalOpen: true });
|
||||
}
|
||||
|
|
@ -139,10 +150,12 @@ class InteractiveImportRow extends Component {
|
|||
rejections,
|
||||
additionalFile,
|
||||
isSelected,
|
||||
onSelectedChange
|
||||
onSelectedChange,
|
||||
audioTags
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
isDetailsModalOpen,
|
||||
isSelectAuthorModalOpen,
|
||||
isSelectBookModalOpen,
|
||||
isSelectQualityModalOpen
|
||||
|
|
@ -159,7 +172,7 @@ class InteractiveImportRow extends Component {
|
|||
const showQualityPlaceholder = isSelected && !quality;
|
||||
|
||||
const pathCellContents = (
|
||||
<div>
|
||||
<div onClick={this.onDetailsPress}>
|
||||
{path}
|
||||
</div>
|
||||
);
|
||||
|
|
@ -172,6 +185,13 @@ class InteractiveImportRow extends Component {
|
|||
/>
|
||||
) : pathCellContents;
|
||||
|
||||
const fileDetails = (
|
||||
<FileDetails
|
||||
audioTags={audioTags}
|
||||
filename={path}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
className={additionalFile ? styles.additionalFile : undefined}
|
||||
|
|
@ -262,6 +282,18 @@ class InteractiveImportRow extends Component {
|
|||
}
|
||||
</TableRowCell>
|
||||
|
||||
<ConfirmModal
|
||||
isOpen={isDetailsModalOpen}
|
||||
title="File Details"
|
||||
message={fileDetails}
|
||||
size={sizes.LARGE}
|
||||
kind={kinds.DEFAULT}
|
||||
hideCancelButton={true}
|
||||
confirmLabel="Close"
|
||||
onConfirm={this.onDetailsModalClose}
|
||||
onCancel={this.onDetailsModalClose}
|
||||
/>
|
||||
|
||||
<SelectAuthorModal
|
||||
isOpen={isSelectAuthorModalOpen}
|
||||
ids={[id]}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Abstractions;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NzbDrone.Core.Books;
|
||||
|
|
@ -24,7 +26,7 @@ public class BookFileController : RestControllerWithSignalR<BookFileResource, Bo
|
|||
{
|
||||
private readonly IMediaFileService _mediaFileService;
|
||||
private readonly IDeleteMediaFiles _mediaFileDeletionService;
|
||||
private readonly IAudioTagService _audioTagService;
|
||||
private readonly IEBookTagService _eBookTagService;
|
||||
private readonly IAuthorService _authorService;
|
||||
private readonly IBookService _bookService;
|
||||
private readonly IUpgradableSpecification _upgradableSpecification;
|
||||
|
|
@ -32,7 +34,7 @@ public class BookFileController : RestControllerWithSignalR<BookFileResource, Bo
|
|||
public BookFileController(IBroadcastSignalRMessage signalRBroadcaster,
|
||||
IMediaFileService mediaFileService,
|
||||
IDeleteMediaFiles mediaFileDeletionService,
|
||||
IAudioTagService audioTagService,
|
||||
IEBookTagService eBookTagService,
|
||||
IAuthorService authorService,
|
||||
IBookService bookService,
|
||||
IUpgradableSpecification upgradableSpecification)
|
||||
|
|
@ -40,7 +42,7 @@ public BookFileController(IBroadcastSignalRMessage signalRBroadcaster,
|
|||
{
|
||||
_mediaFileService = mediaFileService;
|
||||
_mediaFileDeletionService = mediaFileDeletionService;
|
||||
_audioTagService = audioTagService;
|
||||
_eBookTagService = eBookTagService;
|
||||
_authorService = authorService;
|
||||
_bookService = bookService;
|
||||
_upgradableSpecification = upgradableSpecification;
|
||||
|
|
@ -61,7 +63,7 @@ private BookFileResource MapToResource(BookFile bookFile)
|
|||
public override BookFileResource GetResourceById(int id)
|
||||
{
|
||||
var resource = MapToResource(_mediaFileService.Get(id));
|
||||
resource.AudioTags = _audioTagService.ReadTags(resource.Path);
|
||||
resource.AudioTags = _eBookTagService.ReadTags((FileInfoBase)new FileInfo(resource.Path));
|
||||
return resource;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue