@@ -3207,18 +3207,27 @@ function renderServerList(servers) {
32073207 servers . filter ( s => _normType ( s . type ) === 'iptv' ) . forEach ( refreshIPTVServerCardStatus ) ;
32083208}
32093209
3210+ // Channel/EPG-matched counts shared by the settings server card and the
3211+ // library browser status line. EPG is dropped entirely when zero — most
3212+ // sources have no EPG configured, and "EPG 0" carries no information.
3213+ function _iptvCountParts ( summary ) {
3214+ const parts = [ tr ( 'iptvChannelsCount' , { count : summary . channel_count || 0 } ) ] ;
3215+ if ( summary . epg_matched_count ) parts . push ( tr ( 'iptvEpgMatched' , { count : summary . epg_matched_count } ) ) ;
3216+ return parts ;
3217+ }
3218+
32103219async function refreshIPTVServerCardStatus ( s ) {
32113220 try {
32123221 const summary = await api ( 'GET' , `/api/iptv/summary?server_id=${ encodeURIComponent ( s . id ) } ` ) ;
32133222 const el = document . getElementById ( `iptv-summary-${ s . id } ` ) ;
32143223 if ( ! el ) return ;
3215- const statusKey = summary . refresh_status === 'ok' ? 'iptvSourceStatusOk'
3216- : ( summary . refresh_status === 'error' ? 'iptvSourceStatusError' : 'iptvSourceStatusPending' ) ;
3217- el . textContent = [
3218- tr ( 'iptvChannelsCount' , { count : summary . channel_count || 0 } ) ,
3219- tr ( 'iptvEpgMatched' , { count : summary . epg_matched_count || 0 } ) ,
3220- tr ( statusKey ) ,
3221- ] . join ( ' · ' ) ;
3224+ const parts = _iptvCountParts ( summary ) ;
3225+ // "ok" is the expected steady state and is already implied by having
3226+ // fresh counts; only surface the badge when there's something to flag.
3227+ if ( summary . refresh_status !== 'ok' ) {
3228+ parts . push ( tr ( summary . refresh_status === 'error' ? 'iptvSourceStatusError' : 'iptvSourceStatusPending' ) ) ;
3229+ }
3230+ el . textContent = parts . join ( ' · ' ) ;
32223231 el . classList . toggle ( 'iptv-status-error' , summary . refresh_status === 'error' ) ;
32233232 } catch ( _ ) { }
32243233}
@@ -3782,21 +3791,18 @@ async function loadIPTVSourceStatus() {
37823791function renderIPTVSourceStatus ( s ) {
37833792 const el = document . getElementById ( 'iptv-source-status' ) ;
37843793 if ( ! el ) return ;
3785- const statusKey = s . refresh_status === 'ok' ? 'iptvSourceStatusOk'
3786- : ( s . refresh_status === 'error' ? 'iptvSourceStatusError' : 'iptvSourceStatusPending' ) ;
3787- const parts = [
3788- tr ( 'iptvChannelsCount' , { count : s . channel_count || 0 } ) ,
3789- tr ( 'iptvEpgMatched' , { count : s . epg_matched_count || 0 } ) ,
3790- ] ;
3794+ const parts = _iptvCountParts ( s ) ;
37913795 if ( s . last_refreshed ) {
37923796 const time = new Date ( s . last_refreshed ) ;
37933797 if ( ! isNaN ( time ) ) parts . push ( tr ( 'iptvLastUpdated' , { time : time . toLocaleString ( ) } ) ) ;
37943798 }
3795- const statusCls = s . refresh_status === 'error' ? ' iptv-status-error' : '' ;
3796- el . innerHTML = `
3797- <span>${ parts . map ( esc ) . join ( ' · ' ) } </span>
3798- <span class="${ statusCls } ">${ esc ( tr ( statusKey ) ) } </span>
3799- ` ;
3799+ // "ok" is the expected steady state and is already implied by having
3800+ // fresh counts; only show a second line when there's something to flag.
3801+ const badge = s . refresh_status === 'ok' ? '' : `
3802+ <span class="${ s . refresh_status === 'error' ? 'iptv-status-error' : '' } ">${ esc ( tr (
3803+ s . refresh_status === 'error' ? 'iptvSourceStatusError' : 'iptvSourceStatusPending'
3804+ ) ) } </span>`;
3805+ el . innerHTML = `<span class="iptv-source-status-line">${ parts . map ( esc ) . join ( ' · ' ) } </span>${ badge } ` ;
38003806}
38013807
38023808async function refreshIPTVSource ( ) {
0 commit comments