parent
2ca504d7e9
commit
e28a70a6e6
|
@ -32,6 +32,7 @@ android {
|
|||
dependencies {
|
||||
implementation 'com.esotericsoftware:kryo:4.0.2'
|
||||
implementation 'com.google.android.material:material:1.0.0'
|
||||
implementation 'com.github.hannesa2:AndroidSlidingUpPanel:4.0.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.1.0'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ import androidx.appcompat.widget.Toolbar;
|
|||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelState;
|
||||
|
||||
import net.nullsum.audinaut.R;
|
||||
import net.nullsum.audinaut.domain.MusicDirectory;
|
||||
import net.nullsum.audinaut.domain.PlayerState;
|
||||
|
@ -65,11 +68,19 @@ import java.util.List;
|
|||
public class SubsonicFragmentActivity extends SubsonicActivity implements DownloadService.OnSongChangedListener {
|
||||
private static boolean infoDialogDisplayed;
|
||||
private static boolean sessionInitialized = false;
|
||||
private SlidingUpPanelLayout slideUpPanel;
|
||||
private SlidingUpPanelLayout.PanelSlideListener panelSlideListener;
|
||||
private boolean isPanelClosing = false;
|
||||
private boolean resuming = false;
|
||||
private NowPlayingFragment nowPlayingFragment;
|
||||
private SubsonicFragment secondaryFragment;
|
||||
private Toolbar mainToolbar;
|
||||
private Toolbar nowPlayingToolbar;
|
||||
|
||||
private View bottomBar;
|
||||
private ImageView coverArtView;
|
||||
private TextView trackView;
|
||||
private TextView artistView;
|
||||
private ImageButton startButton;
|
||||
private DownloadFile currentPlaying;
|
||||
private ImageButton previousButton;
|
||||
|
@ -156,21 +167,71 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
}
|
||||
}
|
||||
|
||||
slideUpPanel = findViewById(R.id.slide_up_panel);
|
||||
panelSlideListener = new SlidingUpPanelLayout.PanelSlideListener() {
|
||||
@Override
|
||||
public void onPanelSlide(View panel, float slideOffset) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanelStateChanged(View panel, PanelState previousState, PanelState newState) {
|
||||
if (newState == PanelState.COLLAPSED) {
|
||||
isPanelClosing = false;
|
||||
if (bottomBar.getVisibility() == View.GONE) {
|
||||
bottomBar.setVisibility(View.VISIBLE);
|
||||
nowPlayingToolbar.setVisibility(View.GONE);
|
||||
nowPlayingFragment.setPrimaryFragment(false);
|
||||
setSupportActionBar(mainToolbar);
|
||||
recreateSpinner();
|
||||
}
|
||||
} else if (newState == PanelState.EXPANDED) {
|
||||
isPanelClosing = false;
|
||||
currentFragment.stopActionMode();
|
||||
|
||||
// Disable custom view before switching
|
||||
getSupportActionBar().setDisplayShowCustomEnabled(false);
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(true);
|
||||
|
||||
bottomBar.setVisibility(View.GONE);
|
||||
nowPlayingToolbar.setVisibility(View.VISIBLE);
|
||||
setSupportActionBar(nowPlayingToolbar);
|
||||
|
||||
if (secondaryFragment == null) {
|
||||
nowPlayingFragment.setPrimaryFragment(true);
|
||||
} else {
|
||||
secondaryFragment.setPrimaryFragment(true);
|
||||
}
|
||||
|
||||
drawerToggle.setDrawerIndicatorEnabled(false);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
slideUpPanel.addPanelSlideListener(panelSlideListener);
|
||||
|
||||
if (getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD)) {
|
||||
// Post this later so it actually runs
|
||||
handler.postDelayed(this::openNowPlaying, 200);
|
||||
|
||||
getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD);
|
||||
}
|
||||
|
||||
bottomBar = findViewById(R.id.bottom_bar);
|
||||
mainToolbar = findViewById(R.id.main_toolbar);
|
||||
nowPlayingToolbar = findViewById(R.id.now_playing_toolbar);
|
||||
coverArtView = bottomBar.findViewById(R.id.album_art);
|
||||
trackView = bottomBar.findViewById(R.id.track_name);
|
||||
artistView = bottomBar.findViewById(R.id.artist_name);
|
||||
|
||||
setSupportActionBar(mainToolbar);
|
||||
|
||||
if (findViewById(R.id.fragment_container) != null && savedInstanceState == null) {
|
||||
nowPlayingFragment = new NowPlayingFragment();
|
||||
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
|
||||
trans.add(R.id.now_playing_fragment_container, nowPlayingFragment, nowPlayingFragment.getTag() + "");
|
||||
trans.commit();
|
||||
}
|
||||
|
||||
if (currentFragment instanceof NowPlayingFragment) {
|
||||
rewindButton = findViewById(R.id.download_rewind);
|
||||
rewindButton.setOnClickListener(v -> new SilentBackgroundTask<Void>(SubsonicFragmentActivity.this) {
|
||||
@Override
|
||||
|
@ -230,7 +291,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
return null;
|
||||
}
|
||||
}.execute());
|
||||
}
|
||||
|
||||
if (!infoDialogDisplayed) {
|
||||
infoDialogDisplayed = true;
|
||||
|
@ -253,6 +313,10 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
super.onNewIntent(intent);
|
||||
|
||||
if (currentFragment != null && intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY) != null) {
|
||||
if (isNowPlayingOpen()) {
|
||||
closeNowPlaying();
|
||||
}
|
||||
|
||||
if (currentFragment instanceof SearchFragment) {
|
||||
String query = intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY);
|
||||
boolean autoplay = intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false);
|
||||
|
@ -267,6 +331,10 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
SearchFragment fragment = new SearchFragment();
|
||||
replaceFragment(fragment, fragment.getSupportTag());
|
||||
}
|
||||
} else if (intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD, false)) {
|
||||
if (!isNowPlayingOpen()) {
|
||||
openNowPlaying();
|
||||
}
|
||||
} else {
|
||||
setIntent(intent);
|
||||
}
|
||||
|
@ -320,6 +388,7 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
if (secondaryFragment != null) {
|
||||
savedInstanceState.putString(Constants.MAIN_NOW_PLAYING_SECONDARY, secondaryFragment.getTag());
|
||||
}
|
||||
savedInstanceState.putInt(Constants.MAIN_SLIDE_PANEL_STATE, slideUpPanel.getPanelState().hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -345,12 +414,18 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
if (drawerToggle != null && backStack.size() > 0) {
|
||||
drawerToggle.setDrawerIndicatorEnabled(false);
|
||||
}
|
||||
|
||||
if (savedInstanceState.getInt(Constants.MAIN_SLIDE_PANEL_STATE, -1) == SlidingUpPanelLayout.PanelState.EXPANDED.hashCode()) {
|
||||
panelSlideListener.onPanelStateChanged(null, null, PanelState.EXPANDED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (isNowPlayingOpen()) {
|
||||
if (secondaryFragment != null) {
|
||||
if (secondaryFragment == null) {
|
||||
closeNowPlaying();
|
||||
} else {
|
||||
removeCurrent();
|
||||
}
|
||||
} else {
|
||||
|
@ -373,8 +448,21 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
|
||||
@Override
|
||||
public void replaceFragment(SubsonicFragment fragment, int tag, boolean replaceCurrent) {
|
||||
if (slideUpPanel != null && isNowPlayingOpen() && !isPanelClosing) {
|
||||
secondaryFragment = fragment;
|
||||
nowPlayingFragment.setPrimaryFragment(false);
|
||||
secondaryFragment.setPrimaryFragment(true);
|
||||
supportInvalidateOptionsMenu();
|
||||
|
||||
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
|
||||
trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
|
||||
trans.hide(nowPlayingFragment);
|
||||
trans.add(R.id.now_playing_fragment_container, secondaryFragment, tag + "");
|
||||
trans.commit();
|
||||
} else {
|
||||
super.replaceFragment(fragment, tag, replaceCurrent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCurrent() {
|
||||
|
@ -402,6 +490,15 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawerItemSelected(String fragmentType) {
|
||||
super.drawerItemSelected(fragmentType);
|
||||
|
||||
if (isNowPlayingOpen() && !resuming) {
|
||||
closeNowPlaying();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startFragmentActivity(String fragmentType) {
|
||||
// Create a transaction that does all of this
|
||||
|
@ -435,8 +532,19 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openNowPlaying() {
|
||||
slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeNowPlaying() {
|
||||
slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
|
||||
isPanelClosing = true;
|
||||
}
|
||||
|
||||
private boolean isNowPlayingOpen() {
|
||||
return false;
|
||||
return slideUpPanel.getPanelState() == PanelState.EXPANDED;
|
||||
}
|
||||
|
||||
private SubsonicFragment getNewFragment(String fragmentType) {
|
||||
|
@ -534,7 +642,35 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
MusicDirectory.Entry song = null;
|
||||
if (currentPlaying != null) {
|
||||
song = currentPlaying.getSong();
|
||||
trackView.setText(song.getTitle());
|
||||
|
||||
if (song.getArtist() != null) {
|
||||
artistView.setVisibility(View.VISIBLE);
|
||||
artistView.setText(song.getArtist());
|
||||
} else {
|
||||
artistView.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
trackView.setText(R.string.main_title);
|
||||
artistView.setText(R.string.main_artist);
|
||||
}
|
||||
|
||||
if (coverArtView != null) {
|
||||
int height = coverArtView.getHeight();
|
||||
if (height <= 0) {
|
||||
int[] attrs = new int[]{R.attr.actionBarSize};
|
||||
TypedArray typedArray = this.obtainStyledAttributes(attrs);
|
||||
height = typedArray.getDimensionPixelSize(0, 0);
|
||||
typedArray.recycle();
|
||||
}
|
||||
getImageLoader().loadImage(coverArtView, song, false, height, false);
|
||||
}
|
||||
|
||||
previousButton.setVisibility(View.VISIBLE);
|
||||
nextButton.setVisibility(View.VISIBLE);
|
||||
|
||||
rewindButton.setVisibility(View.GONE);
|
||||
fastforwardButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -553,10 +689,26 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo
|
|||
public void onStateUpdate(PlayerState playerState) {
|
||||
int[] attrs = new int[]{(playerState == PlayerState.STARTED) ? R.attr.actionbar_pause : R.attr.actionbar_start};
|
||||
TypedArray typedArray = this.obtainStyledAttributes(attrs);
|
||||
startButton.setImageResource(typedArray.getResourceId(0, 0));
|
||||
typedArray.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMetadataUpdate(MusicDirectory.Entry song, int fieldChange) {
|
||||
if (song != null && coverArtView != null && fieldChange == DownloadService.METADATA_UPDATED_COVER_ART) {
|
||||
int height = coverArtView.getHeight();
|
||||
if (height <= 0) {
|
||||
int[] attrs = new int[]{R.attr.actionBarSize};
|
||||
TypedArray typedArray = this.obtainStyledAttributes(attrs);
|
||||
height = typedArray.getDimensionPixelSize(0, 0);
|
||||
typedArray.recycle();
|
||||
}
|
||||
getImageLoader().loadImage(coverArtView, song, false, height, false);
|
||||
|
||||
// We need to update it immediately since it won't update if updater is not running for it
|
||||
if (nowPlayingFragment != null && slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
|
||||
nowPlayingFragment.onMetadataUpdate(song, fieldChange);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.sothree.slidinguppanel.SlidingUpPanelLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:sothree="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/slide_up_panel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="bottom">
|
||||
android:gravity="bottom"
|
||||
sothree:umanoDragView="@+id/slide_up_swipe_target"
|
||||
sothree:umanoPanelHeight="?attr/actionBarSize"
|
||||
sothree:umanoShadowHeight="4dp">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -22,4 +24,123 @@
|
|||
|
||||
<include layout="@layout/abstract_fragment_container" />
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/slide_up_swipe_target"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/actionbarBackgroundColor">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/now_playing_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:elevation="4dp"
|
||||
android:theme="?attr/actionbarThemeStyle"
|
||||
android:visibility="gone"
|
||||
app:popupTheme="?attr/actionbarPopupStyle" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bottom_bar"
|
||||
style="@style/BasicButton"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:elevation="4dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<net.nullsum.audinaut.view.RecyclingImageView
|
||||
android:id="@+id/album_art"
|
||||
android:layout_width="?attr/actionBarSize"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:layout_gravity="left|center"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="8dip">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_name"
|
||||
style="?attr/actionbarTitleStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:scrollHorizontally="true"
|
||||
android:singleLine="true"
|
||||
android:text="@string/main.title">
|
||||
|
||||
<requestFocus
|
||||
android:duplicateParentState="true"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true" />
|
||||
</TextView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/artist_name"
|
||||
style="?attr/actionbarSubtitleStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:text="@string/main.artist" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/download_rewind"
|
||||
style="@style/PlaybackControl.BottomBar"
|
||||
android:padding="2dp"
|
||||
app:srcCompat="?attr/actionbar_rewind"
|
||||
android:visibility="gone" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/download_previous"
|
||||
style="@style/PlaybackControl.BottomBar"
|
||||
android:padding="2dp"
|
||||
app:srcCompat="?attr/actionbar_backward" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/download_start"
|
||||
style="@style/PlaybackControl.BottomBar"
|
||||
app:srcCompat="?attr/actionbar_start" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/download_next"
|
||||
style="@style/PlaybackControl.BottomBar"
|
||||
android:padding="2dp"
|
||||
app:srcCompat="?attr/actionbar_forward" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/download_fastforward"
|
||||
style="@style/PlaybackControl.BottomBar"
|
||||
android:padding="2dp"
|
||||
app:srcCompat="?attr/actionbar_fastforward"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/now_playing_fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:clickable="true" />
|
||||
</LinearLayout>
|
||||
</com.sothree.slidinguppanel.SlidingUpPanelLayout>
|
||||
|
|
Loading…
Reference in New Issue