aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/app.iml21
-rw-r--r--app/build.gradle2
-rw-r--r--app/src/main/java/github/daneren2005/dsub/activity/DownloadActivity.java62
-rw-r--r--app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java142
-rw-r--r--app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java182
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java21
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java148
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java3
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java5
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java254
-rw-r--r--app/src/main/java/github/daneren2005/dsub/provider/DSubWidgetProvider.java5
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java9
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/Util.java27
-rw-r--r--app/src/main/res/layout-large-land/abstract_fragment_container.xml4
-rw-r--r--app/src/main/res/layout/abstract_fragment_activity.xml199
-rw-r--r--app/src/main/res/layout/abstract_fragment_container.xml4
-rw-r--r--app/src/main/res/layout/drawer_header.xml42
-rw-r--r--app/src/main/res/layout/drawer_list_item.xml5
-rw-r--r--app/src/main/res/values-large/dimens.xml2
-rw-r--r--app/src/main/res/values-v16/themes.xml2
-rw-r--r--app/src/main/res/values/dimens.xml2
-rw-r--r--app/src/main/res/values/strings.xml2
-rw-r--r--app/src/main/res/values/styles.xml6
-rw-r--r--app/src/main/res/values/themes.xml17
24 files changed, 709 insertions, 457 deletions
diff --git a/app/app.iml b/app/app.iml
index 28b7ee49..64c8e5af 100644
--- a/app/app.iml
+++ b/app/app.iml
@@ -71,9 +71,12 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.1.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/mediarouter-v7/22.1.1/jars" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/recyclerview-v7/22.1.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.1.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-base/7.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services-cast/7.0.0/jars" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.sothree.slidinguppanel/library/3.0.0/jars" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/de.hdodenhof/circleimageview/1.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
@@ -94,27 +97,31 @@
<orderEntry type="library" exported="" name="mediarouter-v7-22.1.1" level="project" />
<orderEntry type="library" exported="" name="seamless-util-1.1.0" level="project" />
<orderEntry type="library" exported="" name="cling-core-2.0.1" level="project" />
+ <orderEntry type="library" exported="" name="recyclerview-v7-22.1.1" level="project" />
<orderEntry type="library" exported="" name="jetty-continuation-8.1.16.v20140903" level="project" />
- <orderEntry type="library" exported="" name="javax.servlet-3.0.0.v201112011016" level="project" />
- <orderEntry type="library" exported="" name="jetty-server-8.1.16.v20140903" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.1.1" level="project" />
- <orderEntry type="library" exported="" name="support-v4-22.1.1" level="project" />
<orderEntry type="library" exported="" name="play-services-cast-7.0.0" level="project" />
- <orderEntry type="library" exported="" name="cling-support-2.0.1" level="project" />
<orderEntry type="library" exported="" name="seamless-http-1.1.0" level="project" />
<orderEntry type="library" exported="" name="jetty-util-8.1.16.v20140903" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-22.1.1" level="project" />
<orderEntry type="library" exported="" name="seamless-swing-1.1.0" level="project" />
<orderEntry type="library" exported="" name="seamless-xml-1.1.0" level="project" />
+ <orderEntry type="library" exported="" name="kryo-2.21-all" level="project" />
+ <orderEntry type="library" exported="" name="play-services-base-7.0.0" level="project" />
+ <orderEntry type="library" exported="" name="jetty-http-8.1.16.v20140903" level="project" />
+ <orderEntry type="library" exported="" name="library-2.4.0" level="project" />
+ <orderEntry type="library" exported="" name="javax.servlet-3.0.0.v201112011016" level="project" />
+ <orderEntry type="library" exported="" name="jetty-server-8.1.16.v20140903" level="project" />
+ <orderEntry type="library" exported="" name="support-v4-22.1.1" level="project" />
+ <orderEntry type="library" exported="" name="cling-support-2.0.1" level="project" />
<orderEntry type="library" exported="" name="jetty-io-8.1.16.v20140903" level="project" />
<orderEntry type="library" exported="" name="CWAC-EndlessAdapter" level="project" />
+ <orderEntry type="library" exported="" name="circleimageview-1.2.1" level="project" />
<orderEntry type="library" exported="" name="jetty-security-8.1.16.v20140903" level="project" />
- <orderEntry type="library" exported="" name="kryo-2.21-all" level="project" />
- <orderEntry type="library" exported="" name="play-services-base-7.0.0" level="project" />
<orderEntry type="library" exported="" name="jetty-servlet-8.1.16.v20140903" level="project" />
<orderEntry type="library" exported="" name="CWAC-AdapterWrapper" level="project" />
+ <orderEntry type="library" exported="" name="library-3.0.0" level="project" />
<orderEntry type="library" exported="" name="jetty-client-8.1.16.v20140903" level="project" />
- <orderEntry type="library" exported="" name="jetty-http-8.1.16.v20140903" level="project" />
<orderEntry type="module" module-name="DragSort ListView" exported="" />
<orderEntry type="module" module-name="Server Proxy" exported="" />
</component>
diff --git a/app/build.gradle b/app/build.gradle
index 97e72a11..56da71aa 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -33,6 +33,8 @@ dependencies {
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.android.support:mediarouter-v7:22.1.1'
compile 'com.google.android.gms:play-services-cast:7.0.0'
+ compile 'com.sothree.slidinguppanel:library:3.0.0'
+ compile 'de.hdodenhof:circleimageview:1.2.1'
compile group: 'org.fourthline.cling', name: 'cling-core', version:'2.0.1'
compile group: 'org.fourthline.cling', name: 'cling-support', version:'2.0.1'
compile group: 'org.eclipse.jetty', name: 'jetty-server', version:'8.1.16.v20140903'
diff --git a/app/src/main/java/github/daneren2005/dsub/activity/DownloadActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/DownloadActivity.java
deleted file mode 100644
index e13a8b8c..00000000
--- a/app/src/main/java/github/daneren2005/dsub/activity/DownloadActivity.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package github.daneren2005.dsub.activity;
-
-import github.daneren2005.dsub.R;
-import android.os.Bundle;
-import android.view.MotionEvent;
-import github.daneren2005.dsub.fragments.NowPlayingFragment;
-
-import android.widget.EditText;
-
-import github.daneren2005.dsub.util.Constants;
-
-public class DownloadActivity extends SubsonicActivity {
- private static final String TAG = DownloadActivity.class.getSimpleName();
- private EditText playlistNameView;
-
- /**
- * Called when the activity is first created.
- */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.download_activity);
-
- if (findViewById(R.id.fragment_container) != null && savedInstanceState == null) {
- currentFragment = new NowPlayingFragment();
- if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW)) {
- Bundle args = new Bundle();
- args.putBoolean(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW, true);
- currentFragment.setArguments(args);
- }
- currentFragment.setPrimaryFragment(true);
- getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + "").commit();
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent me) {
- if(currentFragment != null && currentFragment.getGestureDetector() != null) {
- return currentFragment.getGestureDetector().onTouchEvent(me);
- } else {
- return false;
- }
- }
-}
diff --git a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
index 4651eb0b..cb09728c 100644
--- a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
+++ b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicActivity.java
@@ -51,6 +51,7 @@ import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
+import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
@@ -68,6 +69,7 @@ import github.daneren2005.dsub.service.DownloadService;
import github.daneren2005.dsub.service.HeadphoneListenerService;
import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.ImageLoader;
+import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.Util;
import github.daneren2005.dsub.adapter.DrawerAdapter;
import github.daneren2005.dsub.view.UpdateView;
@@ -97,6 +99,10 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
ActionBarDrawerToggle drawerToggle;
DrawerAdapter drawerAdapter;
ListView drawerList;
+ View drawerHeader;
+ ImageView drawerUserAvatar;
+ TextView drawerServerName;
+ TextView drawerUserName;
TextView lastSelectedView = null;
int lastSelectedPosition = 0;
boolean drawerOpen = false;
@@ -118,17 +124,6 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
super.onCreate(bundle);
startService(new Intent(this, DownloadService.class));
setVolumeControlStream(AudioManager.STREAM_MUSIC);
-
- View actionbar = getLayoutInflater().inflate(R.layout.actionbar_spinner, null);
- actionBarSpinner = (Spinner)actionbar.findViewById(R.id.spinner);
- spinnerAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item);
- spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- actionBarSpinner.setOnItemSelectedListener(this);
- actionBarSpinner.setAdapter(spinnerAdapter);
-
- getSupportActionBar().setCustomView(actionbar);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setHomeButtonEnabled(true);
if(getIntent().hasExtra(Constants.FRAGMENT_POSITION)) {
lastSelectedPosition = getIntent().getIntExtra(Constants.FRAGMENT_POSITION, 0);
@@ -138,6 +133,13 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
+
+ if(spinnerAdapter == null) {
+ createCustomActionBarView();
+ }
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setHomeButtonEnabled(true);
+
// Sync the toggle state after onRestoreInstanceState has occurred.
if(drawerToggle != null) {
drawerToggle.syncState();
@@ -150,6 +152,17 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
}
+ protected void createCustomActionBarView() {
+ View customActionbar = getLayoutInflater().inflate(R.layout.actionbar_spinner, null);
+ actionBarSpinner = (Spinner)customActionbar.findViewById(R.id.spinner);
+ spinnerAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item);
+ spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ actionBarSpinner.setOnItemSelectedListener(this);
+ actionBarSpinner.setAdapter(spinnerAdapter);
+
+ getSupportActionBar().setCustomView(customActionbar);
+ }
+
@Override
protected void onResume() {
super.onResume();
@@ -160,7 +173,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
restart();
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}
-
+
populateDrawer();
UpdateView.addActiveActivity();
}
@@ -210,12 +223,12 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
LayoutInflater layoutInflater = getLayoutInflater();
layoutInflater.inflate(viewId, rootView);
}
-
+
drawerList = (ListView) findViewById(R.id.left_drawer);
drawerList.setOnItemClickListener(new ListView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, final View view, final int position, long id) {
- final int actualPosition = drawerAdapter.getActualPosition(position);
+ final int actualPosition = drawerAdapter.getActualPosition(position - 1);
if("Settings".equals(drawerItemsDescriptions[actualPosition])) {
startActivity(new Intent(SubsonicActivity.this, SettingsActivity.class));
drawer.closeDrawers();
@@ -232,7 +245,13 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
});
+ drawerHeader = getLayoutInflater().inflate(R.layout.drawer_header, drawerList, false);
+ drawerServerName = (TextView) drawerHeader.findViewById(R.id.header_server_name);
+ drawerUserName = (TextView) drawerHeader.findViewById(R.id.header_user_name);
+ drawerUserAvatar = (ImageView) drawerHeader.findViewById(R.id.header_user_avatar);
+ updateDrawerHeader();
+ drawerList.addHeaderView(drawerHeader, null, false);
if(!isTv()) {
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
@@ -258,7 +277,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
if (lastSelectedView == null && drawerList.getCount() > lastSelectedPosition) {
- lastSelectedView = (TextView) drawerList.getChildAt(lastSelectedPosition).findViewById(R.id.drawer_name);
+ lastSelectedView = (TextView) drawerList.getChildAt(lastSelectedPosition + 1).findViewById(R.id.drawer_name);
if (lastSelectedView != null) {
lastSelectedView.setTextAppearance(SubsonicActivity.this, R.style.DSub_TextViewStyle_Bold);
}
@@ -299,7 +318,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
primaryContainer = findViewById(R.id.fragment_container);
}
}
-
+
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
@@ -370,10 +389,11 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
-
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
+ SubsonicFragment currentFragment = getCurrentFragment();
if(drawerOpen) {
menuInflater.inflate(R.menu.drawer_menu, menu);
} else if(currentFragment != null) {
@@ -399,7 +419,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
return true;
}
- return currentFragment.onOptionsItemSelected(item);
+ return getCurrentFragment().onOptionsItemSelected(item);
}
@Override
@@ -415,7 +435,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
return super.onKeyDown(keyCode, event);
}
-
+
@Override
public void setTitle(CharSequence title) {
if(title != null && !title.equals(getSupportActionBar().getTitle())) {
@@ -426,7 +446,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
public void setSubtitle(CharSequence title) {
getSupportActionBar().setSubtitle(title);
}
-
+
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
int top = spinnerAdapter.getCount() - 1;
@@ -439,9 +459,9 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
@Override
public void onNothingSelected(AdapterView<?> parent) {
-
+
}
-
+
private void populateDrawer() {
SharedPreferences prefs = Util.getPreferences(this);
boolean podcastsEnabled = prefs.getBoolean(Constants.PREFERENCES_KEY_PODCASTS_ENABLED, true);
@@ -449,7 +469,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
boolean sharedEnabled = prefs.getBoolean(Constants.PREFERENCES_KEY_SHARED_ENABLED, true) && !Util.isOffline(this);
boolean chatEnabled = prefs.getBoolean(Constants.PREFERENCES_KEY_CHAT_ENABLED, true) && !Util.isOffline(this);
boolean adminEnabled = prefs.getBoolean(Constants.PREFERENCES_KEY_ADMIN_ENABLED, true) && !Util.isOffline(this);
-
+
if(drawerItems == null || !enabledItems[0] == podcastsEnabled || !enabledItems[1] == bookmarksEnabled || !enabledItems[2] == sharedEnabled || !enabledItems[3] == chatEnabled || !enabledItems[4] == adminEnabled) {
drawerItems = getResources().getStringArray(R.array.drawerItems);
drawerItemsDescriptions = getResources().getStringArray(R.array.drawerItemsDescriptions);
@@ -488,7 +508,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
if(!getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW)) {
drawerItemsVisibleList.set(8, false);
}
-
+
drawerList.setAdapter(drawerAdapter = new DrawerAdapter(this, drawerItemsList, drawerItemsIconsList, drawerItemsVisibleList));
enabledItems[0] = podcastsEnabled;
enabledItems[1] = bookmarksEnabled;
@@ -506,26 +526,26 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
}
- if(drawerList.getChildAt(lastSelectedPosition) == null) {
+ if(drawerList.getChildAt(lastSelectedPosition + 1) == null) {
lastSelectedView = null;
drawerAdapter.setSelectedPosition(lastSelectedPosition);
} else {
- lastSelectedView = (TextView) drawerList.getChildAt(lastSelectedPosition).findViewById(R.id.drawer_name);
+ lastSelectedView = (TextView) drawerList.getChildAt(lastSelectedPosition + 1).findViewById(R.id.drawer_name);
if(lastSelectedView != null) {
lastSelectedView.setTextAppearance(SubsonicActivity.this, R.style.DSub_TextViewStyle_Bold);
}
}
}
}
-
- private void drawerItemSelected(int position, View view) {
+
+ protected void drawerItemSelected(int position, View view) {
startFragmentActivity(drawerItemsDescriptions[position]);
-
+
if(lastSelectedView != view) {
if(lastSelectedView != null) {
lastSelectedView.setTextAppearance(this, R.style.DSub_TextViewStyle);
}
-
+
lastSelectedView = (TextView) view.findViewById(R.id.drawer_name);
lastSelectedView.setTextAppearance(this, R.style.DSub_TextViewStyle_Bold);
lastSelectedPosition = position;
@@ -575,6 +595,10 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
}
+ protected SubsonicFragment getCurrentFragment() {
+ return this.currentFragment;
+ }
+
public void replaceFragment(SubsonicFragment fragment, int tag) {
replaceFragment(fragment, tag, false);
}
@@ -628,11 +652,11 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
backStack.remove(backStack.size() - 1);
}
}
-
+
// Add fragment to the right container
trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
trans.add(R.id.fragment_second_container, fragment, tag + "");
-
+
// Commit it all
trans.commit();
}
@@ -656,7 +680,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
trans.commit();
} else {
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
-
+
// Remove old right fragment
trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
trans.remove(oldFrag);
@@ -682,7 +706,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
secondaryContainer.startAnimation(AnimationUtils.loadAnimation(this, R.anim.exit_to_right));
secondaryContainer.setVisibility(View.GONE);
}
-
+
trans.commit();
}
recreateSpinner();
@@ -697,14 +721,17 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
currentFragment.invalidate();
populateDrawer();
}
-
+
supportInvalidateOptionsMenu();
}
-
+
protected void recreateSpinner() {
if(currentFragment == null || currentFragment.getTitle() == null) {
return;
}
+ if(spinnerAdapter == null) {
+ createCustomActionBarView();
+ }
if(backStack.size() > 0) {
spinnerAdapter.clear();
@@ -727,6 +754,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
getSupportActionBar().setDisplayShowCustomEnabled(true);
}
} else if(!isTv()) {
+ getSupportActionBar().setTitle(currentFragment.getTitle());
getSupportActionBar().setDisplayShowCustomEnabled(false);
}
}
@@ -745,7 +773,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
theme = theme.substring(0, theme.indexOf("_fullscreen"));
Util.setTheme(this, theme);
}
-
+
Util.applyTheme(this, theme);
}
private void applyFullscreen() {
@@ -754,8 +782,8 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
// Hide additional elements on higher Android versions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
- View.SYSTEM_UI_FLAG_FULLSCREEN |
- View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ View.SYSTEM_UI_FLAG_FULLSCREEN |
+ View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
getWindow().getDecorView().setSystemUiVisibility(flags);
} else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
@@ -786,7 +814,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
if(finished) {
return null;
}
-
+
// If service is not available, request it to start and wait for it.
for (int i = 0; i < 5; i++) {
DownloadService downloadService = DownloadService.getInstance();
@@ -799,7 +827,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
return DownloadService.getInstance();
}
-
+
public static String getThemeName() {
return theme;
}
@@ -811,6 +839,38 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
return touchscreen;
}
+ public void openNowPlaying() {
+
+ }
+ public void closeNowPlaying() {
+
+ }
+
+ public void setActiveServer(int instance) {
+ if (Util.getActiveServer(this) != instance) {
+ final DownloadService service = getDownloadService();
+ if (service != null) {
+ new SilentBackgroundTask<Void>(this) {
+ @Override
+ protected Void doInBackground() throws Throwable {
+ service.clearIncomplete();
+ return null;
+ }
+ }.execute();
+
+ }
+ Util.setActiveServer(this, instance);
+ invalidate();
+ UserUtil.refreshCurrentUser(this, false, true);
+ updateDrawerHeader();
+ }
+ }
+ private void updateDrawerHeader() {
+ drawerServerName.setText(Util.getServerName(this));
+ drawerUserName.setText(UserUtil.getCurrentUsername(this));
+ getImageLoader().loadAvatar(this, drawerUserAvatar, UserUtil.getCurrentUsername(this));
+ }
+
private void setUncaughtExceptionHandler() {
Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler();
if (!(handler instanceof SubsonicActivity.SubsonicUncaughtExceptionHandler)) {
diff --git a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
index 6614e09d..83d5bce8 100644
--- a/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
+++ b/app/src/main/java/github/daneren2005/dsub/activity/SubsonicFragmentActivity.java
@@ -31,14 +31,17 @@ import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentTransaction;
+import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
+import android.widget.ImageView;
import android.widget.TextView;
+import com.sothree.slidinguppanel.SlidingUpPanelLayout;
+
import java.io.File;
-import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -53,6 +56,7 @@ import github.daneren2005.dsub.fragments.AdminFragment;
import github.daneren2005.dsub.fragments.ChatFragment;
import github.daneren2005.dsub.fragments.DownloadFragment;
import github.daneren2005.dsub.fragments.MainFragment;
+import github.daneren2005.dsub.fragments.NowPlayingFragment;
import github.daneren2005.dsub.fragments.SearchFragment;
import github.daneren2005.dsub.fragments.SelectArtistFragment;
import github.daneren2005.dsub.fragments.SelectBookmarkFragment;
@@ -66,7 +70,6 @@ import github.daneren2005.dsub.service.DownloadService;
import github.daneren2005.dsub.service.MusicService;
import github.daneren2005.dsub.service.MusicServiceFactory;
import github.daneren2005.dsub.updates.Updater;
-import github.daneren2005.dsub.util.BackgroundTask;
import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.FileUtil;
import github.daneren2005.dsub.util.SilentBackgroundTask;
@@ -83,9 +86,15 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
private static boolean sessionInitialized = false;
private static long ALLOWED_SKEW = 30000L;
+ private Handler handler = new Handler();
+ private SlidingUpPanelLayout slideUpPanel;
+ private NowPlayingFragment nowPlayingFragment;
+ private Toolbar mainToolbar;
+ private Toolbar nowPlayingToolbar;
+
private ScheduledExecutorService executorService;
private View bottomBar;
- private View coverArtView;
+ private ImageView coverArtView;
private TextView trackView;
private TextView artistView;
private ImageButton startButton;
@@ -105,14 +114,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
if(drawerAdapter != null) {
drawerAdapter.setDownloadVisible(true);
}
- } else if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD)) {
- DownloadService service = getDownloadService();
- if((service != null && service.getCurrentPlaying() != null)) {
- getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD);
- Intent intent = new Intent();
- intent.setClass(this, DownloadActivity.class);
- startActivity(intent);
- }
}
setContentView(R.layout.abstract_fragment_activity);
@@ -128,49 +129,112 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
}
}
currentFragment = getNewFragment(fragmentType);
-
+
if("".equals(fragmentType) || fragmentType == null || firstRun) {
// Initial startup stuff
if(!sessionInitialized) {
loadSession();
}
}
-
+
currentFragment.setPrimaryFragment(true);
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + "").commit();
-
+
if(getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY) != null) {
SearchFragment fragment = new SearchFragment();
replaceFragment(fragment, fragment.getSupportTag());
}
-
+
// If a album type is set, switch to that album type view
String albumType = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE);
if(albumType != null) {
SubsonicFragment fragment = new SelectDirectoryFragment();
-
+
Bundle args = new Bundle();
args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, albumType);
args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20);
args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0);
-
+
fragment.setArguments(args);
replaceFragment(fragment, fragment.getSupportTag());
}
}
- bottomBar = findViewById(R.id.bottom_bar);
- bottomBar.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- Intent intent = new Intent();
- intent.setClass(v.getContext(), DownloadActivity.class);
- startActivity(intent);
+ slideUpPanel = (SlidingUpPanelLayout) findViewById(R.id.slide_up_panel);
+ slideUpPanel.setPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() {
+ @Override
+ public void onPanelSlide(View panel, float slideOffset) {
+
+ }
+
+ @Override
+ public void onPanelCollapsed(View panel) {
+ bottomBar.setVisibility(View.VISIBLE);
+ nowPlayingToolbar.setVisibility(View.GONE);
+ nowPlayingFragment.setPrimaryFragment(false);
+ setSupportActionBar(mainToolbar);
+
+ if(getSupportActionBar().getCustomView() == null) {
+ createCustomActionBarView();
+ }
+ recreateSpinner();
+ if(drawerToggle != null && backStack.size() > 0) {
+ drawerToggle.setDrawerIndicatorEnabled(false);
+ } else {
+ drawerToggle.setDrawerIndicatorEnabled(true);
+ }
+ }
+
+ @Override
+ public void onPanelExpanded(View panel) {
+ // Disable custom view before switching
+ getSupportActionBar().setDisplayShowCustomEnabled(false);
+
+ bottomBar.setVisibility(View.GONE);
+ nowPlayingToolbar.setVisibility(View.VISIBLE);
+ setSupportActionBar(nowPlayingToolbar);
+ nowPlayingFragment.setPrimaryFragment(true);
+
+ drawerToggle.setDrawerIndicatorEnabled(false);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setHomeAsUpIndicator(coverArtView.getDrawable());
+ }
+
+ @Override
+ public void onPanelAnchored(View panel) {
+
+ }
+
+ @Override
+ public void onPanelHidden(View panel) {
+
}
});
- coverArtView = bottomBar.findViewById(R.id.album_art);
+
+ if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD)) {
+ // Post this later so it actually runs
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ openNowPlaying();
+ }
+ }, 200);
+ }
+
+ bottomBar = findViewById(R.id.bottom_bar);
+ mainToolbar = (Toolbar) findViewById(R.id.main_toolbar);
+ nowPlayingToolbar = (Toolbar) findViewById(R.id.now_playing_toolbar);
+ coverArtView = (ImageView) bottomBar.findViewById(R.id.album_art);
trackView = (TextView) bottomBar.findViewById(R.id.track_name);
artistView = (TextView) bottomBar.findViewById(R.id.artist_name);
+ setSupportActionBar(mainToolbar);
+
+ nowPlayingFragment = new NowPlayingFragment();
+ FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
+ trans.add(R.id.now_playing_fragment_container, nowPlayingFragment, nowPlayingFragment.getTag() + "");
+ trans.commit();
+
ImageButton previousButton = (ImageButton) findViewById(R.id.download_previous);
previousButton.setOnClickListener(new View.OnClickListener() {
@Override
@@ -262,7 +326,7 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
}
}
}
-
+
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@@ -300,7 +364,6 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
public void onResume() {
super.onResume();
- final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
@@ -369,7 +432,9 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
@Override
public void onBackPressed() {
- if(onBackPressedSupport()) {
+ if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
+ slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
+ } else if(onBackPressedSupport()) {
if(!Util.disableExitPrompt(this) && lastBackPressTime < (System.currentTimeMillis() - 4000)) {
lastBackPressTime = System.currentTimeMillis();
Util.toast(this, R.string.main_back_confirm);
@@ -380,6 +445,15 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
}
@Override
+ protected SubsonicFragment getCurrentFragment() {
+ if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
+ return nowPlayingFragment;
+ } else {
+ return super.getCurrentFragment();
+ }
+ }
+
+ @Override
public void replaceFragment(SubsonicFragment fragment, int tag, boolean replaceCurrent) {
super.replaceFragment(fragment, tag, replaceCurrent);
if(drawerToggle != null) {
@@ -393,24 +467,33 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
drawerToggle.setDrawerIndicatorEnabled(true);
}
}
-
+
+ @Override
+ protected void drawerItemSelected(int position, View view) {
+ super.drawerItemSelected(position, view);
+
+ if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
+ slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
+ }
+ }
+
@Override
public void startFragmentActivity(String fragmentType) {
// Create a transaction that does all of this
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
-
+
// Clear existing stack
for(int i = backStack.size() - 1; i >= 0; i--) {
trans.remove(backStack.get(i));
}
trans.remove(currentFragment);
backStack.clear();
-
+
// Create new stack
currentFragment = getNewFragment(fragmentType);
currentFragment.setPrimaryFragment(true);
trans.add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + "");
-
+
// Done, cleanup
trans.commit();
supportInvalidateOptionsMenu();
@@ -426,7 +509,16 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
drawerToggle.setDrawerIndicatorEnabled(true);
}
}
-
+
+ @Override
+ public void openNowPlaying() {
+ slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
+ }
+ @Override
+ public void closeNowPlaying() {
+ slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
+ }
+
private SubsonicFragment getNewFragment(String fragmentType) {
if("Artist".equals(fragmentType)) {
return new SelectArtistFragment();
@@ -447,7 +539,7 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
} else {
return new MainFragment();
}
- }
+ }
private void update() {
DownloadService downloadService = getDownloadService();
@@ -470,11 +562,23 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
trackView.setText(song.getTitle());
artistView.setText(song.getArtist());
} else {
- trackView.setText("Title");
- artistView.setText("Artist");
+ trackView.setText(R.string.main_title);
+ artistView.setText(R.string.main_artist);
}
- getImageLoader().loadImage(coverArtView, song, false, false);
+ SilentBackgroundTask task = getImageLoader().loadImage(coverArtView, song, false, coverArtView.getHeight(), false);
+ if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) {
+ if(task == null) {
+ getSupportActionBar().setHomeAsUpIndicator(coverArtView.getDrawable());
+ } else {
+ task.setOnCompletionListener(new Runnable() {
+ @Override
+ public void run() {
+ getSupportActionBar().setHomeAsUpIndicator(coverArtView.getDrawable());
+ }
+ });
+ }
+ }
int[] attrs = new int[] {(state == PlayerState.STARTED) ? R.attr.media_button_pause : R.attr.media_button_start};
TypedArray typedArray = this.obtainStyledAttributes(attrs);
startButton.setImageResource(typedArray.getResourceId(0, 0));
@@ -502,7 +606,7 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
if(ServerInfo.canSavePlayQueue(this) && !Util.isOffline(this)) {
loadRemotePlayQueue();
}
-
+
sessionInitialized = true;
}
private void loadSettings() {
@@ -551,7 +655,7 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
return true;
}
}
-
+
private void loadBookmarks() {
final Context context = this;
new SilentBackgroundTask<Void>(context) {
@@ -562,7 +666,7 @@ public class SubsonicFragmentActivity extends SubsonicActivity {
return null;
}
-
+
@Override
public void error(Throwable error) {
Log.e(TAG, "Failed to get bookmarks", error);
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java
index ae38534a..71c135aa 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java
@@ -140,7 +140,7 @@ public class MainFragment extends SubsonicFragment {
}
int activeServer = menuItem.getItemId() - MENU_ITEM_SERVER_BASE;
- setActiveServer(activeServer);
+ context.setActiveServer(activeServer);
return true;
}
@@ -252,25 +252,6 @@ public class MainFragment extends SubsonicFragment {
}
}
- private void setActiveServer(int instance) {
- if (Util.getActiveServer(context) != instance) {
- final DownloadService service = getDownloadService();
- if (service != null) {
- new SilentBackgroundTask<Void>(context) {
- @Override
- protected Void doInBackground() throws Throwable {
- service.clearIncomplete();
- return null;
- }
- }.execute();
-
- }
- Util.setActiveServer(context, instance);
- context.invalidate();
- UserUtil.refreshCurrentUser(context, false, true);
- }
- }
-
private void toggleOffline() {
boolean isOffline = Util.isOffline(context);
Util.setOffline(context, !isOffline);
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java
index 3e30af50..b9ef412c 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/NowPlayingFragment.java
@@ -20,6 +20,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
@@ -141,6 +142,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
startFlipped = true;
}
}
+ primaryFragment = false;
}
@Override
@@ -153,11 +155,8 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
rootView = inflater.inflate(R.layout.download, container, false);
setTitle(R.string.button_bar_now_playing);
-
+
mainLayout = rootView.findViewById(R.id.download_layout);
- if(!primaryFragment) {
- mainLayout.setVisibility(View.GONE);
- }
WindowManager w = context.getWindowManager();
Display d = w.getDefaultDisplay();
@@ -397,7 +396,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
} else {
// Immediately skip to the next song
downloadService.next(true);
-
+
// Otherwise set rating to 1
setRating(entry, 1);
rateBadButton.setImageResource(R.drawable.ic_action_rating_bad_selected);
@@ -543,13 +542,6 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
registerForContextMenu(playlistView);
- DownloadService downloadService = getDownloadService();
- if (downloadService != null && context.getIntent().getBooleanExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE, false)) {
- context.getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE);
- warnIfStorageUnavailable();
- downloadService.setShufflePlayEnabled(true);
- }
-
if(Build.MODEL.equals("Nexus 4") || Build.MODEL.equals("GT-I9100")) {
View slider = rootView.findViewById(R.id.download_slider);
slider.setPadding(0, 0, 0, 0);
@@ -604,7 +596,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if(menuItemSelected(menuItem.getItemId(), null)) {
return true;
}
-
+
return super.onOptionsItemSelected(menuItem);
}
@@ -641,7 +633,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if(!primaryFragment) {
return false;
}
-
+
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo();
DownloadFile downloadFile = (DownloadFile) playlistView.getItemAtPosition(info.position);
return menuItemSelected(menuItem.getItemId(), downloadFile) || super.onContextItemSelected(menuItem);
@@ -841,7 +833,13 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
@Override
public void onResume() {
super.onResume();
-
+ if(this.primaryFragment) {
+ onResumeHandlers();
+ } else {
+ update();
+ }
+ }
+ private void onResumeHandlers() {
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
@@ -898,25 +896,46 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
@Override
public void onPause() {
super.onPause();
- executorService.shutdown();
- if(getDownloadService() != null) {
- getDownloadService().stopRemoteScan();
+ onPauseHandlers();
+ }
+ private void onPauseHandlers() {
+ if(executorService != null) {
+ executorService.shutdown();
+ if (getDownloadService() != null) {
+ getDownloadService().stopRemoteScan();
+ }
+ executorService = null;
+ playlistFlipper.setDisplayedChild(0);
}
}
-
+
@Override
public void setPrimaryFragment(boolean primary) {
super.setPrimaryFragment(primary);
if(rootView != null) {
if(primary) {
- mainLayout.setVisibility(View.VISIBLE);
- updateButtons();
+ onResumeHandlers();
} else {
- mainLayout.setVisibility(View.GONE);
+ onPauseHandlers();
}
}
}
+ @Override
+ public void setTitle(int title) {
+ this.title = context.getResources().getString(title);
+ if(this.primaryFragment) {
+ context.setTitle(this.title);
+ }
+ }
+ @Override
+ public void setSubtitle(CharSequence title) {
+ this.subtitle = title;
+ if(this.primaryFragment) {
+ context.setSubtitle(title);
+ }
+ }
+
private void scheduleHideControls() {
if (hideControlsFuture != null) {
hideControlsFuture.cancel(false);
@@ -954,7 +973,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if(context == null) {
return;
}
-
+
if(Util.isOffline(context)) {
bookmarkButton.setVisibility(View.GONE);
rateBadButton.setVisibility(View.GONE);
@@ -971,6 +990,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
// Scroll to current playing/downloading.
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void scrollToCurrent() {
if (getDownloadService() == null || songListAdapter == null) {
scrollWhenLoaded = true;
@@ -1043,26 +1063,26 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
- lengthBar.setProgress(length - 1);
+ lengthBar.setProgress(length - 1);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.menu_set_timer)
- .setView(dialogView)
- .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- int length = getMinutes(lengthBar.getProgress());
+ .setView(dialogView)
+ .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ int length = getMinutes(lengthBar.getProgress());
- SharedPreferences.Editor editor = prefs.edit();
- editor.putString(Constants.PREFERENCES_KEY_SLEEP_TIMER_DURATION, Integer.toString(length));
- editor.commit();
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putString(Constants.PREFERENCES_KEY_SLEEP_TIMER_DURATION, Integer.toString(length));
+ editor.commit();
- getDownloadService().setSleepTimerDuration(length);
- getDownloadService().startSleepTimer();
- context.supportInvalidateOptionsMenu();
- }
- })
- .setNegativeButton(R.string.common_cancel, null);
+ getDownloadService().setSleepTimerDuration(length);
+ getDownloadService().startSleepTimer();
+ context.supportInvalidateOptionsMenu();
+ }
+ })
+ .setNegativeButton(R.string.common_cancel, null);
AlertDialog dialog = builder.create();
dialog.show();
}
@@ -1087,7 +1107,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
playlistFlipper.setInAnimation(AnimationUtils.loadAnimation(context, R.anim.push_up_in));
playlistFlipper.setOutAnimation(AnimationUtils.loadAnimation(context, R.anim.push_up_out));
playlistFlipper.setDisplayedChild(1);
-
+
UpdateView.triggerUpdate();
}
}
@@ -1125,7 +1145,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
protected Void doInBackground() throws Throwable {
currentPlayingIndex = downloadService.getCurrentPlayingIndex() + 1;
size = downloadService.size();
-
+
return null;
}
@@ -1133,14 +1153,14 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
protected void done(Void result) {
List<DownloadFile> list;
list = downloadService.getSongs();
-
+
if(downloadService.isShufflePlayEnabled()) {
emptyTextView.setText(R.string.download_shuffle_loading);
}
else {
emptyTextView.setText(R.string.download_empty);
}
-
+
if(songListAdapter == null || refresh) {
songList = new ArrayList<DownloadFile>();
songList.addAll(list);
@@ -1150,7 +1170,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
songList.addAll(list);
songListAdapter.notifyDataSetChanged();
}
-
+
emptyTextView.setVisibility(list.isEmpty() ? View.VISIBLE : View.GONE);
currentRevision = downloadService.getDownloadListUpdateRevision();
@@ -1171,7 +1191,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
default:
break;
}
-
+
if(scrollWhenLoaded) {
scrollToCurrent();
scrollWhenLoaded = false;
@@ -1194,7 +1214,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if (downloadService == null || onCurrentChangedTask != null) {
return;
}
-
+
onCurrentChangedTask = new SilentBackgroundTask<Void>(context) {
int currentPlayingIndex;
int currentPlayingSize;
@@ -1255,7 +1275,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
}
};
-
+
if(onDownloadListChangedTask == null) {
onCurrentChangedTask.execute();
}
@@ -1395,33 +1415,33 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
}.execute();
}
-
+
private void createBookmark() {
DownloadService downloadService = getDownloadService();
if(downloadService == null) {
return;
}
-
+
final DownloadFile currentDownload = downloadService.getCurrentPlaying();
if(currentDownload == null) {
return;
}
-
+
View dialogView = context.getLayoutInflater().inflate(R.layout.create_bookmark, null);
final EditText commentBox = (EditText)dialogView.findViewById(R.id.comment_text);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.download_save_bookmark_title)
- .setView(dialogView)
- .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- String comment = commentBox.getText().toString();
+ .setView(dialogView)
+ .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ String comment = commentBox.getText().toString();
- createBookmark(currentDownload, comment);
- }
- })
- .setNegativeButton(R.string.common_cancel, null);
+ createBookmark(currentDownload, comment);
+ }
+ })
+ .setNegativeButton(R.string.common_cancel, null);
AlertDialog dialog = builder.create();
dialog.show();
}
@@ -1430,13 +1450,13 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if(downloadService == null) {
return;
}
-
+
final Entry currentSong = currentDownload.getSong();
final int position = downloadService.getPlayerPosition();
final Bookmark oldBookmark = currentSong.getBookmark();
currentSong.setBookmark(new Bookmark(position));
bookmarkButton.setImageResource(R.drawable.ic_menu_bookmark_selected);
-
+
new SilentBackgroundTask<Void>(context) {
@Override
protected Void doInBackground() throws Throwable {
@@ -1458,12 +1478,12 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
Util.toast(context, R.string.download_save_bookmark);
setControlsVisible(true);
}
-
+
@Override
protected void error(Throwable error) {
Log.w(TAG, "Failed to create bookmark", error);
currentSong.setBookmark(oldBookmark);
-
+
// If no bookmark at start, then return to no bookmark
if(oldBookmark == null) {
int bookmark;
@@ -1474,14 +1494,14 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
}
bookmarkButton.setImageResource(bookmark);
}
-
+
String msg;
if(error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
} else {
msg = context.getResources().getString(R.string.download_save_bookmark_failed) + getErrorMessage(error);
}
-
+
Util.toast(context, msg, false);
}
}.execute();
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java
index c71d99f6..830e2957 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java
@@ -25,7 +25,6 @@ import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import github.daneren2005.dsub.R;
-import github.daneren2005.dsub.activity.DownloadActivity;
import github.daneren2005.dsub.domain.Bookmark;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.service.DownloadService;
@@ -110,7 +109,7 @@ public class SelectBookmarkFragment extends SelectListFragment<MusicDirectory.En
@Override
protected void done(Void result) {
- Util.startActivityWithoutTransition(context, DownloadActivity.class);
+ context.openNowPlaying();
}
}.execute();
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
index 841a6369..9e7cd053 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
@@ -46,7 +46,6 @@ import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
-import github.daneren2005.dsub.activity.DownloadActivity;
import github.daneren2005.dsub.domain.PodcastEpisode;
import github.daneren2005.dsub.service.MusicService;
import github.daneren2005.dsub.service.MusicServiceFactory;
@@ -993,7 +992,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
@Override
protected void done(Void result) {
if (autoplay) {
- Util.startActivityWithoutTransition(context, DownloadActivity.class);
+ context.openNowPlaying();
} else if (save) {
Util.toast(context,
context.getResources().getQuantityString(R.plurals.select_album_n_songs_downloading, songs.size(), songs.size()));
@@ -1335,7 +1334,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
@Override
protected void done(Void result) {
- Util.startActivityWithoutTransition(context, DownloadActivity.class);
+ context.openNowPlaying();
}
}.execute();
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java
index 109983ba..fcae3a5c 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java
@@ -18,6 +18,7 @@
*/
package github.daneren2005.dsub.fragments;
+import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
@@ -28,6 +29,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.os.StatFs;
import android.support.v4.app.Fragment;
@@ -49,7 +51,6 @@ import android.widget.EditText;
import android.widget.RatingBar;
import android.widget.TextView;
import github.daneren2005.dsub.R;
-import github.daneren2005.dsub.activity.DownloadActivity;
import github.daneren2005.dsub.activity.SubsonicActivity;
import github.daneren2005.dsub.activity.SubsonicFragmentActivity;
import github.daneren2005.dsub.domain.Artist;
@@ -101,7 +102,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
private static final String TAG = SubsonicFragment.class.getSimpleName();
private static int TAG_INC = 10;
private int tag;
-
+
protected SubsonicActivity context;
protected CharSequence title = null;
protected CharSequence subtitle = null;
@@ -116,7 +117,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
protected boolean artistOverride = false;
protected SwipeRefreshLayout refreshLayout;
protected boolean firstRun;
-
+
public SubsonicFragment() {
super();
tag = TAG_INC++;
@@ -187,7 +188,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
return false;
}
-
+
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo, Object selected) {
MenuInflater inflater = context.getMenuInflater();
@@ -199,7 +200,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
else {
inflater.inflate(R.menu.select_podcast_episode_context, menu);
-
+
if(entry.getBookmark() == null) {
menu.removeItem(R.id.bookmark_menu_delete);
}
@@ -223,7 +224,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
else {
inflater.inflate(R.menu.select_song_context, menu);
-
+
if(entry.getBookmark() == null) {
menu.removeItem(R.id.bookmark_menu_delete);
}
@@ -286,7 +287,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
if(info.targetView instanceof SongView) {
SongView songView = (SongView) info.targetView;
DownloadFile downloadFile = songView.getDownloadFile();
-
+
try {
if(downloadFile != null) {
if(downloadFile.isWorkDone()) {
@@ -294,7 +295,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
if(downloadFile.isSaved()) {
menu.removeItem(R.id.song_menu_pin);
}
-
+
// Remove cache option no matter what if already downloaded
menu.removeItem(R.id.song_menu_download);
} else {
@@ -324,7 +325,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
folder = ((ArtistEntryView) info.targetView).getFile();
id = R.id.artist_menu_delete;
}
-
+
try {
if(folder != null && !folder.exists()) {
menu.removeItem(id);
@@ -475,7 +476,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
return true;
}
-
+
public void replaceFragment(SubsonicFragment fragment) {
replaceFragment(fragment, true);
}
@@ -492,7 +493,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
public int getSupportTag() {
return tag;
}
-
+
public void setPrimaryFragment(boolean primary) {
primaryFragment = primary;
if(primary) {
@@ -650,9 +651,12 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
protected void onShuffleRequested() {
if(Util.isOffline(context)) {
- Intent intent = new Intent(context, DownloadActivity.class);
- intent.putExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE, true);
- Util.startActivityWithoutTransition(context, intent);
+ DownloadService downloadService = getDownloadService();
+ if(downloadService == null) {
+ return;
+ }
+ downloadService.setShufflePlayEnabled(true);
+ context.openNowPlaying();
return;
}
@@ -691,21 +695,21 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.shuffle_pick_genre)
- .setItems(names.toArray(new CharSequence[names.size()]), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- if(which == 0) {
- genreCombo.setText("");
- } else {
- genreCombo.setText(finalNames.get(which));
- }
- }
- });
+ .setItems(names.toArray(new CharSequence[names.size()]), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if(which == 0) {
+ genreCombo.setText("");
+ } else {
+ genreCombo.setText(finalNames.get(which));
+ }
+ }
+ });
AlertDialog dialog = builder.create();
dialog.show();
}
@Override
- protected void error(Throwable error) {
+ protected void error(Throwable error) {
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
@@ -731,31 +735,34 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.shuffle_title)
- .setView(dialogView)
- .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- Intent intent = new Intent(context, DownloadActivity.class);
- intent.putExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE, true);
- String genre;
- if(useCombo) {
- genre = genreCombo.getText().toString();
- } else {
- genre = genreBox.getText().toString();
+ .setView(dialogView)
+ .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ String genre;
+ if (useCombo) {
+ genre = genreCombo.getText().toString();
+ } else {
+ genre = genreBox.getText().toString();
+ }
+ String startYear = startYearBox.getText().toString();
+ String endYear = endYearBox.getText().toString();
+
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, startYear);
+ editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, endYear);
+ editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, genre);
+ editor.commit();
+
+ DownloadService downloadService = getDownloadService();
+ if (downloadService == null) {
+ return;
+ }
+ downloadService.setShufflePlayEnabled(true);
+ context.openNowPlaying();
}
- String startYear = startYearBox.getText().toString();
- String endYear = endYearBox.getText().toString();
-
- SharedPreferences.Editor editor = prefs.edit();
- editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, startYear);
- editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, endYear);
- editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, genre);
- editor.commit();
-
- Util.startActivityWithoutTransition(context, intent);
- }
- })
- .setNegativeButton(R.string.common_cancel, null);
+ })
+ .setNegativeButton(R.string.common_cancel, null);
AlertDialog dialog = builder.create();
dialog.show();
}
@@ -906,7 +913,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
playNowOverride = true;
return false;
}
-
+
if (!append && !background) {
downloadService.clear();
}
@@ -994,7 +1001,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
MusicService musicService = MusicServiceFactory.getMusicService(context);
List<Playlist> playlists = new ArrayList<Playlist>();
playlists.addAll(musicService.getPlaylists(false, context, this));
-
+
// Iterate through and remove all non owned public playlists
Iterator<Playlist> it = playlists.iterator();
while(it.hasNext()) {
@@ -1003,7 +1010,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
it.remove();
}
}
-
+
return playlists;
}
@@ -1016,7 +1023,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Playlist playlist = getItem(position);
-
+
// Create new if not getting a convert view to use
PlaylistSongView view;
if(convertView instanceof PlaylistSongView) {
@@ -1033,21 +1040,21 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.playlist_add_to)
- .setAdapter(playlistAdapter, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- if (which > 0) {
- addToPlaylist(playlists.get(which), songs);
- } else {
- createNewPlaylist(songs, false);
+ .setAdapter(playlistAdapter, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if (which > 0) {
+ addToPlaylist(playlists.get(which), songs);
+ } else {
+ createNewPlaylist(songs, false);
+ }
}
- }
- });
+ });
AlertDialog dialog = builder.create();
dialog.show();
}
@Override
- protected void error(Throwable error) {
+ protected void error(Throwable error) {
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
@@ -1075,7 +1082,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
@Override
- protected void error(Throwable error) {
+ protected void error(Throwable error) {
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
@@ -1087,7 +1094,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
}.execute();
}
-
+
protected void createNewPlaylist(final List<Entry> songs, final boolean getSuggestion) {
View layout = context.getLayoutInflater().inflate(R.layout.save_playlist, null);
final EditText playlistNameView = (EditText) layout.findViewById(R.id.save_playlist_name);
@@ -1115,34 +1122,34 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.download_playlist_title)
- .setMessage(R.string.download_playlist_name)
- .setView(layout)
- .setPositiveButton(R.string.common_save, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- String playlistName = String.valueOf(playlistNameView.getText());
- if(overwriteCheckBox.isChecked()) {
- overwritePlaylist(songs, playlistName, getDownloadService().getSuggestedPlaylistId());
- } else {
- createNewPlaylist(songs, playlistName);
-
- if(getSuggestion) {
- DownloadService downloadService = getDownloadService();
- if(downloadService != null) {
- downloadService.setSuggestedPlaylistName(playlistName, null);
+ .setMessage(R.string.download_playlist_name)
+ .setView(layout)
+ .setPositiveButton(R.string.common_save, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ String playlistName = String.valueOf(playlistNameView.getText());
+ if(overwriteCheckBox.isChecked()) {
+ overwritePlaylist(songs, playlistName, getDownloadService().getSuggestedPlaylistId());
+ } else {
+ createNewPlaylist(songs, playlistName);
+
+ if(getSuggestion) {
+ DownloadService downloadService = getDownloadService();
+ if(downloadService != null) {
+ downloadService.setSuggestedPlaylistName(playlistName, null);
+ }
}
}
}
- }
- })
- .setNegativeButton(R.string.common_cancel, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- })
- .setCancelable(true);
-
+ })
+ .setNegativeButton(R.string.common_cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ })
+ .setCancelable(true);
+
AlertDialog dialog = builder.create();
dialog.show();
}
@@ -1184,7 +1191,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
@Override
- protected void error(Throwable error) {
+ protected void error(Throwable error) {
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
@@ -1197,6 +1204,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}.execute();
}
+ @TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
public void displaySongInfo(final Entry song) {
Integer duration = null;
Integer bitrate = null;
@@ -1209,12 +1217,12 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
if(file.exists()) {
MediaMetadataRetriever metadata = new MediaMetadataRetriever();
metadata.setDataSource(file.getAbsolutePath());
-
+
String tmp = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
duration = Integer.parseInt((tmp != null) ? tmp : "0") / 1000;
format = FileUtil.getExtension(file.getName());
size = file.length();
-
+
// If no duration try to read bitrate tag
if(duration == null) {
tmp = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE);
@@ -1224,7 +1232,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
// Divide by 1000 so in kbps
bitrate = (int) (size / duration) / 1000 * 8;
}
-
+
if(Util.isOffline(context)) {
song.setGenre(metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE));
String year = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR);
@@ -1286,7 +1294,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
Util.info(context, song.getTitle(), msg);
}
-
+
protected void playVideo(Entry entry) {
if(entryExists(entry)) {
playExternalPlayer(entry);
@@ -1315,7 +1323,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
intent.putExtra(Intent.EXTRA_TITLE, entry.getTitle());
List<ResolveInfo> intents = context.getPackageManager()
- .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+ .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if(intents != null && intents.size() > 0) {
startActivity(intent);
}else {
@@ -1373,7 +1381,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
public void deleteRecursively(Artist artist) {
deleteRecursively(FileUtil.getArtistDirectory(context, artist));
}
-
+
public void deleteRecursively(Entry album) {
deleteRecursively(FileUtil.getAlbumDirectory(context, album));
@@ -1490,7 +1498,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
intent.putExtra(Intent.EXTRA_TEXT, share.getUrl());
context.startActivity(Intent.createChooser(intent, context.getResources().getString(R.string.share_via)));
}
-
+
public GestureDetector getGestureDetector() {
return gestureScanner;
}
@@ -1515,7 +1523,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
public void onClick(DialogInterface dialog, int id) {
final Bookmark oldBookmark = song.getBookmark();
song.setBookmark(null);
-
+
new SilentBackgroundTask<Void>(context) {
@Override
protected Void doInBackground() throws Throwable {
@@ -1528,7 +1536,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
@Override
protected void error(Throwable error) {
song.setBookmark(oldBookmark);
-
+
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
@@ -1546,7 +1554,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
AlertDialog dialog = builder.create();
dialog.show();
}
-
+
protected void playNow(List<Entry> entries) {
playNow(entries, null, null);
}
@@ -1558,7 +1566,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
break;
}
}
-
+
// If no bookmark found, just play from start
if(bookmark == null) {
playNow(entries, 0, playlistName, playlistId);
@@ -1585,17 +1593,17 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
if(downloadService == null) {
return null;
}
-
+
downloadService.clear();
downloadService.download(entries, false, true, true, false, entries.indexOf(song), position);
downloadService.setSuggestedPlaylistName(playlistName, playlistId);
return null;
}
-
+
@Override
protected void done(Void result) {
- Util.startActivityWithoutTransition(context, DownloadActivity.class);
+ context.openNowPlaying();
}
}.execute();
}
@@ -1657,19 +1665,19 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
View layout = context.getLayoutInflater().inflate(R.layout.rating, null);
final RatingBar ratingBar = (RatingBar) layout.findViewById(R.id.rating_bar);
ratingBar.setRating((float) entry.getRating());
-
+
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(context.getResources().getString(R.string.rating_title, entry.getTitle()))
- .setView(layout)
- .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int id) {
- int rating = (int) ratingBar.getRating();
- setRating(entry, rating, onRatingChange);
- }
- })
- .setNegativeButton(R.string.common_cancel, null);
-
+ .setView(layout)
+ .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ int rating = (int) ratingBar.getRating();
+ setRating(entry, rating, onRatingChange);
+ }
+ })
+ .setNegativeButton(R.string.common_cancel, null);
+
AlertDialog dialog = builder.create();
dialog.show();
}
@@ -1684,7 +1692,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
if(onRatingChange != null) {
onRatingChange.ratingChange(rating);
}
-
+
new SilentBackgroundTask<Void>(context) {
@Override
protected Void doInBackground() throws Throwable {
@@ -1711,7 +1719,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
if(onRatingChange != null) {
onRatingChange.ratingChange(oldRating);
}
-
+
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
@@ -1723,16 +1731,16 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
}.execute();
}
-
+
protected abstract class EntryInstanceUpdater {
private Entry entry;
-
+
public EntryInstanceUpdater(Entry entry) {
this.entry = entry;
}
-
+
public abstract void update(Entry found);
-
+
public void execute() {
DownloadService downloadService = getDownloadService();
if(downloadService != null && !entry.isDirectory()) {
@@ -1745,12 +1753,12 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
serializeChanges = true;
}
}
-
+
if(serializeChanges) {
downloadService.serializeQueue();
}
}
-
+
Entry find = UpdateView.findEntry(entry);
if(find != null) {
update(find);
@@ -1810,7 +1818,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
if(result) {
- Util.startActivityWithoutTransition(context, DownloadActivity.class);
+ context.openNowPlaying();
}
}
}
diff --git a/app/src/main/java/github/daneren2005/dsub/provider/DSubWidgetProvider.java b/app/src/main/java/github/daneren2005/dsub/provider/DSubWidgetProvider.java
index 444b6cff..7cb3ce8b 100644
--- a/app/src/main/java/github/daneren2005/dsub/provider/DSubWidgetProvider.java
+++ b/app/src/main/java/github/daneren2005/dsub/provider/DSubWidgetProvider.java
@@ -39,7 +39,6 @@ import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import github.daneren2005.dsub.R;
-import github.daneren2005.dsub.activity.DownloadActivity;
import github.daneren2005.dsub.activity.SubsonicActivity;
import github.daneren2005.dsub.activity.SubsonicFragmentActivity;
import github.daneren2005.dsub.domain.MusicDirectory;
@@ -270,9 +269,7 @@ public class DSubWidgetProvider extends AppWidgetProvider {
/**
* Link up various button actions using {@link PendingIntent}.
*
- * @param playerActive True if player is active in background, which means
- * widget click will launch {@link DownloadActivity},
- * otherwise we launch {@link github.daneren2005.dsub.activity.SubsonicFragmentActivity}.
+ * @param playerActive @param playerActive True if player is active in background. Launch {@link github.daneren2005.dsub.activity.SubsonicFragmentActivity}.
*/
private void linkButtons(Context context, RemoteViews views, boolean playerActive) {
Intent intent = new Intent(context, SubsonicFragmentActivity.class);
diff --git a/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java b/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java
index 7ba2064b..c3d86d4b 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/ImageLoader.java
@@ -190,8 +190,11 @@ public class ImageLoader {
}
public SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, boolean crossfade) {
- // TODO: If we know this a artist, try to load artist info instead
int size = large ? imageSizeLarge : imageSizeDefault;
+ return loadImage(view, entry, large, size, crossfade);
+ }
+ public SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, int size, boolean crossfade) {
+ // TODO: If we know this a artist, try to load artist info instead
if(entry != null && !entry.isAlbum() && ServerInfo.checkServerVersion(context, "1.11") && !Util.isOffline(context)) {
SilentBackgroundTask task = new ArtistImageTask(view.getContext(), entry, size, imageSizeLarge, large, view, crossfade);
task.execute();
@@ -280,6 +283,7 @@ public class ImageLoader {
view.setImageDrawable(drawable);
return null;
}
+ view.setImageDrawable(null);
SilentBackgroundTask<Void> task = new AvatarTask(context, view, username);
task.execute();
@@ -582,7 +586,6 @@ public class ImageLoader {
}
} catch (Throwable x) {
Log.e(TAG, "Failed to download album art.", x);
- cancelled.set(true);
}
return null;
@@ -592,6 +595,8 @@ public class ImageLoader {
protected void done(Void result) {
if(mDrawable != null) {
mView.setImageDrawable(mDrawable);
+ } else {
+ mView.setImageResource(R.drawable.ic_social_person);
}
}
}
diff --git a/app/src/main/java/github/daneren2005/dsub/util/Util.java b/app/src/main/java/github/daneren2005/dsub/util/Util.java
index 032facd6..969e178e 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/Util.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/Util.java
@@ -48,6 +48,7 @@ import android.view.Gravity;
import android.widget.TextView;
import android.widget.Toast;
import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.activity.SubsonicFragmentActivity;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.PlayerState;
import github.daneren2005.dsub.domain.RepeatMode;
@@ -256,14 +257,26 @@ public final class Util {
}
public static void applyTheme(Context context, String theme) {
- if ("dark".equals(theme)) {
- context.setTheme(R.style.Theme_DSub_Dark);
- } else if ("black".equals(theme)) {
- context.setTheme(R.style.Theme_DSub_Black);
- } else if ("holo".equals(theme)) {
- context.setTheme(R.style.Theme_DSub_Holo);
+ if(context instanceof SubsonicFragmentActivity) {
+ if ("dark".equals(theme)) {
+ context.setTheme(R.style.Theme_DSub_Dark_No_Actionbar);
+ } else if ("black".equals(theme)) {
+ context.setTheme(R.style.Theme_DSub_Black_No_Actionbar);
+ } else if ("holo".equals(theme)) {
+ context.setTheme(R.style.Theme_DSub_Holo_No_Actionbar);
+ } else {
+ context.setTheme(R.style.Theme_DSub_Light_No_Actionbar);
+ }
} else {
- context.setTheme(R.style.Theme_DSub_Light);
+ if ("dark".equals(theme)) {
+ context.setTheme(R.style.Theme_DSub_Dark);
+ } else if ("black".equals(theme)) {
+ context.setTheme(R.style.Theme_DSub_Black);
+ } else if ("holo".equals(theme)) {
+ context.setTheme(R.style.Theme_DSub_Holo);
+ } else {
+ context.setTheme(R.style.Theme_DSub_Light);
+ }
}
SharedPreferences prefs = Util.getPreferences(context);
diff --git a/app/src/main/res/layout-large-land/abstract_fragment_container.xml b/app/src/main/res/layout-large-land/abstract_fragment_container.xml
index 5e3b1561..3901710f 100644
--- a/app/src/main/res/layout-large-land/abstract_fragment_container.xml
+++ b/app/src/main/res/layout-large-land/abstract_fragment_container.xml
@@ -2,8 +2,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
- android:layout_height="0px"
- android:layout_weight="1">
+ android:layout_height="match_parent"
+ android:layout_marginTop="?attr/actionBarSize">
<FrameLayout
android:id="@+id/fragment_container"
diff --git a/app/src/main/res/layout/abstract_fragment_activity.xml b/app/src/main/res/layout/abstract_fragment_activity.xml
index d9c99f2f..29fbc3b1 100644
--- a/app/src/main/res/layout/abstract_fragment_activity.xml
+++ b/app/src/main/res/layout/abstract_fragment_activity.xml
@@ -1,84 +1,131 @@
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.sothree.slidinguppanel.SlidingUpPanelLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ 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="center_horizontal"
- android:orientation="vertical" >
+ android:gravity="bottom"
+ sothree:umanoPanelHeight="?attr/actionBarSize"
+ sothree:umanoShadowHeight="4dp"
+ sothree:umanoDragView="@+id/slide_up_swipe_target">
- <include layout="@layout/abstract_fragment_container" />
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <View
- android:layout_width="fill_parent"
- android:layout_height="1px"
- android:background="@color/dividerColor"/>
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/main_toolbar"
+ style="?attr/actionBarStyle"
+ android:layout_height="?attr/actionBarSize"
+ android:layout_width="match_parent"/>
+
+ <include layout="@layout/abstract_fragment_container"/>
+ </FrameLayout>
<LinearLayout
- android:id="@+id/bottom_bar"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- style="@style/BasicButton"
- android:orientation="horizontal">
-
- <github.daneren2005.dsub.view.RecyclingImageView
- android:id="@+id/album_art"
- android:layout_width="50dip"
- android:layout_height="50dip"
- android:layout_gravity="left|center"
- android:scaleType="fitStart"/>
-
- <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"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:textColor="?android:textColorPrimary"
- android:singleLine="true"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textSize="13sp"
- android:text="@string/search.artists"/>
-
- <TextView
- android:id="@+id/artist_name"
+ 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.support.v7.widget.Toolbar
+ android:id="@+id/now_playing_toolbar"
+ style="?attr/actionBarStyle"
+ android:layout_height="?attr/actionBarSize"
+ android:layout_width="match_parent"
+ android:visibility="gone"/>
+
+ <LinearLayout
+ android:id="@+id/bottom_bar"
+ android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:textColor="?android:textColorSecondary"
- android:singleLine="true"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textSize="12sp"
- android:text="@string/search.albums"/>
- </LinearLayout>
-
- <LinearLayout
- android:layout_height="wrap_content"
- android:layout_width="0dp"
- android:layout_weight="1">
-
- <ImageButton
- style="@style/PlaybackControl.Small"
- android:id="@+id/download_previous"
- android:src="?attr/media_button_backward"
- android:layout_width="0dp"
- android:layout_weight="1"/>
-
- <ImageButton
- style="@style/PlaybackControl.Small"
- android:id="@+id/download_start"
- android:src="?attr/media_button_start"
- android:layout_width="0dp"
- android:layout_weight="1"/>
-
- <ImageButton
- style="@style/PlaybackControl.Small"
- android:id="@+id/download_next"
- android:src="?attr/media_button_forward"
- android:layout_width="0dp"
- android:layout_weight="1"/>
- </LinearLayout>
+ style="@style/BasicButton"
+ android:orientation="horizontal">
+
+ <github.daneren2005.dsub.view.RecyclingImageView
+ android:id="@+id/album_art"
+ android:layout_width="?attr/actionBarSize"
+ android:layout_height="?attr/actionBarSize"
+ android:layout_gravity="left|center"
+ android:scaleType="fitStart"/>
+
+ <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"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:textColor="?android:textColorPrimary"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textSize="@dimen/BottomBar.Text.Major"
+ android:text="@string/main.title"
+ android:ellipsize="marquee"
+ android:marqueeRepeatLimit="marquee_forever"
+ android:scrollHorizontally="true"
+ android:focusable="true"
+ android:focusableInTouchMode="true">
+
+ <requestFocus android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:duplicateParentState="true" />
+ </TextView>
+
+ <TextView
+ android:id="@+id/artist_name"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:textColor="?android:textColorSecondary"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textSize="@dimen/BottomBar.Text.Minor"
+ android:text="@string/main.artist"/>
+ </LinearLayout>
+
+
+ <LinearLayout
+ android:layout_height="fill_parent"
+ android:layout_width="0dp"
+ android:layout_weight="1">
+
+ <ImageButton
+ style="@style/PlaybackControl.Match"
+ android:id="@+id/download_previous"
+ android:src="?attr/media_button_backward"
+ android:layout_width="0dp"
+ android:layout_weight="1"/>
+
+ <ImageButton
+ style="@style/PlaybackControl.Match"
+ android:id="@+id/download_start"
+ android:src="?attr/media_button_start"
+ android:layout_width="0dp"
+ android:layout_weight="1"/>
+
+ <ImageButton
+ style="@style/PlaybackControl.Match"
+ android:id="@+id/download_next"
+ android:src="?attr/media_button_forward"
+ android:layout_width="0dp"
+ android:layout_weight="1"/>
+ </LinearLayout>
+ </LinearLayout>
+ </FrameLayout>
+
+ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/now_playing_fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
</LinearLayout>
-</LinearLayout> \ No newline at end of file
+</com.sothree.slidinguppanel.SlidingUpPanelLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/abstract_fragment_container.xml b/app/src/main/res/layout/abstract_fragment_container.xml
index 61e17d1d..f13356c4 100644
--- a/app/src/main/res/layout/abstract_fragment_container.xml
+++ b/app/src/main/res/layout/abstract_fragment_container.xml
@@ -2,5 +2,5 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
- android:layout_height="0px"
- android:layout_weight="1"/> \ No newline at end of file
+ android:layout_height="match_parent"
+ android:layout_marginTop="?attr/actionBarSize"/> \ No newline at end of file
diff --git a/app/src/main/res/layout/drawer_header.xml b/app/src/main/res/layout/drawer_header.xml
new file mode 100644
index 00000000..00441b73
--- /dev/null
+++ b/app/src/main/res/layout/drawer_header.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="178dp"
+ android:orientation="vertical"
+ android:weightSum="1">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="56dp"
+ android:orientation="vertical"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentStart="true">
+
+ <TextView
+ android:id="@+id/header_server_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="16dp"
+ android:textColor="?android:textColorPrimary"
+ android:textSize="14sp"
+ android:textStyle="bold"/>
+
+ <TextView
+ android:id="@+id/header_user_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="16dp"
+ android:layout_marginTop="5dp"
+ android:textColor="?android:textColorSecondary"
+ android:textSize="14sp"
+ android:textStyle="normal"/>
+ </LinearLayout>
+
+ <de.hdodenhof.circleimageview.CircleImageView
+ android:id="@+id/header_user_avatar"
+ android:layout_width="70dp"
+ android:layout_height="70dp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginTop="38dp"/>
+</RelativeLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/drawer_list_item.xml b/app/src/main/res/layout/drawer_list_item.xml
index 5f17c9e9..607b3658 100644
--- a/app/src/main/res/layout/drawer_list_item.xml
+++ b/app/src/main/res/layout/drawer_list_item.xml
@@ -20,7 +20,8 @@
android:id="@+id/drawer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textSize="26sp"
android:singleLine="true"
- android:textColor="?android:textColorPrimary"/>
+ android:textColor="?android:textColorPrimary"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ style="DSub.TextViewStyle"/>
</LinearLayout>
diff --git a/app/src/main/res/values-large/dimens.xml b/app/src/main/res/values-large/dimens.xml
index b08dda86..fe8f1a6c 100644
--- a/app/src/main/res/values-large/dimens.xml
+++ b/app/src/main/res/values-large/dimens.xml
@@ -4,4 +4,6 @@
<dimen name="Button.Small">54dip</dimen>
<dimen name="AlbumArt.Small">96dip</dimen>
<dimen name="AlbumArt.Header">210dip</dimen>
+ <dimen name="BottomBar.Text.Major">18sp</dimen>
+ <dimen name="BottomBar.Text.Minor">16sp</dimen>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values-v16/themes.xml b/app/src/main/res/values-v16/themes.xml
index 013ac0aa..a14b6a1b 100644
--- a/app/src/main/res/values-v16/themes.xml
+++ b/app/src/main/res/values-v16/themes.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DSub.TextViewStyle" parent="android:Widget.TextView">
- <item name="android:fontFamily">sans-serif-light</item>
+ <item name="android:fontFamily">sans-serif</item>
</style>
<style name="DSub.TextViewStyle.Bold" parent="android:Widget.TextView">
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index be3e843d..9759e1c2 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -4,4 +4,6 @@
<dimen name="Button.Small">46dip</dimen>
<dimen name="AlbumArt.Small">78dip</dimen>
<dimen name="AlbumArt.Header">120dip</dimen>
+ <dimen name="BottomBar.Text.Major">13sp</dimen>
+ <dimen name="BottomBar.Text.Minor">12sp</dimen>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8544c6e3..e6e19b4c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -79,6 +79,8 @@
<string name="main.songs_genres">@string/main.albums_genres</string>
<string name="main.back_confirm">Press back again to exit</string>
<string name="main.scan_complete">Completed scan of Server</string>
+ <string name="main.artist">Artist</string>
+ <string name="main.title">Title</string>
<string name="menu.search">Search</string>
<string name="menu.shuffle">Shuffle</string>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 43271afd..061cfae7 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -23,6 +23,12 @@
<item name="android:layout_width">@dimen/Button.Small</item>
<item name="android:layout_height">@dimen/Button.Small</item>
</style>
+
+ <style name="PlaybackControl.Match" parent="@style/PlaybackControl">
+ <item name="android:padding">4dip</item>
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:layout_width">wrap_content</item>
+ </style>
<style name="MenuBarButton" parent="@style/BasicButton">
<item name="android:layout_width">0dip</item>
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 78a2c34d..50d2d171 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -76,6 +76,23 @@
<style name="Theme.DSub.Holo" parent="Theme.DSub.Dark">
<item name="android:windowBackground">@drawable/background</item>
</style>
+
+ <style name="Theme.DSub.Light.No_Actionbar" parent="Theme.DSub.Light">
+ <item name="windowActionBar">false</item>
+ <item name="windowNoTitle">true</item>
+ </style>
+ <style name="Theme.DSub.Black.No_Actionbar" parent="Theme.DSub.Black">
+ <item name="windowActionBar">false</item>
+ <item name="windowNoTitle">true</item>
+ </style>
+ <style name="Theme.DSub.Dark.No_Actionbar" parent="Theme.DSub.Dark">
+ <item name="windowActionBar">false</item>
+ <item name="windowNoTitle">true</item>
+ </style>
+ <style name="Theme.DSub.Holo.No_Actionbar" parent="Theme.DSub.Holo">
+ <item name="windowActionBar">false</item>
+ <item name="windowNoTitle">true</item>
+ </style>
<style name="Widget.DSub.ActionBarStyle.Light" parent="Widget.AppCompat.Light.ActionBar.Solid">
<item name="background">@android:color/transparent</item>