@@ -6,74 +6,74 @@ import type { Locale } from "../../lib/locale";
66import type { Channel } from "../../types/player" ;
77
88interface ChannelListItemProps {
9- channel : Channel ;
10- isCurrentChannel : boolean ;
11- handleChannelClick : ( channel : Channel ) => void ;
12- locale : Locale ;
13- currentProgram ?: string ;
9+ channel : Channel ;
10+ isCurrentChannel : boolean ;
11+ handleChannelClick : ( channel : Channel ) => void ;
12+ locale : Locale ;
13+ currentProgram ?: string ;
1414}
1515
1616const ChannelListItemComponent = forwardRef < HTMLButtonElement , ChannelListItemProps > (
17- ( { channel, isCurrentChannel, handleChannelClick, locale, currentProgram } , ref ) => {
18- const t = usePlayerTranslation ( locale ) ;
17+ ( { channel, isCurrentChannel, handleChannelClick, locale, currentProgram } , ref ) => {
18+ const t = usePlayerTranslation ( locale ) ;
1919
20- const handleClick = useCallback ( ( ) => {
21- handleChannelClick ( channel ) ;
22- } , [ handleChannelClick , channel ] ) ;
20+ const handleClick = useCallback ( ( ) => {
21+ handleChannelClick ( channel ) ;
22+ } , [ handleChannelClick , channel ] ) ;
2323
24- return (
25- < button
26- type = "button"
27- key = { channel . id }
28- ref = { ref }
29- className = { clsx (
30- "rounded-xl border bg-card text-card-foreground shadow group cursor-pointer overflow-hidden transition duration-200 flex items-center gap-2 p-2 w-full text-left" ,
31- isCurrentChannel
32- ? "border-primary bg-primary/5 shadow-md"
33- : "border-border hover:border-primary/50 hover:bg-muted/50 hover:shadow-sm" ,
34- ) }
35- onClick = { handleClick }
36- >
37- { /* Left: Channel Number and Info */ }
38- < span className = "flex h-5 md:h-6 min-w-7 md:min-w-8 items-center justify-center rounded-md bg-primary/10 px-1.5 md:px-2 text-[10px] md:text-xs font-semibold text-primary shrink-0" >
39- { channel . id }
40- </ span >
41- < div className = "flex-1 overflow-hidden min-w-0" >
42- < div className = "flex items-center gap-1 md:gap-1.5" >
43- < div className = "truncate text-sm md:text-base font-semibold leading-tight" > { channel . name } </ div >
44- { channel . sources . some ( ( s ) => s . catchup && s . catchupSource ) && (
45- < span title = { t ( "catchupSupported" ) } >
46- < History className = "h-3 w-3 md:h-3.5 md:w-3.5 shrink-0 text-primary" />
47- </ span >
48- ) }
49- </ div >
50- < div className = "mt-0.5 truncate text-[10px] md:text-xs text-muted-foreground" >
51- { channel . group }
52- { currentProgram && (
53- < >
54- < span className = "mx-1" > ·</ span >
55- < span > { currentProgram } </ span >
56- </ >
57- ) }
58- </ div >
59- </ div >
60- { /* Right: Logo */ }
61- { channel . logo && (
62- < div className = "flex h-8 w-12 md:h-10 md:w-16 shrink-0 items-center justify-center overflow-hidden rounded bg-linear-to-br from-muted/20 to-muted/40 p-0.5 md:p-1" >
63- < img
64- src = { channel . logo }
65- alt = { channel . name }
66- referrerPolicy = "no-referrer"
67- className = "h-full w-full object-contain transition-transform duration-200 group-hover:scale-105 drop-shadow-[0_1px_2px_rgba(0,0,0,0.3)]"
68- onError = { ( e ) => {
69- ( e . target as HTMLImageElement ) . style . display = "none" ;
70- } }
71- />
72- </ div >
73- ) }
74- </ button >
75- ) ;
76- } ,
24+ return (
25+ < button
26+ type = "button"
27+ key = { channel . id }
28+ ref = { ref }
29+ className = { clsx (
30+ "rounded-xl border bg-card text-card-foreground shadow group cursor-pointer overflow-hidden transition duration-200 flex items-center gap-2 p-2 w-full text-left" ,
31+ isCurrentChannel
32+ ? "border-primary bg-primary/5 shadow-md"
33+ : "border-border hover:border-primary/50 hover:bg-muted/50 hover:shadow-sm" ,
34+ ) }
35+ onClick = { handleClick }
36+ >
37+ { /* Left: Channel Number and Info */ }
38+ < span className = "flex h-5 md:h-6 min-w-7 md:min-w-8 items-center justify-center rounded-md bg-primary/10 px-1.5 md:px-2 text-[10px] md:text-xs font-semibold text-primary shrink-0" >
39+ { channel . id }
40+ </ span >
41+ < div className = "flex-1 overflow-hidden min-w-0" >
42+ < div className = "flex items-center gap-1 md:gap-1.5" >
43+ < div className = "truncate text-sm md:text-base font-semibold leading-tight" > { channel . name } </ div >
44+ { channel . sources . some ( ( s ) => s . catchup && s . catchupSource ) && (
45+ < span title = { t ( "catchupSupported" ) } >
46+ < History className = "h-3 w-3 md:h-3.5 md:w-3.5 shrink-0 text-primary" />
47+ </ span >
48+ ) }
49+ </ div >
50+ < div className = "mt-0.5 truncate text-[10px] md:text-xs text-muted-foreground" >
51+ { channel . group }
52+ { currentProgram && (
53+ < >
54+ < span className = "mx-1" > ·</ span >
55+ < span > { currentProgram } </ span >
56+ </ >
57+ ) }
58+ </ div >
59+ </ div >
60+ { /* Right: Logo */ }
61+ { channel . logo && (
62+ < div className = "flex h-8 w-12 md:h-10 md:w-16 shrink-0 items-center justify-center overflow-hidden rounded bg-linear-to-br from-muted/20 to-muted/40 p-0.5 md:p-1" >
63+ < img
64+ src = { channel . logo }
65+ alt = { channel . name }
66+ referrerPolicy = "no-referrer"
67+ className = "h-full w-full object-contain transition-transform duration-200 group-hover:scale-105 drop-shadow-[0_1px_2px_rgba(0,0,0,0.3)]"
68+ onError = { ( e ) => {
69+ ( e . target as HTMLImageElement ) . style . display = "none" ;
70+ } }
71+ />
72+ </ div >
73+ ) }
74+ </ button >
75+ ) ;
76+ } ,
7777) ;
7878
7979export const ChannelListItem = memo ( ChannelListItemComponent ) ;
0 commit comments