2121import java .util .concurrent .ScheduledExecutorService ;
2222import java .util .concurrent .TimeUnit ;
2323
24+ import android .animation .ValueAnimator ;
2425import android .annotation .TargetApi ;
2526import androidx .appcompat .app .AlertDialog ;
2627import android .content .DialogInterface ;
2728import android .content .Intent ;
2829import android .content .SharedPreferences ;
2930import android .content .res .Configuration ;
31+ import android .graphics .Bitmap ;
32+ import android .graphics .Color ;
33+ import android .graphics .Rect ;
34+ import android .graphics .drawable .GradientDrawable ;
35+ import android .graphics .drawable .TransitionDrawable ;
3036import android .os .Build ;
3137import android .os .Bundle ;
3238import android .os .Handler ;
39+
40+ import androidx .core .graphics .ColorUtils ;
3341import androidx .core .view .MenuItemCompat ;
3442import androidx .mediarouter .app .MediaRouteButton ;
3543import androidx .recyclerview .widget .LinearLayoutManager ;
5058import android .view .WindowManager ;
5159import android .view .animation .AnimationUtils ;
5260import android .widget .EditText ;
61+ import android .widget .FrameLayout ;
5362import android .widget .ImageButton ;
54- import android .widget .ImageView ;
5563import android .widget .SeekBar ;
5664import android .widget .TextView ;
5765import android .widget .ViewFlipper ;
5866import com .shehabic .droppy .DroppyClickCallbackInterface ;
5967import com .shehabic .droppy .DroppyMenuPopup ;
6068import com .shehabic .droppy .animations .DroppyFadeInAnimation ;
69+
6170import github .paroj .dsub2000 .R ;
6271import github .paroj .dsub2000 .activity .SubsonicFragmentActivity ;
6372import github .paroj .dsub2000 .adapter .SectionAdapter ;
7887import github .paroj .dsub2000 .adapter .DownloadFileAdapter ;
7988import github .paroj .dsub2000 .view .FadeOutAnimation ;
8089import github .paroj .dsub2000 .view .FastScroller ;
90+ import github .paroj .dsub2000 .view .RecyclingImageView ;
8191import github .paroj .dsub2000 .view .UpdateView ;
8292import github .paroj .dsub2000 .util .Util ;
8393
@@ -95,12 +105,15 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
95105 private static final int ACTION_PREVIOUS = 1 ;
96106 private static final int ACTION_NEXT = 2 ;
97107 private static final int ACTION_REWIND = 3 ;
98- private static final int ACTION_FORWARD = 4 ;
108+ private static final int ACTION_CLOSE = 4 ;
99109
110+ private FrameLayout downloadLayout ;
111+ private int lastAlbumArtColor ;
112+ private GradientDrawable glowDrawable ;
100113 private ViewFlipper playlistFlipper ;
101114 private TextView emptyTextView ;
102115 private TextView songTitleTextView ;
103- private ImageView albumArtImageView ;
116+ private RecyclingImageView albumArtImageView ;
104117 private RecyclerView playlistView ;
105118 private TextView positionTextView ;
106119 private TextView durationTextView ;
@@ -169,11 +182,63 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bu
169182 swipeDistance = (d .getWidth () + d .getHeight ()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100 ;
170183 swipeVelocity = (d .getWidth () + d .getHeight ()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100 ;
171184 gestureScanner = new GestureDetector (this );
185+ downloadLayout = (FrameLayout ) rootView .findViewById (R .id .download_album_art_background );
186+ downloadLayout .setOnTouchListener (new View .OnTouchListener () {
187+ @ Override
188+ public boolean onTouch (View v , MotionEvent me ) {
189+ return gestureScanner .onTouchEvent (me );
190+ }
191+ });
192+ albumArtImageView = (RecyclingImageView )rootView .findViewById (R .id .download_album_art_image );
193+ if (albumArtImageView != null && downloadLayout != null ) {
194+ glowDrawable = new GradientDrawable ();
195+ downloadLayout .setBackground (glowDrawable );
196+ albumArtImageView .setOnImageChangedListener (drawable -> {
197+ if (drawable instanceof TransitionDrawable ) {
198+ return ;
199+ }
200+ Bitmap bitmap = ImageUtil .getBitmapFromDrawable (drawable );
201+ int albumArtColor = ImageUtil .getVibrantColorFromBitmap (bitmap , Color .TRANSPARENT );
202+ if (albumArtColor == Color .TRANSPARENT || lastAlbumArtColor == albumArtColor ) {
203+ return ;
204+ }
205+
206+ int gWidth = downloadLayout .getMeasuredWidth ();
207+ int gHeight = downloadLayout .getMeasuredHeight ();
208+ float gradientRadius = Math .max (gWidth , gHeight ) * 0.52f ;
209+ glowDrawable .setGradientType (GradientDrawable .RADIAL_GRADIENT );
210+ glowDrawable .setGradientRadius (gradientRadius );
211+ glowDrawable .setDither (true );
212+
213+ ValueAnimator animator = ValueAnimator .ofArgb (lastAlbumArtColor , albumArtColor );
214+ animator .setDuration (900 );
215+ animator .addUpdateListener (animation -> {
216+ int color = (int ) animation .getAnimatedValue ();
217+ glowDrawable .setColors (new int []{
218+ ColorUtils .setAlphaComponent (color , 100 ),
219+ ColorUtils .setAlphaComponent (color , 100 ),
220+ ColorUtils .setAlphaComponent (color , 100 ),
221+ ColorUtils .setAlphaComponent (color , 80 ),
222+ ColorUtils .setAlphaComponent (color , 0 )
223+ });
224+ });
225+ animator .start ();
226+ lastAlbumArtColor = albumArtColor ;
227+ });
228+ albumArtImageView .setOnTouchListener (new View .OnTouchListener () {
229+ @ Override
230+ public boolean onTouch (View v , MotionEvent me ) {
231+ if (me .getAction () == MotionEvent .ACTION_DOWN ) {
232+ lastY = (int ) me .getRawY ();
233+ }
234+ return gestureScanner .onTouchEvent (me );
235+ }
236+ });
237+ }
172238
173239 playlistFlipper = (ViewFlipper )rootView .findViewById (R .id .download_playlist_flipper );
174240 emptyTextView = (TextView )rootView .findViewById (R .id .download_empty );
175241 songTitleTextView = (TextView )rootView .findViewById (R .id .download_song_title );
176- albumArtImageView = (ImageView )rootView .findViewById (R .id .download_album_art_image );
177242 positionTextView = (TextView )rootView .findViewById (R .id .download_position );
178243 durationTextView = (TextView )rootView .findViewById (R .id .download_duration );
179244 statusTextView = (TextView )rootView .findViewById (R .id .download_status );
@@ -237,15 +302,6 @@ public boolean onTouch(View v, MotionEvent me) {
237302 rateCombinedButton .setOnTouchListener (touchListener );
238303 playbackSpeedButton .setOnTouchListener (touchListener );
239304 emptyTextView .setOnTouchListener (touchListener );
240- albumArtImageView .setOnTouchListener (new View .OnTouchListener () {
241- @ Override
242- public boolean onTouch (View v , MotionEvent me ) {
243- if (me .getAction () == MotionEvent .ACTION_DOWN ) {
244- lastY = (int ) me .getRawY ();
245- }
246- return gestureScanner .onTouchEvent (me );
247- }
248- });
249305
250306 previousButton .setOnClickListener (new View .OnClickListener () {
251307 @ Override
@@ -436,7 +492,7 @@ public void onClick(View view) {
436492 albumArtImageView .setOnClickListener (new View .OnClickListener () {
437493 @ Override
438494 public void onClick (View view ) {
439- if (Util .getPreferences (context ).getBoolean (Constants .PREFERENCES_KEY_TAP_COVER_FOR_PLAYLIST , true )) {
495+ if (Util .getPreferences (context ).getBoolean (Constants .PREFERENCES_KEY_TAP_COVER_FOR_PLAYLIST , false )) {
440496 if (overlayHeight == -1 || lastY < (view .getBottom () - overlayHeight )) {
441497 toggleFullscreenAlbumArt ();
442498 setControlsVisible (true );
@@ -1190,13 +1246,22 @@ else if (e2.getX() - e1.getX() > swipeDistance && Math.abs(velocityX) > swipeVel
11901246 }
11911247 // Top to Bottom swipe
11921248 else if (e2 .getY () - e1 .getY () > swipeDistance && Math .abs (velocityY ) > swipeVelocity ) {
1193- action = ACTION_FORWARD ;
1249+ action = ACTION_CLOSE ;
11941250 }
11951251 // Bottom to Top swipe
11961252 else if (e1 .getY () - e2 .getY () > swipeDistance && Math .abs (velocityY ) > swipeVelocity ) {
11971253 action = ACTION_REWIND ;
11981254 }
11991255
1256+ Rect rect = new Rect ();
1257+ albumArtImageView .getGlobalVisibleRect (rect );
1258+ int x = (int ) e1 .getRawX ();
1259+ int y = (int ) e1 .getRawY ();
1260+ boolean startedOnImage = rect .contains (x , y );
1261+ if (!startedOnImage && action != ACTION_CLOSE ) {
1262+ return false ;
1263+ }
1264+
12001265 if (action > 0 ) {
12011266 final int performAction = action ;
12021267 warnIfStorageUnavailable ();
@@ -1210,8 +1275,9 @@ protected Void doInBackground() throws Throwable {
12101275 case ACTION_PREVIOUS :
12111276 downloadService .previous ();
12121277 break ;
1213- case ACTION_FORWARD :
1214- downloadService .fastForward ();
1278+ case ACTION_CLOSE :
1279+ SubsonicFragmentActivity activity = (SubsonicFragmentActivity ) getActivity ();
1280+ activity .closeNowPlaying ();
12151281 break ;
12161282 case ACTION_REWIND :
12171283 downloadService .rewind ();
0 commit comments