@ -50535,6 +50535,33 @@ function _formatFileSize(bytes) {
return ( bytes / 1048576 ) . toFixed ( 1 ) + ' MB' ;
}
function _renderPlayButton ( f ) {
const d = f . details || { } ;
const filePath = f . file _path || d . file _path || d . original _path ;
if ( ! filePath ) return '' ;
const title = d . expected _title || d . title || d . file _title || d . matched _title || '' ;
const artist = d . expected _artist || d . artist || d . artist _name || '' ;
const album = d . album || d . album _title || '' ;
const albumArt = d . album _thumb _url || '' ;
return ` <button class="repair-finding-play-btn" onclick="event.stopPropagation(); playFindingTrack(this)"
data - path = "${_escFinding(filePath)}" data - title = "${_escFinding(title)}"
data - artist = "${_escFinding(artist)}" data - album = "${_escFinding(album)}"
data - art = "${_escFinding(albumArt)}" data - entity - id = "${_escFinding(f.entity_id || '')}" title = "Play this track" >
< svg viewBox = "0 0 24 24" > < polygon points = "5,3 19,12 5,21" / > < / s v g > P l a y
< / b u t t o n > ` ;
}
function playFindingTrack ( btn ) {
const track = {
file _path : btn . dataset . path ,
title : btn . dataset . title || 'Unknown Track' ,
id : btn . dataset . entityId || null
} ;
const albumTitle = btn . dataset . album || '' ;
const artistName = btn . dataset . artist || '' ;
playLibraryTrack ( track , albumTitle , artistName ) ;
}
function _renderFindingMedia ( d ) {
const albumUrl = d . album _thumb _url ;
const artistUrl = d . artist _thumb _url ;
@ -50572,7 +50599,7 @@ function _renderFindingDetail(f) {
if ( d . title ) rows . push ( [ 'Title' , d . title ] ) ;
if ( d . track _id ) rows . push ( [ 'Track ID' , d . track _id ] ) ;
if ( d . original _path ) rows . push ( [ 'Original Path' , d . original _path , 'path' ] ) ;
return media + _gridRows ( rows ) ;
return media + _gridRows ( rows ) + _renderPlayButton ( f ) ;
case 'orphan_file' :
if ( d . folder ) rows . push ( [ 'Folder' , d . folder , 'path' ] ) ;
@ -50580,7 +50607,7 @@ function _renderFindingDetail(f) {
if ( d . file _size ) rows . push ( [ 'File Size' , _formatFileSize ( d . file _size ) ] ) ;
if ( d . modified ) rows . push ( [ 'Last Modified' , d . modified ] ) ;
if ( f . file _path ) rows . push ( [ 'Full Path' , f . file _path , 'path' ] ) ;
return _gridRows ( rows ) ;
return _gridRows ( rows ) + _renderPlayButton ( f ) ;
case 'acoustid_mismatch' : {
let html = media + '<div style="margin-bottom:8px">' ;
@ -50593,14 +50620,14 @@ function _renderFindingDetail(f) {
rows . push ( [ 'AcoustID Title' , d . acoustid _title || '-' , 'highlight' ] ) ;
rows . push ( [ 'AcoustID Artist' , d . acoustid _artist || '-' , 'highlight' ] ) ;
if ( f . file _path ) rows . push ( [ 'File' , f . file _path , 'path' ] ) ;
return html + _gridRows ( rows ) ;
return html + _gridRows ( rows ) + _renderPlayButton ( f ) ;
}
case 'acoustid_no_match' :
if ( d . expected _title ) rows . push ( [ 'Expected Title' , d . expected _title ] ) ;
if ( d . expected _artist ) rows . push ( [ 'Expected Artist' , d . expected _artist ] ) ;
if ( f . file _path ) rows . push ( [ 'File' , f . file _path , 'path' ] ) ;
return media + _gridRows ( rows ) ;
return media + _gridRows ( rows ) + _renderPlayButton ( f ) ;
case 'fake_lossless' : {
const cutoff = d . detected _cutoff _khz || 0 ;
@ -50628,7 +50655,7 @@ function _renderFindingDetail(f) {
if ( d . bitrate ) rows . push ( [ 'Bitrate' , ` ${ d . bitrate } kbps ` ] ) ;
if ( d . file _size ) rows . push ( [ 'File Size' , _formatFileSize ( d . file _size ) ] ) ;
if ( f . file _path ) rows . push ( [ 'File' , f . file _path , 'path' ] ) ;
return flHtml + _gridRows ( rows ) ;
return flHtml + _gridRows ( rows ) + _renderPlayButton ( f ) ;
}
case 'duplicate_tracks' :
@ -50736,6 +50763,7 @@ function _renderFindingDetail(f) {
tnHtml += ` <div class="repair-detail-sublist"> ${ d . changes . map ( c => `
< div class = "repair-detail-subitem" > < strong > $ { _escFinding ( c ) } < / s t r o n g > < / d i v > ` ) . j o i n ( ' ' ) } < / d i v > ` ;
}
tnHtml += _renderPlayButton ( f ) ;
return tnHtml ;
default :