@@ -12,6 +12,7 @@ import NVActivityIndicatorView
1212class StationTableViewCell : UITableViewCell {
1313
1414 // MARK: - UI
15+ private var representedStation : RadioStation ?
1516
1617 private let cardBlurView : UIVisualEffectView = {
1718 let blur = UIBlurEffect ( style: . systemUltraThinMaterialDark)
@@ -107,6 +108,22 @@ class StationTableViewCell: UITableViewCell {
107108 return view
108109 } ( )
109110
111+ private let bufferingOverlay : UIView = {
112+ let view = UIView ( )
113+ view. backgroundColor = UIColor . black. withAlphaComponent ( 0.5 )
114+ view. layer. cornerRadius = 12
115+ view. clipsToBounds = true
116+ view. alpha = 0
117+ view. translatesAutoresizingMaskIntoConstraints = false
118+ return view
119+ } ( )
120+
121+ private let bufferingIndicator : NVActivityIndicatorView = {
122+ let view = NVActivityIndicatorView ( frame: . zero, type: . ballPulse, color: . white, padding: nil )
123+ view. translatesAutoresizingMaskIntoConstraints = false
124+ return view
125+ } ( )
126+
110127 private var isAnimatingPulse = false
111128
112129 // MARK: - Init
@@ -122,13 +139,16 @@ class StationTableViewCell: UITableViewCell {
122139
123140 override func prepareForReuse( ) {
124141 super. prepareForReuse ( )
142+ representedStation = nil
125143 titleLabel. text = nil
126144 subtitleLabel. text = nil
127145 stationImageView. image = nil
128146 stopPulseAnimation ( )
129147 pulseRingView. alpha = 0
130148 equalizerView. stopAnimating ( )
131149 equalizerView. alpha = 0
150+ bufferingIndicator. stopAnimating ( )
151+ bufferingOverlay. alpha = 0
132152 }
133153
134154 // MARK: - Highlight / Tap Feedback
@@ -160,6 +180,8 @@ class StationTableViewCell: UITableViewCell {
160180 artworkContainer. addSubview ( artworkShadowView)
161181 artworkContainer. addSubview ( pulseRingView)
162182 artworkContainer. addSubview ( stationImageView)
183+ artworkContainer. addSubview ( bufferingOverlay)
184+ bufferingOverlay. addSubview ( bufferingIndicator)
163185
164186 // Subtitle stack: label + equalizer
165187 subtitleStack. addArrangedSubview ( equalizerView)
@@ -223,25 +245,51 @@ class StationTableViewCell: UITableViewCell {
223245 pulseRingView. bottomAnchor. constraint ( equalTo: stationImageView. bottomAnchor, constant: - pulseInset) ,
224246 pulseRingView. leadingAnchor. constraint ( equalTo: stationImageView. leadingAnchor, constant: pulseInset) ,
225247 pulseRingView. trailingAnchor. constraint ( equalTo: stationImageView. trailingAnchor, constant: - pulseInset) ,
248+
249+ // Buffering overlay on top of image
250+ bufferingOverlay. topAnchor. constraint ( equalTo: stationImageView. topAnchor) ,
251+ bufferingOverlay. bottomAnchor. constraint ( equalTo: stationImageView. bottomAnchor) ,
252+ bufferingOverlay. leadingAnchor. constraint ( equalTo: stationImageView. leadingAnchor) ,
253+ bufferingOverlay. trailingAnchor. constraint ( equalTo: stationImageView. trailingAnchor) ,
254+ bufferingIndicator. centerXAnchor. constraint ( equalTo: bufferingOverlay. centerXAnchor) ,
255+ bufferingIndicator. centerYAnchor. constraint ( equalTo: bufferingOverlay. centerYAnchor) ,
256+ bufferingIndicator. widthAnchor. constraint ( equalToConstant: 30 ) ,
257+ bufferingIndicator. heightAnchor. constraint ( equalToConstant: 20 ) ,
226258 ] )
227259 }
228260
229261 // MARK: - Now Playing
230262
231- func setNowPlaying( isPlaying: Bool , isCurrentStation: Bool ) {
263+ func setNowPlaying( isPlaying: Bool , isBuffering : Bool , isCurrentStation: Bool ) {
232264 guard isCurrentStation else {
233265 stopPulseAnimation ( )
234266 pulseRingView. alpha = 0
235267 equalizerView. stopAnimating ( )
236268 equalizerView. alpha = 0
269+ bufferingIndicator. stopAnimating ( )
270+ bufferingOverlay. alpha = 0
237271 return
238272 }
239273
240- if isPlaying {
274+ if isBuffering {
275+ // Dark overlay + buffering indicator on artwork
276+ stopPulseAnimation ( )
277+ pulseRingView. alpha = 0
278+ equalizerView. stopAnimating ( )
279+ equalizerView. alpha = 0
280+ bufferingIndicator. startAnimating ( )
281+ bufferingOverlay. alpha = 1
282+ } else if isPlaying {
283+ // Pulse ring + equalizer
284+ bufferingIndicator. stopAnimating ( )
285+ bufferingOverlay. alpha = 0
241286 startPulseAnimation ( )
242287 equalizerView. startAnimating ( )
243288 equalizerView. alpha = 0.7
244289 } else {
290+ // Stopped — subtle indicators
291+ bufferingIndicator. stopAnimating ( )
292+ bufferingOverlay. alpha = 0
245293 stopPulseAnimation ( )
246294 pulseRingView. alpha = 0.25
247295 pulseRingView. transform = . identity
@@ -277,11 +325,13 @@ class StationTableViewCell: UITableViewCell {
277325
278326extension StationTableViewCell {
279327 func configureStationCell( station: RadioStation ) {
328+ representedStation = station
280329 titleLabel. text = station. name
281330 subtitleLabel. text = station. desc
282331
283332 station. getImage { [ weak self] image in
284- self ? . stationImageView. image = image
333+ guard let self = self , self . representedStation == station else { return }
334+ self . stationImageView. image = image
285335 }
286336 }
287337}
0 commit comments