diff --git a/app/build.gradle b/app/build.gradle
index db0ac695..d1c3940a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -125,6 +125,7 @@ dependencies {
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.github.kabouzeid:Android-Universal-Image-Loader:c2894ad9f1'
compile 'com.jakewharton:butterknife:7.0.1'
+ compile 'org.solovyev.android.views:linear-layout-manager:0.5@aar'
//noinspection GradleDynamicVersion
compile 'com.anjlab.android.iab.v3:library:1.0.+@aar'
}
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsSlidingMusicPanelActivity.java b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsSlidingMusicPanelActivity.java
index 1352fdcb..e62da28b 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsSlidingMusicPanelActivity.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/activities/base/AbsSlidingMusicPanelActivity.java
@@ -12,8 +12,8 @@ import android.view.ViewGroup;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
-import com.kabouzeid.gramophone.ui.fragments.MiniPlayerFragment;
-import com.kabouzeid.gramophone.ui.fragments.PlayerFragment;
+import com.kabouzeid.gramophone.ui.fragments.player.MiniPlayerFragment;
+import com.kabouzeid.gramophone.ui.fragments.player.PlayerFragment;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import butterknife.Bind;
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlayerFragment.java b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlayerFragment.java
deleted file mode 100644
index e98f0185..00000000
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlayerFragment.java
+++ /dev/null
@@ -1,411 +0,0 @@
-package com.kabouzeid.gramophone.ui.fragments;
-
-import android.animation.AnimatorSet;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.support.annotation.ColorInt;
-import android.support.v4.app.Fragment;
-import android.support.v7.widget.Toolbar;
-import android.view.LayoutInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.kabouzeid.gramophone.R;
-import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
-import com.kabouzeid.gramophone.dialogs.PlayingQueueDialog;
-import com.kabouzeid.gramophone.dialogs.SleepTimerDialog;
-import com.kabouzeid.gramophone.dialogs.SongDetailDialog;
-import com.kabouzeid.gramophone.dialogs.SongShareDialog;
-import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
-import com.kabouzeid.gramophone.helper.MusicProgressViewUpdateHelper;
-import com.kabouzeid.gramophone.interfaces.MusicServiceEventListener;
-import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
-import com.kabouzeid.gramophone.loader.SongLoader;
-import com.kabouzeid.gramophone.model.Song;
-import com.kabouzeid.gramophone.ui.activities.base.AbsMusicServiceActivity;
-import com.kabouzeid.gramophone.ui.activities.tageditor.AbsTagEditorActivity;
-import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
-import com.kabouzeid.gramophone.util.ColorUtil;
-import com.kabouzeid.gramophone.util.MusicUtil;
-import com.kabouzeid.gramophone.util.NavigationUtil;
-import com.kabouzeid.gramophone.util.PreferenceUtil;
-import com.kabouzeid.gramophone.util.Util;
-import com.kabouzeid.gramophone.util.ViewUtil;
-
-import butterknife.Bind;
-import butterknife.ButterKnife;
-
-public class PlayerFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener, MusicServiceEventListener, Toolbar.OnMenuItemClickListener, PaletteColorHolder, MusicProgressViewUpdateHelper.Callback, PlayerAlbumCoverFragment.OnColorChangedListener {
- public static final String TAG = PlayerFragment.class.getSimpleName();
-
- @Bind(R.id.player_toolbar)
- Toolbar toolbar;
-
- private AnimatorSet colorTransitionAnimator;
- private int lastColor;
- private int lastPlaybackControlsColor;
-
- private Song song;
-
- private MusicProgressViewUpdateHelper progressViewUpdateHelper;
-
- private AbsMusicServiceActivity activity;
- private Callbacks callbacks;
-
- private PlaybackControlsFragment playbackControlsFragment;
- private PlayingInfoFragment playingInfoFragment;
- private PlayerAlbumCoverFragment playerAlbumCoverFragment;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- try {
- activity = (AbsMusicServiceActivity) context;
- callbacks = (Callbacks) context;
- } catch (ClassCastException e) {
- throw new RuntimeException(context.getClass().getSimpleName() + " must be an instance of " + AbsMusicServiceActivity.class.getSimpleName() + " and implement " + Callbacks.class.getSimpleName());
- }
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- activity = null;
- callbacks = null;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_player, container, false);
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- ButterKnife.bind(this, view);
-
- playbackControlsFragment = (PlaybackControlsFragment) getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
- playingInfoFragment = (PlayingInfoFragment) getChildFragmentManager().findFragmentById(R.id.playing_info_fragment);
- playerAlbumCoverFragment = (PlayerAlbumCoverFragment) getChildFragmentManager().findFragmentById(R.id.player_album_cover_fragment);
- playerAlbumCoverFragment.setOnColorChangedListener(this);
-
-// alignAlbumArt();
- setUpPlayerToolbar();
-// setUpPlayerStatusBarElevation();
-
- PreferenceUtil.getInstance(getContext()).registerOnSharedPreferenceChangedListener(this);
- activity.addMusicServiceEventListener(this);
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- activity.removeMusicServiceEventListener(this);
- PreferenceUtil.getInstance(activity).unregisterOnSharedPreferenceChangedListener(this);
- ButterKnife.unbind(this);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- progressViewUpdateHelper.start();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- progressViewUpdateHelper.stop();
- }
-
- @Override
- public void onPlayingMetaChanged() {
- updateCurrentSong();
- }
-
- @Override
- public void onPlayStateChanged() {
-
- }
-
- @Override
- public void onRepeatModeChanged() {
-
- }
-
- @Override
- public void onShuffleModeChanged() {
-
- }
-
- @Override
- public void onMediaStoreChanged() {
-
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- switch (key) {
-// case PreferenceUtil.OPAQUE_STATUSBAR_NOW_PLAYING:
-// opaqueStatusBar = PreferenceUtil.getInstance(activity).opaqueStatusbarNowPlaying();
-// // do not break here
-// case PreferenceUtil.OPAQUE_TOOLBAR_NOW_PLAYING:
-// opaqueToolBar = opaqueStatusBar && PreferenceUtil.getInstance(activity).opaqueToolbarNowPlaying();
-// setUpPlayerStatusBarElevation();
-// animateColorChange(lastColor);
-// alignAlbumArt();
-// break;
-// case PreferenceUtil.ALTERNATIVE_PROGRESS_SLIDER_NOW_PLAYING:
-// alternativeProgressSlider = PreferenceUtil.getInstance(activity).alternativeProgressSliderNowPlaying();
-// setUpProgressSlider();
-// break;
- }
- }
-
-// private void initProgressSliderDependentViews() {
-// if (getView() == null) return;
-// if (alternativeProgressSlider) {
-// getView().findViewById(R.id.player_default_progress_container).setVisibility(View.GONE);
-// getView().findViewById(R.id.player_default_progress_slider).setVisibility(View.GONE);
-// getView().findViewById(R.id.player_alternative_progress_container).setVisibility(View.VISIBLE);
-//
-// songCurrentProgress = (TextView) getView().findViewById(R.id.player_alternative_song_current_progress);
-// songTotalTime = (TextView) getView().findViewById(R.id.player_alternative_song_total_time);
-// progressSlider = (SeekBar) getView().findViewById(R.id.player_alternative_progress_slider);
-// } else {
-// getView().findViewById(R.id.player_default_progress_container).setVisibility(View.VISIBLE);
-// getView().findViewById(R.id.player_default_progress_slider).setVisibility(View.VISIBLE);
-// getView().findViewById(R.id.player_alternative_progress_container).setVisibility(View.GONE);
-//
-// songCurrentProgress = (TextView) getView().findViewById(R.id.player_default_song_current_progress);
-// songTotalTime = (TextView) getView().findViewById(R.id.player_default_song_total_time);
-// progressSlider = (SeekBar) getView().findViewById(R.id.player_default_progress_slider);
-// }
-// }
-//
-// private void moveProgressSliderIntoPlace() {
-// if (!alternativeProgressSlider) {
-// RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) progressSlider.getLayoutParams();
-// progressSlider.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
-// final int seekBarMarginLeftRight = getResources().getDimensionPixelSize(R.dimen.seek_bar_margin_left_right);
-// lp.setMargins(seekBarMarginLeftRight, 0, seekBarMarginLeftRight, -(progressSlider.getMeasuredHeight() / 2));
-// progressSlider.setLayoutParams(lp);
-// }
-// }
-
-// private void updateProgressSliderTint() {
-// int thumbColor;
-// int progressColor;
-// if (alternativeProgressSlider) {
-// if (colorPlaybackControls) {
-// thumbColor = lastPlaybackControlsColor;
-// } else {
-// thumbColor = ThemeSingleton.get().positiveColor.getDefaultColor();
-// }
-// progressColor = Color.TRANSPARENT;
-// } else {
-// if (colorPlaybackControls) {
-// if (ColorUtil.useDarkTextColorOnBackground(lastPlaybackControlsColor)) {
-// thumbColor = ColorUtil.shiftColor(lastPlaybackControlsColor, 1.2f);
-// } else {
-// thumbColor = ColorUtil.shiftColor(lastPlaybackControlsColor, 0.8f);
-// }
-// } else {
-// thumbColor = activity.getThemeColorAccent();
-// }
-// progressColor = thumbColor;
-// }
-// setSeekBarTint(progressSlider, thumbColor, progressColor);
-// }
-//
-// private static void setSeekBarTint(SeekBar seekBar, @ColorInt int thumbColor, @ColorInt int progressColor) {
-// seekBar.getThumb().mutate().setColorFilter(thumbColor, PorterDuff.Mode.SRC_IN);
-// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-// // this will only tint the left part of the progress bar
-// seekBar.setProgressTintList(ColorStateList.valueOf(progressColor));
-// } else {
-// seekBar.getProgressDrawable().mutate().setColorFilter(progressColor, PorterDuff.Mode.SRC_IN);
-// }
-// }
-
-// private void setUpProgressSlider() {
-// initProgressSliderDependentViews();
-// moveProgressSliderIntoPlace();
-// updateProgressSliderTint();
-// progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
-// @Override
-// public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-// if (fromUser) {
-// MusicPlayerRemote.seekTo(progress);
-// onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), MusicPlayerRemote.getSongDurationMillis());
-// }
-// }
-// });
-// }
-
-// private void alignAlbumArt() {
-// if (opaqueStatusBar) {
-// if (opaqueToolBar) {
-// alignAlbumArtToToolbar();
-// } else {
-// alignAlbumArtToStatusBar();
-// }
-// } else {
-// alignAlbumArtToTop();
-// }
-// }
-//
-// private void alignAlbumArtToTop() {
-// RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) albumArtFrame.getLayoutParams();
-// if (Build.VERSION.SDK_INT > 16) {
-// params.removeRule(RelativeLayout.BELOW);
-// } else {
-// params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
-// ViewGroup.LayoutParams.MATCH_PARENT);
-// params.addRule(RelativeLayout.ABOVE, R.id.player_footer_frame);
-// }
-// }
-//
-// private void alignAlbumArtToToolbar() {
-// RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) albumArtFrame.getLayoutParams();
-// params.addRule(RelativeLayout.BELOW, R.id.player_toolbar);
-// }
-//
-// private void alignAlbumArtToStatusBar() {
-// RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) albumArtFrame.getLayoutParams();
-// params.addRule(RelativeLayout.BELOW, R.id.player_status_bar);
-// }
-
- private void setUpPlayerToolbar() {
- toolbar.inflateMenu(R.menu.menu_player);
- toolbar.setNavigationIcon(R.drawable.ic_close_white_24dp);
- toolbar.setNavigationOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- activity.onBackPressed();
- }
- });
- toolbar.setOnMenuItemClickListener(this);
- }
-
-// private void setUpPlayerStatusBarElevation() {
-// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-// if (opaqueToolBar) {
-// statusbar.setElevation(getResources().getDimensionPixelSize(R.dimen.toolbar_elevation));
-// } else {
-// statusbar.setElevation(0);
-// }
-// }
-// }
-
- private void updatePlayerMenu() {
- boolean isFavorite = MusicUtil.isFavorite(activity, song);
- Drawable favoriteIcon = Util.getTintedDrawable(activity, isFavorite ? R.drawable.ic_favorite_white_24dp : R.drawable.ic_favorite_outline_white_24dp, ViewUtil.getToolbarIconColor(activity, PreferenceUtil.getInstance(activity).opaqueToolbarNowPlaying() && ColorUtil.useDarkTextColorOnBackground(lastColor)));
- toolbar.getMenu().findItem(R.id.action_toggle_favorite)
- .setIcon(favoriteIcon)
- .setTitle(isFavorite ? getString(R.string.action_remove_from_favorites) : getString(R.string.action_add_to_favorites));
- }
-
- private void updateCurrentSong() {
- getCurrentSong();
- updatePlayerMenu();
- }
-
- private void getCurrentSong() {
- song = MusicPlayerRemote.getCurrentSong();
- }
-
- @Override
- @ColorInt
- public int getPaletteColor() {
- return lastColor;
- }
-
- @Override
- public void onUpdateProgressViews(int progress, int total) {
-// progressSlider.setMax(total);
-// progressSlider.setProgress(progress);
-// songTotalTime.setText(MusicUtil.getReadableDurationString(total));
-// songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
- }
-
- private void animateColorChange(final int newColor) {
- getView().setBackgroundColor(newColor);
- lastColor = newColor;
- }
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.action_sleep_timer:
- new SleepTimerDialog().show(getFragmentManager(), "SET_SLEEP_TIMER");
- return true;
- case R.id.action_toggle_favorite:
- MusicUtil.toggleFavorite(activity, song);
- if (MusicUtil.isFavorite(activity, song)) {
- playerAlbumCoverFragment.showHeart();
- }
- updatePlayerMenu();
- return true;
- case R.id.action_share:
- SongShareDialog.create(song).show(getFragmentManager(), "SHARE_SONG");
- return true;
- case R.id.action_equalizer:
- NavigationUtil.openEqualizer(activity);
- return true;
- case R.id.action_shuffle_all:
- MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(activity), true);
- return true;
- case R.id.action_add_to_playlist:
- AddToPlaylistDialog.create(song).show(getFragmentManager(), "ADD_PLAYLIST");
- return true;
- case R.id.action_playing_queue:
- PlayingQueueDialog.create().show(getFragmentManager(), "PLAY_QUEUE");
- return true;
- case R.id.action_tag_editor:
- Intent intent = new Intent(activity, SongTagEditorActivity.class);
- intent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id);
- startActivity(intent);
- return true;
- case R.id.action_details:
- SongDetailDialog.create(song).show(getFragmentManager(), "SONG_DETAIL");
- return true;
- case R.id.action_go_to_album:
- NavigationUtil.goToAlbum(activity, song.albumId);
- return true;
- case R.id.action_go_to_artist:
- NavigationUtil.goToArtist(activity, song.artistId);
- return true;
- }
- return false;
- }
-
- public void showControls() {
- playbackControlsFragment.showControls();
- }
-
- public void resetShowControlsAnimation() {
- playbackControlsFragment.resetShowControlsAnimation();
- }
-
- @Override
- public void onColorChanged(int color) {
- animateColorChange(color);
- playbackControlsFragment.setColor(color);
- callbacks.onPaletteColorChanged();
- }
-
- public interface Callbacks {
- void onPaletteColorChanged();
- }
-}
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlayingInfoFragment.java b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlayingInfoFragment.java
deleted file mode 100644
index c41cbc29..00000000
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlayingInfoFragment.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.kabouzeid.gramophone.ui.fragments;
-
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.kabouzeid.gramophone.R;
-import com.kabouzeid.gramophone.interfaces.MusicServiceEventListener;
-import com.kabouzeid.gramophone.ui.activities.base.AbsMusicServiceActivity;
-
-import butterknife.ButterKnife;
-
-/**
- * @author Karim Abou Zeid (kabouzeid)
- */
-public class PlayingInfoFragment extends Fragment implements MusicServiceEventListener {
-
-
- private AbsMusicServiceActivity activity;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- try {
- activity = (AbsMusicServiceActivity) context;
- } catch (ClassCastException e) {
- throw new RuntimeException(context.getClass().getSimpleName() + " must be an instance of " + AbsMusicServiceActivity.class.getSimpleName());
- }
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
- activity = null;
- }
-
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_playing_info, container, false);
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- ButterKnife.bind(this, view);
- activity.addMusicServiceEventListener(this);
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- activity.removeMusicServiceEventListener(this);
- ButterKnife.unbind(this);
- }
-
- @Override
- public void onPlayingMetaChanged() {
-
- }
-
- @Override
- public void onPlayStateChanged() {
- }
-
- @Override
- public void onRepeatModeChanged() {
- }
-
- @Override
- public void onShuffleModeChanged() {
- }
-
- @Override
- public void onMediaStoreChanged() {
- }
-
-}
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/MiniPlayerFragment.java b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/MiniPlayerFragment.java
similarity index 99%
rename from app/src/main/java/com/kabouzeid/gramophone/ui/fragments/MiniPlayerFragment.java
rename to app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/MiniPlayerFragment.java
index 4ca804e7..eca87784 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/MiniPlayerFragment.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/MiniPlayerFragment.java
@@ -1,4 +1,4 @@
-package com.kabouzeid.gramophone.ui.fragments;
+package com.kabouzeid.gramophone.ui.fragments.player;
import android.content.Context;
import android.graphics.PorterDuff;
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlaybackControlsFragment.java b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlaybackControlsFragment.java
similarity index 98%
rename from app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlaybackControlsFragment.java
rename to app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlaybackControlsFragment.java
index 640864ec..dc0aa342 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlaybackControlsFragment.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlaybackControlsFragment.java
@@ -1,4 +1,4 @@
-package com.kabouzeid.gramophone.ui.fragments;
+package com.kabouzeid.gramophone.ui.fragments.player;
import android.content.Context;
import android.graphics.Color;
@@ -229,7 +229,7 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
lastPlaybackControlsColor));
break;
default:
- shuffleButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_shuffle_white_36dp,
+ shuffleButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_trending_flat_white_36dp,
lastPlaybackControlsColor));
break;
}
@@ -256,7 +256,7 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
lastPlaybackControlsColor));
break;
default:
- repeatButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_repeat_white_36dp,
+ repeatButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_repeat_off_white_36dp,
lastPlaybackControlsColor));
break;
}
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlayerAlbumCoverFragment.java b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerAlbumCoverFragment.java
similarity index 99%
rename from app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlayerAlbumCoverFragment.java
rename to app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerAlbumCoverFragment.java
index ecd94d7c..42ebedd4 100644
--- a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/PlayerAlbumCoverFragment.java
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerAlbumCoverFragment.java
@@ -1,4 +1,4 @@
-package com.kabouzeid.gramophone.ui.fragments;
+package com.kabouzeid.gramophone.ui.fragments.player;
import android.animation.Animator;
import android.content.Context;
diff --git a/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerFragment.java b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerFragment.java
new file mode 100644
index 00000000..1a03a82a
--- /dev/null
+++ b/app/src/main/java/com/kabouzeid/gramophone/ui/fragments/player/PlayerFragment.java
@@ -0,0 +1,277 @@
+package com.kabouzeid.gramophone.ui.fragments.player;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.annotation.ColorInt;
+import android.support.v4.app.Fragment;
+import android.support.v7.widget.CardView;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
+import android.view.LayoutInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.widget.RelativeLayout;
+
+import com.kabouzeid.gramophone.R;
+import com.kabouzeid.gramophone.adapter.song.SongAdapter;
+import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
+import com.kabouzeid.gramophone.dialogs.PlayingQueueDialog;
+import com.kabouzeid.gramophone.dialogs.SleepTimerDialog;
+import com.kabouzeid.gramophone.dialogs.SongDetailDialog;
+import com.kabouzeid.gramophone.dialogs.SongShareDialog;
+import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
+import com.kabouzeid.gramophone.interfaces.MusicServiceEventListener;
+import com.kabouzeid.gramophone.interfaces.PaletteColorHolder;
+import com.kabouzeid.gramophone.loader.SongLoader;
+import com.kabouzeid.gramophone.model.Song;
+import com.kabouzeid.gramophone.ui.activities.MainActivity;
+import com.kabouzeid.gramophone.ui.activities.base.AbsMusicServiceActivity;
+import com.kabouzeid.gramophone.ui.activities.tageditor.AbsTagEditorActivity;
+import com.kabouzeid.gramophone.ui.activities.tageditor.SongTagEditorActivity;
+import com.kabouzeid.gramophone.util.ColorUtil;
+import com.kabouzeid.gramophone.util.MusicUtil;
+import com.kabouzeid.gramophone.util.NavigationUtil;
+import com.kabouzeid.gramophone.util.Util;
+import com.kabouzeid.gramophone.util.ViewUtil;
+import com.kabouzeid.gramophone.views.SquareLayout;
+import com.sothree.slidinguppanel.SlidingUpPanelLayout;
+
+import org.solovyev.android.views.llm.LinearLayoutManager;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+
+public class PlayerFragment extends Fragment implements MusicServiceEventListener, Toolbar.OnMenuItemClickListener, PaletteColorHolder, PlayerAlbumCoverFragment.OnColorChangedListener {
+ public static final String TAG = PlayerFragment.class.getSimpleName();
+
+ @Bind(R.id.player_toolbar)
+ Toolbar toolbar;
+ @Bind(R.id.player_sliding_layout)
+ SlidingUpPanelLayout slidingUpPanelLayout;
+ @Bind(R.id.player_recycler_view)
+ RecyclerView recyclerView;
+ @Bind(R.id.playing_queue_card)
+ CardView playingQueueCard;
+ @Bind(R.id.album_cover_container)
+ SquareLayout albumCoverContainer;
+ @Bind(R.id.player_content)
+ RelativeLayout playerContent;
+
+ private int lastColor;
+
+ private AbsMusicServiceActivity activity;
+ private Callbacks callbacks;
+
+ private PlaybackControlsFragment playbackControlsFragment;
+ private PlayerAlbumCoverFragment playerAlbumCoverFragment;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ try {
+ activity = (AbsMusicServiceActivity) context;
+ callbacks = (Callbacks) context;
+ } catch (ClassCastException e) {
+ throw new RuntimeException(context.getClass().getSimpleName() + " must be an instance of " + AbsMusicServiceActivity.class.getSimpleName() + " and implement " + Callbacks.class.getSimpleName());
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ activity = null;
+ callbacks = null;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_player, container, false);
+ }
+
+ @Override
+ public void onViewCreated(final View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ ButterKnife.bind(this, view);
+
+ setUpPlayerToolbar();
+ setUpSubFragments();
+
+ recyclerView.setAdapter(new SongAdapter(
+ ((MainActivity) getActivity()),
+ SongLoader.getAllSongs(getActivity()),
+ R.layout.item_list,
+ false,
+ ((MainActivity) getActivity())));
+
+ // TODO set child size
+ recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
+
+ view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ setUpPanelAndAlbumCoverHeight();
+ }
+ });
+
+
+
+ activity.addMusicServiceEventListener(this);
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ activity.removeMusicServiceEventListener(this);
+ ButterKnife.unbind(this);
+ }
+
+ @Override
+ public void onPlayingMetaChanged() {
+ updatePlayerMenu();
+ }
+
+ @Override
+ public void onPlayStateChanged() {
+
+ }
+
+ @Override
+ public void onRepeatModeChanged() {
+
+ }
+
+ @Override
+ public void onShuffleModeChanged() {
+
+ }
+
+ @Override
+ public void onMediaStoreChanged() {
+
+ }
+
+ private void setUpPanelAndAlbumCoverHeight() {
+ final int availablePanelHeight = slidingUpPanelLayout.getHeight() - playerContent.getHeight();
+ final int minPanelHeight = (int) getResources().getDisplayMetrics().density * (72 + 32);
+ if (availablePanelHeight < minPanelHeight) {
+ albumCoverContainer.getLayoutParams().height = albumCoverContainer.getHeight() - (minPanelHeight - availablePanelHeight);
+ albumCoverContainer.forceSquare(false);
+ }
+ slidingUpPanelLayout.setPanelHeight(Math.max(minPanelHeight, availablePanelHeight));
+ }
+
+ private void setUpSubFragments() {
+ playbackControlsFragment = (PlaybackControlsFragment) getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
+ playerAlbumCoverFragment = (PlayerAlbumCoverFragment) getChildFragmentManager().findFragmentById(R.id.player_album_cover_fragment);
+
+ playerAlbumCoverFragment.setOnColorChangedListener(this);
+ }
+
+ private void setUpPlayerToolbar() {
+ toolbar.inflateMenu(R.menu.menu_player);
+ toolbar.setNavigationIcon(R.drawable.ic_close_white_24dp);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ activity.onBackPressed();
+ }
+ });
+ toolbar.setOnMenuItemClickListener(this);
+ }
+
+ private void updatePlayerMenu() {
+ boolean isFavorite = MusicUtil.isFavorite(activity, MusicPlayerRemote.getCurrentSong());
+ Drawable favoriteIcon = Util.getTintedDrawable(activity, isFavorite ? R.drawable.ic_favorite_white_24dp : R.drawable.ic_favorite_outline_white_24dp, ViewUtil.getToolbarIconColor(activity, ColorUtil.useDarkTextColorOnBackground(lastColor)));
+ toolbar.getMenu().findItem(R.id.action_toggle_favorite)
+ .setIcon(favoriteIcon)
+ .setTitle(isFavorite ? getString(R.string.action_remove_from_favorites) : getString(R.string.action_add_to_favorites));
+ }
+
+ @Override
+ @ColorInt
+ public int getPaletteColor() {
+ return lastColor;
+ }
+
+ private void animateColorChange(final int newColor) {
+ getView().setBackgroundColor(newColor);
+ lastColor = newColor;
+ }
+
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ final Song song = MusicPlayerRemote.getCurrentSong();
+ switch (item.getItemId()) {
+ case R.id.action_sleep_timer:
+ new SleepTimerDialog().show(getFragmentManager(), "SET_SLEEP_TIMER");
+ return true;
+ case R.id.action_toggle_favorite:
+ MusicUtil.toggleFavorite(activity, song);
+ if (MusicUtil.isFavorite(activity, song)) {
+ playerAlbumCoverFragment.showHeart();
+ }
+ updatePlayerMenu();
+ return true;
+ case R.id.action_share:
+ SongShareDialog.create(song).show(getFragmentManager(), "SHARE_SONG");
+ return true;
+ case R.id.action_equalizer:
+ NavigationUtil.openEqualizer(activity);
+ return true;
+ case R.id.action_shuffle_all:
+ MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(activity), true);
+ return true;
+ case R.id.action_add_to_playlist:
+ AddToPlaylistDialog.create(song).show(getFragmentManager(), "ADD_PLAYLIST");
+ return true;
+ case R.id.action_playing_queue:
+ PlayingQueueDialog.create().show(getFragmentManager(), "PLAY_QUEUE");
+ return true;
+ case R.id.action_tag_editor:
+ Intent intent = new Intent(activity, SongTagEditorActivity.class);
+ intent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id);
+ startActivity(intent);
+ return true;
+ case R.id.action_details:
+ SongDetailDialog.create(song).show(getFragmentManager(), "SONG_DETAIL");
+ return true;
+ case R.id.action_go_to_album:
+ NavigationUtil.goToAlbum(activity, song.albumId);
+ return true;
+ case R.id.action_go_to_artist:
+ NavigationUtil.goToArtist(activity, song.artistId);
+ return true;
+ }
+ return false;
+ }
+
+ public void showControls() {
+ playbackControlsFragment.showControls();
+ }
+
+ public void resetShowControlsAnimation() {
+ playbackControlsFragment.resetShowControlsAnimation();
+ }
+
+ @Override
+ public void onColorChanged(int color) {
+ animateColorChange(color);
+ playbackControlsFragment.setColor(color);
+ callbacks.onPaletteColorChanged();
+ }
+
+ public interface Callbacks {
+ void onPaletteColorChanged();
+ }
+}
diff --git a/app/src/main/java/com/kabouzeid/gramophone/views/SquareLayout.java b/app/src/main/java/com/kabouzeid/gramophone/views/SquareLayout.java
new file mode 100644
index 00000000..7414545a
--- /dev/null
+++ b/app/src/main/java/com/kabouzeid/gramophone/views/SquareLayout.java
@@ -0,0 +1,43 @@
+package com.kabouzeid.gramophone.views;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+/**
+ * @author Karim Abou Zeid (kabouzeid)
+ */
+public class SquareLayout extends FrameLayout {
+
+ private boolean forceSquare = true;
+
+ public SquareLayout(Context context) {
+ super(context);
+ }
+
+ public SquareLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SquareLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public SquareLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ //noinspection SuspiciousNameCombination
+ super.onMeasure(widthMeasureSpec, forceSquare ? widthMeasureSpec : heightMeasureSpec);
+ }
+
+ public void forceSquare(boolean forceSquare) {
+ this.forceSquare = forceSquare;
+ requestLayout();
+ }
+}
diff --git a/app/src/main/res/drawable-hdpi/ic_repeat_off_white_36dp.png b/app/src/main/res/drawable-hdpi/ic_repeat_off_white_36dp.png
new file mode 100644
index 00000000..1b83e734
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_repeat_off_white_36dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_trending_flat_white_36dp.png b/app/src/main/res/drawable-hdpi/ic_trending_flat_white_36dp.png
new file mode 100644
index 00000000..d9a840d5
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_trending_flat_white_36dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_repeat_off_white_36dp.png b/app/src/main/res/drawable-mdpi/ic_repeat_off_white_36dp.png
new file mode 100644
index 00000000..4149dc54
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_repeat_off_white_36dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_trending_flat_white_36dp.png b/app/src/main/res/drawable-mdpi/ic_trending_flat_white_36dp.png
new file mode 100644
index 00000000..ea5d1e18
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_trending_flat_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_repeat_off_white_36dp.png b/app/src/main/res/drawable-xhdpi/ic_repeat_off_white_36dp.png
new file mode 100644
index 00000000..009f7a6e
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_repeat_off_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_trending_flat_white_36dp.png b/app/src/main/res/drawable-xhdpi/ic_trending_flat_white_36dp.png
new file mode 100644
index 00000000..28ede2eb
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_trending_flat_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_repeat_off_white_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_repeat_off_white_36dp.png
new file mode 100644
index 00000000..42ab374b
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_repeat_off_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_trending_flat_white_36dp.png b/app/src/main/res/drawable-xxhdpi/ic_trending_flat_white_36dp.png
new file mode 100644
index 00000000..cdf966ee
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_trending_flat_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_repeat_off_white_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_repeat_off_white_36dp.png
new file mode 100644
index 00000000..59b70a15
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_repeat_off_white_36dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_trending_flat_white_36dp.png b/app/src/main/res/drawable-xxxhdpi/ic_trending_flat_white_36dp.png
new file mode 100644
index 00000000..0da7c185
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_trending_flat_white_36dp.png differ
diff --git a/app/src/main/res/layout-land/fragment_player.xml b/app/src/main/res/layout-land/fragment_player.xml
deleted file mode 100644
index d26d1bbe..00000000
--- a/app/src/main/res/layout-land/fragment_player.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_playback_controls.xml b/app/src/main/res/layout/fragment_playback_controls.xml
index fc8bf331..37203991 100644
--- a/app/src/main/res/layout/fragment_playback_controls.xml
+++ b/app/src/main/res/layout/fragment_playback_controls.xml
@@ -8,7 +8,7 @@
android:orientation="vertical">
diff --git a/app/src/main/res/layout/fragment_player.xml b/app/src/main/res/layout/fragment_player.xml
index 1eeb223e..27a8467a 100644
--- a/app/src/main/res/layout/fragment_player.xml
+++ b/app/src/main/res/layout/fragment_player.xml
@@ -1,48 +1,80 @@
-
+
+ android:focusable="true"
+ android:clickable="false"
+ android:gravity="bottom"
+ sothree:umanoDragView="@+id/player_panel"
+ sothree:umanoFadeColor="#00000000"
+ sothree:umanoOverlay="true"
+ sothree:umanoPanelHeight="0dp"
+ sothree:umanoScrollableView="@+id/player_recycler_view"
+ sothree:umanoParallaxOffset="32dp"
+ sothree:umanoShadowHeight="0dp">
-
+ android:layout_alignParentTop="true">
+
+
+
+
+ android:layout_below="@id/album_cover_container" />
-
+
+
-
+
-
+
-
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_playing_info.xml b/app/src/main/res/layout/fragment_playing_info.xml
deleted file mode 100644
index cc876390..00000000
--- a/app/src/main/res/layout/fragment_playing_info.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/sliding_music_panel_layout.xml b/app/src/main/res/layout/sliding_music_panel_layout.xml
index e025d048..315af03e 100644
--- a/app/src/main/res/layout/sliding_music_panel_layout.xml
+++ b/app/src/main/res/layout/sliding_music_panel_layout.xml
@@ -5,6 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
+ sothree:umanoScrollableView="@+id/sliding_panel"
sothree:umanoDragView="@+id/sliding_panel"
sothree:umanoPanelHeight="@dimen/mini_player_height"
sothree:umanoShadowHeight="@dimen/card_elevation">
@@ -18,19 +19,17 @@
android:id="@+id/sliding_panel"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="?android:colorBackground"
- android:clickable="true"
- android:focusable="false">
+ android:background="?android:colorBackground">