aboutsummaryrefslogtreecommitdiff
path: root/src/github/daneren2005
diff options
context:
space:
mode:
Diffstat (limited to 'src/github/daneren2005')
-rw-r--r--src/github/daneren2005/dsub/activity/SettingsActivity.java32
-rw-r--r--src/github/daneren2005/dsub/activity/SubsonicActivity.java27
-rw-r--r--src/github/daneren2005/dsub/fragments/MainFragment.java6
-rw-r--r--src/github/daneren2005/dsub/fragments/NowPlayingFragment.java2
-rw-r--r--src/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java6
-rw-r--r--src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java130
-rw-r--r--src/github/daneren2005/dsub/fragments/SubsonicFragment.java96
-rw-r--r--src/github/daneren2005/dsub/service/CachedMusicService.java47
-rw-r--r--src/github/daneren2005/dsub/service/DownloadService.java70
-rw-r--r--src/github/daneren2005/dsub/service/MusicService.java2
-rw-r--r--src/github/daneren2005/dsub/service/OfflineMusicService.java21
-rw-r--r--src/github/daneren2005/dsub/service/RESTMusicService.java33
-rw-r--r--src/github/daneren2005/dsub/util/Constants.java3
-rw-r--r--src/github/daneren2005/dsub/util/FileUtil.java20
-rw-r--r--src/github/daneren2005/dsub/util/tags/BastpUtil.java2
-rw-r--r--src/github/daneren2005/dsub/view/AlbumCell.java4
-rw-r--r--src/github/daneren2005/dsub/view/AlbumView.java4
-rw-r--r--src/github/daneren2005/dsub/view/ArtistEntryView.java4
-rw-r--r--src/github/daneren2005/dsub/view/ArtistView.java4
-rw-r--r--src/github/daneren2005/dsub/view/SeekBarPreference.java8
-rw-r--r--src/github/daneren2005/dsub/view/SongView.java4
21 files changed, 418 insertions, 107 deletions
diff --git a/src/github/daneren2005/dsub/activity/SettingsActivity.java b/src/github/daneren2005/dsub/activity/SettingsActivity.java
index c1618b7d..0dd68fcb 100644
--- a/src/github/daneren2005/dsub/activity/SettingsActivity.java
+++ b/src/github/daneren2005/dsub/activity/SettingsActivity.java
@@ -39,6 +39,10 @@ import android.preference.PreferenceScreen;
import android.text.InputType;
import android.util.Log;
import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.service.DownloadService;
@@ -55,6 +59,7 @@ import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
+import java.security.acl.Group;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
@@ -84,9 +89,11 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer
private CheckBoxPreference syncStarred;
private CheckBoxPreference syncMostRecent;
private CheckBoxPreference replayGain;
+ private ListPreference replayGainType;
private Preference replayGainBump;
private Preference replayGainUntagged;
private String internalSSID;
+ private String internalSSIDDisplay;
private int serverCount = 3;
private SharedPreferences settings;
@@ -102,7 +109,7 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer
if(internalSSID == null) {
internalSSID = "";
}
- internalSSID = this.getResources().getString(R.string.settings_server_local_network_ssid_hint, internalSSID);
+ internalSSIDDisplay = this.getResources().getString(R.string.settings_server_local_network_ssid_hint, internalSSID);
theme = (ListPreference) findPreference(Constants.PREFERENCES_KEY_THEME);
maxBitrateWifi = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_WIFI);
@@ -125,6 +132,7 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer
syncStarred = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SYNC_STARRED);
syncMostRecent = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_SYNC_MOST_RECENT);
replayGain = (CheckBoxPreference) findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN);
+ replayGainType = (ListPreference) findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN_TYPE);
replayGainBump = (Preference) findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN_BUMP);
replayGainUntagged = (Preference) findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN_UNTAGGED);
@@ -329,12 +337,15 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer
}
}
if(replayGain.isChecked()) {
+ replayGainType.setEnabled(true);
replayGainBump.setEnabled(true);
replayGainUntagged.setEnabled(true);
} else {
+ replayGainType.setEnabled(false);
replayGainBump.setEnabled(false);
replayGainUntagged.setEnabled(false);
}
+ replayGainType.setSummary(replayGainType.getEntry());
for (ServerSettings ss : serverSettings.values()) {
ss.update();
@@ -372,11 +383,26 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer
serverUrlPreference.setSummary(serverUrlPreference.getText());
screen.setSummary(serverUrlPreference.getText());
- final EditTextPreference serverLocalNetworkSSIDPreference = new EditTextPreference(this);
+ final EditTextPreference serverLocalNetworkSSIDPreference = new EditTextPreference(this) {
+ @Override
+ protected void onAddEditTextToDialogView(View dialogView, final EditText editText) {
+ super.onAddEditTextToDialogView(dialogView, editText);
+ ViewGroup root = (ViewGroup) ((ViewGroup) dialogView).getChildAt(0);
+
+ Button defaultButton = new Button(getContext());
+ defaultButton.setText(internalSSIDDisplay);
+ defaultButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ editText.setText(internalSSID);
+ }
+ });
+ root.addView(defaultButton);
+ }
+ };
serverLocalNetworkSSIDPreference.setKey(Constants.PREFERENCES_KEY_SERVER_LOCAL_NETWORK_SSID + instance);
serverLocalNetworkSSIDPreference.setTitle(R.string.settings_server_local_network_ssid);
serverLocalNetworkSSIDPreference.setDialogTitle(R.string.settings_server_local_network_ssid);
- serverLocalNetworkSSIDPreference.setDialogMessage(internalSSID);
final EditTextPreference serverInternalUrlPreference = new EditTextPreference(this);
serverInternalUrlPreference.setKey(Constants.PREFERENCES_KEY_SERVER_INTERNAL_URL + instance);
diff --git a/src/github/daneren2005/dsub/activity/SubsonicActivity.java b/src/github/daneren2005/dsub/activity/SubsonicActivity.java
index 6544b685..c3f8e4a7 100644
--- a/src/github/daneren2005/dsub/activity/SubsonicActivity.java
+++ b/src/github/daneren2005/dsub/activity/SubsonicActivity.java
@@ -45,6 +45,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
+import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
@@ -371,8 +372,10 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
@Override
public void setTitle(CharSequence title) {
- getSupportActionBar().setTitle(title);
- recreateSpinner();
+ if(!title.equals(getSupportActionBar().getTitle())) {
+ getSupportActionBar().setTitle(title);
+ recreateSpinner();
+ }
}
public void setSubtitle(CharSequence title) {
getSupportActionBar().setSubtitle(title);
@@ -495,7 +498,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
protected void exit() {
- if(this.getClass() != SubsonicFragmentActivity.class) {
+ if(((Object) this).getClass() != SubsonicFragmentActivity.class) {
Intent intent = new Intent(this, SubsonicFragmentActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(Constants.INTENT_EXTRA_NAME_EXIT, true);
@@ -542,6 +545,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
if(secondaryContainer == null) {
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(oldFragment);
trans.add(R.id.fragment_container, fragment, tag + "");
trans.commit();
@@ -555,12 +559,16 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
if(backStack.size() > 1) {
// Move old right to left if there is a backstack already
SubsonicFragment newLeftFragment = backStack.get(backStack.size() - 1);
+ if(replaceCurrent) {
+ // trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
+ }
trans.remove(newLeftFragment);
// Only move right to left if replaceCurrent is false
if(!replaceCurrent) {
SubsonicFragment oldLeftFragment = backStack.get(backStack.size() - 2);
oldLeftFragment.setSecondaryFragment(false);
+ // trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
trans.hide(oldLeftFragment);
// Make sure remove is finished before adding
@@ -568,6 +576,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
getSupportFragmentManager().executePendingTransactions();
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.add(R.id.fragment_container, newLeftFragment, newLeftFragment.getSupportTag() + "");
} else {
backStack.remove(backStack.size() - 1);
@@ -575,6 +584,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
// 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
@@ -594,6 +604,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
if(secondaryContainer == null) {
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
+ 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);
trans.show(currentFragment);
trans.commit();
@@ -601,10 +612,12 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
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);
// Only switch places if there is a backstack, otherwise primary container is correct
if(backStack.size() > 0) {
+ trans.setCustomAnimations(0, 0, 0, 0);
// Add current left fragment to right side
trans.remove(currentFragment);
@@ -613,12 +626,14 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
getSupportFragmentManager().executePendingTransactions();
trans = getSupportFragmentManager().beginTransaction();
+ // trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
trans.add(R.id.fragment_second_container, currentFragment, currentFragment.getSupportTag() + "");
SubsonicFragment newLeftFragment = backStack.get(backStack.size() - 1);
newLeftFragment.setSecondaryFragment(true);
trans.show(newLeftFragment);
} else {
+ secondaryContainer.startAnimation(AnimationUtils.loadAnimation(this, R.anim.exit_to_right));
secondaryContainer.setVisibility(View.GONE);
}
@@ -641,6 +656,10 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
protected void recreateSpinner() {
+ if(currentFragment == null || currentFragment.getTitle() == null) {
+ return;
+ }
+
if(backStack.size() > 0) {
spinnerAdapter.clear();
for(int i = 0; i < backStack.size(); i++) {
@@ -656,7 +675,7 @@ public class SubsonicActivity extends ActionBarActivity implements OnItemSelecte
}
protected void restart() {
- Intent intent = new Intent(this, this.getClass());
+ Intent intent = new Intent(this, ((Object) this).getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtras(getIntent());
Util.startActivityWithoutTransition(this, intent);
diff --git a/src/github/daneren2005/dsub/fragments/MainFragment.java b/src/github/daneren2005/dsub/fragments/MainFragment.java
index bbdc4de6..403bad03 100644
--- a/src/github/daneren2005/dsub/fragments/MainFragment.java
+++ b/src/github/daneren2005/dsub/fragments/MainFragment.java
@@ -264,7 +264,7 @@ public class MainFragment extends SubsonicFragment {
// Clear out recently added count when viewing
if("newest".equals(type)) {
SharedPreferences.Editor editor = Util.getPreferences(context).edit();
- editor.putInt(Constants.PREFERENCES_KEY_RECENT_COUNT, 0);
+ editor.putInt(Constants.PREFERENCES_KEY_RECENT_COUNT + Util.getActiveServer(context), 0);
editor.commit();
// Clear immediately so doesn't still show when pressing back
@@ -467,7 +467,7 @@ public class MainFragment extends SubsonicFragment {
private void getMostRecentCount() {
// Use stashed value until after refresh occurs
SharedPreferences prefs = Util.getPreferences(context);
- final int startCount = prefs.getInt(Constants.PREFERENCES_KEY_RECENT_COUNT, 0);
+ final int startCount = prefs.getInt(Constants.PREFERENCES_KEY_RECENT_COUNT + Util.getActiveServer(context), 0);
setMostRecentCount(startCount);
new SilentBackgroundTask<Integer>(context) {
@@ -506,7 +506,7 @@ public class MainFragment extends SubsonicFragment {
// Add the old count which will get cleared out after viewing recents
count += startCount;
SharedPreferences.Editor editor = Util.getPreferences(context).edit();
- editor.putInt(Constants.PREFERENCES_KEY_RECENT_COUNT, count);
+ editor.putInt(Constants.PREFERENCES_KEY_RECENT_COUNT + Util.getActiveServer(context), count);
editor.commit();
return count;
diff --git a/src/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/src/github/daneren2005/dsub/fragments/NowPlayingFragment.java
index a0da3b57..189e2a0c 100644
--- a/src/github/daneren2005/dsub/fragments/NowPlayingFragment.java
+++ b/src/github/daneren2005/dsub/fragments/NowPlayingFragment.java
@@ -627,7 +627,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
menu.findItem(R.id.menu_show_artist).setVisible(false);
}
- hideMenuItems(menu);
+ hideMenuItems(menu, (AdapterView.AdapterContextMenuInfo) menuInfo);
}
}
diff --git a/src/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java b/src/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java
index f9ab0cc9..c26429ce 100644
--- a/src/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java
+++ b/src/github/daneren2005/dsub/fragments/SelectBookmarkFragment.java
@@ -19,6 +19,7 @@
package github.daneren2005.dsub.fragments;
import android.content.DialogInterface;
+import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -29,6 +30,7 @@ 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.DownloadFile;
import github.daneren2005.dsub.service.DownloadService;
import github.daneren2005.dsub.service.MusicService;
import github.daneren2005.dsub.service.MusicServiceFactory;
@@ -39,6 +41,8 @@ import github.daneren2005.dsub.util.ProgressListener;
import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.Util;
import github.daneren2005.dsub.view.BookmarkAdapter;
+import github.daneren2005.dsub.view.SongView;
+
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Arrays;
@@ -53,6 +57,8 @@ public class SelectBookmarkFragment extends SelectListFragment<MusicDirectory.En
MenuInflater inflater = context.getMenuInflater();
inflater.inflate(R.menu.select_bookmark_context, menu);
+
+ hideMenuItems(menu, (AdapterView.AdapterContextMenuInfo) menuInfo);
}
@Override
diff --git a/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java b/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
index 824d4f33..d441267d 100644
--- a/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
+++ b/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
@@ -87,6 +87,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
boolean restoredInstance = false;
boolean lookupParent = false;
boolean largeAlbums = false;
+ boolean topTracks = false;
String lookupEntry;
public SelectDirectoryFragment() {
@@ -131,6 +132,8 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
refreshListing = args.getBoolean(Constants.INTENT_EXTRA_REFRESH_LISTINGS);
artist = args.getBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, false);
lookupEntry = args.getString(Constants.INTENT_EXTRA_SEARCH_SONG);
+ topTracks = args.getBoolean(Constants.INTENT_EXTRA_TOP_TRACKS);
+ showAll = args.getBoolean(Constants.INTENT_EXTRA_SHOW_ALL);
String childId = args.getString(Constants.INTENT_EXTRA_NAME_CHILD_ID);
if(childId != null) {
@@ -203,6 +206,10 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
menuInflater.inflate(R.menu.empty, menu);
} else {
menuInflater.inflate(R.menu.select_album, menu);
+
+ if(!ServerInfo.isMadsonic(context)) {
+ menu.removeItem(R.id.menu_top_tracks);
+ }
}
} else {
if(podcastId == null) {
@@ -258,9 +265,6 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
case R.id.menu_shuffle:
playNow(true, false);
return true;
- case R.id.menu_select:
- selectAllOrNone();
- return true;
case R.id.menu_download:
downloadBackground(false);
selectAll(false, false);
@@ -286,12 +290,14 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
downloadAllPodcastEpisodes();
return true;
case R.id.menu_show_all:
- showAll = true;
- refresh(true);
+ setShowAll();
return true;
case R.id.menu_unstar:
unstarSelected();
return true;
+ case R.id.menu_top_tracks:
+ showTopTracks();
+ return true;
}
return super.onOptionsItemSelected(item);
@@ -455,6 +461,8 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
} else {
if(showAll) {
getRecursiveMusicDirectory(id, name, refresh);
+ } else if(topTracks) {
+ getTopTracks(id, name, refresh);
} else {
getMusicDirectory(id, name, refresh);
}
@@ -471,6 +479,10 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
if(lookupParent && dir.getParent() != null) {
dir = getMusicDirectory(dir.getParent(), name, refresh, service, this);
+
+ // Update the fragment pointers so other stuff works correctly
+ SelectDirectoryFragment.this.id = dir.getId();
+ SelectDirectoryFragment.this.name = dir.getName();
}
return dir;
@@ -560,6 +572,17 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}.execute();
}
+ private void getTopTracks(final String id, final String name, final boolean refresh) {
+ setTitle(name);
+
+ new LoadTask() {
+ @Override
+ protected MusicDirectory load(MusicService service) throws Exception {
+ return service.getTopTrackSongs(name, 20, context, this);
+ }
+ }.execute();
+ }
+
private void getAlbumList(final String albumListType, final int size) {
showHeader = false;
@@ -615,22 +638,21 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
protected Pair<MusicDirectory, Boolean> doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
MusicDirectory dir = load(musicService);
- boolean valid = musicService.isLicenseValid(context, this);
- return new Pair<MusicDirectory, Boolean>(dir, valid);
+ licenseValid = musicService.isLicenseValid(context, this);
+
+ albums = dir.getChildren(true, false);
+ if(largeAlbums) {
+ entries = dir.getChildren(false, true);
+ } else {
+ entries = dir.getChildren();
+ }
+
+ return new Pair<MusicDirectory, Boolean>(dir, licenseValid);
}
@Override
protected void done(Pair<MusicDirectory, Boolean> result) {
- if(largeAlbums) {
- albums = result.getFirst().getChildren(true, false);
- entries = result.getFirst().getChildren(false, true);
- } else {
- albums = result.getFirst().getChildren(true, false);
- entries = result.getFirst().getChildren();
- }
- licenseValid = result.getSecond();
- finishLoading();
-
+ finishLoading();
currentTask = null;
}
}
@@ -646,7 +668,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
} else {
showHeader = false;
if(!"root".equals(id) && (entries.size() == 0 || !largeAlbums && albums.size() == entries.size())) {
- hideButtons = true;
+ hideButtons = true;
}
}
@@ -699,7 +721,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
if(validData) {
entryList.setVisibility(View.VISIBLE);
}
- context.supportInvalidateOptionsMenu();
+ context.supportInvalidateOptionsMenu();
if(lookupEntry != null) {
for(int i = 0; i < entries.size(); i++) {
@@ -711,12 +733,12 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
}
- Bundle args = getArguments();
- boolean playAll = args.getBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false);
- if (playAll && !restoredInstance) {
- playAll(args.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, false), false);
- }
- }
+ Bundle args = getArguments();
+ boolean playAll = args.getBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false);
+ if (playAll && !restoredInstance) {
+ playAll(args.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, false), false);
+ }
+ }
private void setupAlbumList() {
albumList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@@ -778,18 +800,6 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
}
- private void selectAllOrNone() {
- boolean someUnselected = false;
- int count = entryList.getCount();
- for (int i = 0; i < count; i++) {
- if (!entryList.isItemChecked(i) && entryList.getItemAtPosition(i) instanceof Entry) {
- someUnselected = true;
- break;
- }
- }
- selectAll(someUnselected, true);
- }
-
private void selectAll(boolean selected, boolean toast) {
int count = entryList.getCount();
int selectedCount = 0;
@@ -888,10 +898,11 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
private void downloadBackground(final boolean save) {
List<Entry> songs = getSelectedSongs();
if(songs.isEmpty()) {
- selectAll(true, false);
- songs = getSelectedSongs();
+ // Get both songs and albums
+ downloadRecursively(id, save, false, false, false, true);
+ } else {
+ downloadBackground(save, songs);
}
- downloadBackground(save, songs);
}
private void downloadBackground(final boolean save, final List<Entry> songs) {
if (getDownloadService() == null) {
@@ -920,6 +931,11 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
if(songs.isEmpty()) {
selectAll(true, false);
songs = getSelectedSongs();
+
+ // Also delete all directories
+ for(Entry album: albums) {
+ deleteRecursively(album);
+ }
}
if (getDownloadService() != null) {
getDownloadService().delete(songs);
@@ -1162,6 +1178,24 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
builder.create().show();
}
+ private void showTopTracks() {
+ SubsonicFragment fragment = new SelectDirectoryFragment();
+ Bundle args = new Bundle(getArguments());
+ args.putBoolean(Constants.INTENT_EXTRA_TOP_TRACKS, true);
+ fragment.setArguments(args);
+
+ replaceFragment(fragment, true);
+ }
+
+ private void setShowAll() {
+ SubsonicFragment fragment = new SelectDirectoryFragment();
+ Bundle args = new Bundle(getArguments());
+ args.putBoolean(Constants.INTENT_EXTRA_SHOW_ALL, true);
+ fragment.setArguments(args);
+
+ replaceFragment(fragment, true);
+ }
+
private View createHeader(List<Entry> entries) {
View header = entryList.findViewById(R.id.select_album_header);
boolean add = false;
@@ -1187,12 +1221,14 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
return;
}
- AlertDialog.Builder imageDialog = new AlertDialog.Builder(context);
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
ImageView fullScreenView = new ImageView(context);
imageLoader.loadImage(fullScreenView, albumRep, true, true);
- imageDialog.setView(fullScreenView);
- imageDialog.setCancelable(true);
- imageDialog.create();
+ builder.setCancelable(true);
+
+ AlertDialog imageDialog = builder.create();
+ // Set view here with unecessary 0's to remove top/bottom border
+ imageDialog.setView(fullScreenView, 0, 0, 0, 0);
imageDialog.show();
}
});
@@ -1253,6 +1289,12 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
}
});
+ } else if(topTracks) {
+ artistView.setText(R.string.menu_top_tracks);
+ artistView.setVisibility(View.VISIBLE);
+ } else if(showAll) {
+ artistView.setText(R.string.menu_show_all);
+ artistView.setVisibility(View.VISIBLE);
} else if (artists.size() == 1) {
String artistText = artists.iterator().next();
if(years.size() == 1) {
diff --git a/src/github/daneren2005/dsub/fragments/SubsonicFragment.java b/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
index cf6f78b0..68ca5189 100644
--- a/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
+++ b/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
@@ -40,6 +40,7 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
+import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
@@ -73,7 +74,12 @@ import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.LoadingTask;
import github.daneren2005.dsub.util.UserUtil;
import github.daneren2005.dsub.util.Util;
+import github.daneren2005.dsub.view.AlbumCell;
+import github.daneren2005.dsub.view.AlbumView;
+import github.daneren2005.dsub.view.ArtistEntryView;
+import github.daneren2005.dsub.view.ArtistView;
import github.daneren2005.dsub.view.PlaylistSongView;
+import github.daneren2005.dsub.view.SongView;
import github.daneren2005.dsub.view.UpdateView;
import java.io.File;
@@ -96,7 +102,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
private int tag;
protected SubsonicActivity context;
- protected CharSequence title = "DSub";
+ protected CharSequence title = null;
protected CharSequence subtitle = null;
protected View rootView;
protected boolean primaryFragment = false;
@@ -108,6 +114,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
protected boolean artist = false;
protected boolean artistOverride = false;
protected SwipeRefreshLayout refreshLayout;
+ protected boolean firstRun;
public SubsonicFragment() {
super();
@@ -124,6 +131,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
title = name;
}
}
+ firstRun = true;
}
@Override
@@ -135,7 +143,11 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
@Override
public void onResume() {
super.onResume();
- UpdateView.triggerUpdate();
+ if(firstRun) {
+ firstRun = false;
+ } else {
+ UpdateView.triggerUpdate();
+ }
}
@Override
@@ -168,7 +180,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo, Object selected) {
MenuInflater inflater = context.getMenuInflater();
-
+
if(selected instanceof Entry) {
Entry entry = (Entry) selected;
if(entry instanceof PodcastEpisode && !entry.isVideo()) {
@@ -227,10 +239,10 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
}
- hideMenuItems(menu);
+ hideMenuItems(menu, (AdapterView.AdapterContextMenuInfo) menuInfo);
}
- protected void hideMenuItems(ContextMenu menu) {
+ protected void hideMenuItems(ContextMenu menu, AdapterView.AdapterContextMenuInfo info) {
if(!ServerInfo.checkServerVersion(context, "1.8")) {
menu.setGroupVisible(R.id.server_1_8, false);
menu.setGroupVisible(R.id.hide_star, false);
@@ -258,6 +270,60 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
if(!prefs.getBoolean(Constants.PREFERENCES_KEY_MENU_RATING, true)) {
menu.setGroupVisible(R.id.hide_rating, false);
}
+
+ if(!Util.isOffline(context)) {
+ // If we are looking at a standard song view, get downloadFile to cache what options to show
+ if(info.targetView instanceof SongView) {
+ SongView songView = (SongView) info.targetView;
+ DownloadFile downloadFile = songView.getDownloadFile();
+
+ try {
+ if(downloadFile != null) {
+ if(downloadFile.isWorkDone()) {
+ // Remove permanent cache menu if already perma cached
+ 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 {
+ // Remove delete option if nothing to delete
+ menu.removeItem(R.id.song_menu_delete);
+ }
+ }
+ } catch(Exception e) {
+ Log.w(TAG, "Failed to lookup downloadFile info", e);
+ }
+ }
+ // Apply similar logic to album views
+ else if(info.targetView instanceof AlbumCell || info.targetView instanceof AlbumView
+ || info.targetView instanceof ArtistView || info.targetView instanceof ArtistEntryView) {
+ File folder = null;
+ int id = 0;
+ if(info.targetView instanceof AlbumCell) {
+ folder = ((AlbumCell) info.targetView).getFile();
+ id = R.id.album_menu_delete;
+ } else if(info.targetView instanceof AlbumView) {
+ folder = ((AlbumView) info.targetView).getFile();
+ id = R.id.album_menu_delete;
+ } else if(info.targetView instanceof ArtistView) {
+ folder = ((ArtistView) info.targetView).getFile();
+ id = R.id.artist_menu_delete;
+ } else if(info.targetView instanceof ArtistEntryView) {
+ folder = ((ArtistEntryView) info.targetView).getFile();
+ id = R.id.artist_menu_delete;
+ }
+
+ try {
+ if(folder != null && !folder.exists()) {
+ menu.removeItem(id);
+ }
+ } catch(Exception e) {
+ Log.w(TAG, "Failed to lookup album directory info", e);
+ }
+ }
+ }
}
protected void recreateContextMenu(ContextMenu menu) {
@@ -420,7 +486,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
public void setPrimaryFragment(boolean primary) {
primaryFragment = primary;
if(primary) {
- if(context != null) {
+ if(context != null && title != null) {
context.setTitle(title);
context.setSubtitle(subtitle);
}
@@ -464,7 +530,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
protected void exit() {
- if(context.getClass() != SubsonicFragmentActivity.class) {
+ if(((Object) context).getClass() != SubsonicFragmentActivity.class) {
Intent intent = new Intent(context, SubsonicFragmentActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(Constants.INTENT_EXTRA_NAME_EXIT, true);
@@ -1112,6 +1178,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
public void displaySongInfo(final Entry song) {
+ Integer duration = null;
Integer bitrate = null;
String format = null;
long size = 0;
@@ -1122,10 +1189,21 @@ 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_BITRATE);
- bitrate = Integer.parseInt((tmp != null) ? tmp : "0") / 1000;
+
+ 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);
+ bitrate = Integer.parseInt((tmp != null) ? tmp : "0") / 1000;
+ } else {
+ // Otherwise do a calculation for it
+ // Divide by 1000 so in kbps
+ bitrate = (int) (size / duration) / 1000 * 8;
+ }
if(Util.isOffline(context)) {
song.setGenre(metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE));
diff --git a/src/github/daneren2005/dsub/service/CachedMusicService.java b/src/github/daneren2005/dsub/service/CachedMusicService.java
index 59ed550c..8e8e120d 100644
--- a/src/github/daneren2005/dsub/service/CachedMusicService.java
+++ b/src/github/daneren2005/dsub/service/CachedMusicService.java
@@ -156,14 +156,17 @@ public class CachedMusicService implements MusicService {
@Override
public MusicDirectory getMusicDirectory(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
MusicDirectory dir = null;
-
+ MusicDirectory cached = FileUtil.deserialize(context, getCacheName(context, "directory", id), MusicDirectory.class);
if(!refresh) {
- dir = FileUtil.deserialize(context, getCacheName(context, "directory", id), MusicDirectory.class);
+ dir = cached;
}
if(dir == null) {
dir = musicService.getMusicDirectory(id, name, refresh, context, progressListener);
FileUtil.serialize(context, dir, getCacheName(context, "directory", id));
+
+ // If a cached copy exists to check against, look for removes
+ deleteRemovedEntries(context, dir, cached);
}
return dir;
@@ -172,14 +175,17 @@ public class CachedMusicService implements MusicService {
@Override
public MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
MusicDirectory dir = null;
-
+ MusicDirectory cached = FileUtil.deserialize(context, getCacheName(context, "artist", id), MusicDirectory.class);
if(!refresh) {
- dir = FileUtil.deserialize(context, getCacheName(context, "artist", id), MusicDirectory.class);
+ dir = cached;
}
if(dir == null) {
dir = musicService.getArtist(id, name, refresh, context, progressListener);
FileUtil.serialize(context, dir, getCacheName(context, "artist", id));
+
+ // If a cached copy exists to check against, look for removes
+ deleteRemovedEntries(context, dir, cached);
}
return dir;
@@ -188,14 +194,17 @@ public class CachedMusicService implements MusicService {
@Override
public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception {
MusicDirectory dir = null;
-
+ MusicDirectory cached = FileUtil.deserialize(context, getCacheName(context, "album", id), MusicDirectory.class);
if(!refresh) {
- dir = FileUtil.deserialize(context, getCacheName(context, "album", id), MusicDirectory.class);
+ dir = cached;
}
if(dir == null) {
dir = musicService.getAlbum(id, name, refresh, context, progressListener);
FileUtil.serialize(context, dir, getCacheName(context, "album", id));
+
+ // If a cached copy exists to check against, look for removes
+ deleteRemovedEntries(context, dir, cached);
}
return dir;
@@ -626,7 +635,12 @@ public class CachedMusicService implements MusicService {
public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception {
return musicService.getSongsByGenre(genre, count, offset, context, progressListener);
}
-
+
+ @Override
+ public MusicDirectory getTopTrackSongs(String artist, int size, Context context, ProgressListener progressListener) throws Exception {
+ return musicService.getTopTrackSongs(artist, size, context, progressListener);
+ }
+
@Override
public List<PodcastChannel> getPodcastChannels(boolean refresh, Context context, ProgressListener progressListener) throws Exception {
checkSettingsChanged(context);
@@ -894,6 +908,25 @@ public class CachedMusicService implements MusicService {
String s = musicService.getRestUrl(context, null, false);
return name + "-" + s.hashCode() + ".ser";
}
+
+ private void deleteRemovedEntries(Context context, MusicDirectory dir, MusicDirectory cached) {
+ if(cached != null) {
+ List<Entry> oldList = new ArrayList<Entry>();
+ oldList.addAll(cached.getChildren());
+
+ // Remove all current items from old list
+ for(Entry entry: dir.getChildren()) {
+ oldList.remove(entry);
+ }
+
+ // Anything remaining has been removed from server
+ MediaStoreService store = new MediaStoreService(context);
+ for(Entry entry: oldList) {
+ File file = FileUtil.getEntryFile(context, entry);
+ Util.recursiveDelete(file, store);
+ }
+ }
+ }
private abstract class SerializeUpdater<T> {
final Context context;
diff --git a/src/github/daneren2005/dsub/service/DownloadService.java b/src/github/daneren2005/dsub/service/DownloadService.java
index 9a803f53..e6ffbd32 100644
--- a/src/github/daneren2005/dsub/service/DownloadService.java
+++ b/src/github/daneren2005/dsub/service/DownloadService.java
@@ -98,6 +98,7 @@ public class DownloadService extends Service {
public static final int FAST_FORWARD = 30000;
public static final int REWIND = 10000;
private static final double DELETE_CUTOFF = 0.84;
+ private static final int REQUIRED_ALBUM_MATCHES = 4;
private RemoteControlClientHelper mRemoteControl;
@@ -138,8 +139,6 @@ public class DownloadService extends Service {
private int cachedPosition = 0;
private boolean downloadOngoing = false;
private float volume = 1.0f;
- private boolean singleAlbum = false;
- private String singleAlbumName;
private AudioEffectsController effectsController;
private RemoteControlState remoteState = RemoteControlState.LOCAL;
@@ -362,20 +361,6 @@ public class DownloadService extends Service {
} else {
downloadList.add(offset, file);
}
-
- // Check if we are still dealing with a single album
- // Don't bother with check if it is already false
- if(singleAlbum) {
- // If first download, set album to it
- if(singleAlbumName == null) {
- singleAlbumName = file.getSong().getAlbum();
- } else {
- // Otherwise, check again previous album name
- if(!singleAlbumName.equals(file.getSong().getAlbum())) {
- singleAlbum = false;
- }
- }
- }
}
public synchronized void downloadBackground(List<MusicDirectory.Entry> songs, boolean save) {
for (MusicDirectory.Entry song : songs) {
@@ -639,8 +624,6 @@ public class DownloadService extends Service {
suggestedPlaylistName = null;
suggestedPlaylistId = null;
- singleAlbum = true;
- singleAlbumName = null;
}
public synchronized void remove(int which) {
@@ -1444,7 +1427,7 @@ public class DownloadService extends Service {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
String dataSource = file.getAbsolutePath();
- if(isPartial) {
+ if(isPartial && !Util.isOffline(this)) {
if (proxy == null) {
proxy = new BufferProxy(this);
proxy.start();
@@ -1855,7 +1838,6 @@ public class DownloadService extends Service {
}
}
currentPlayingIndex = downloadList.indexOf(currentPlaying);
- singleAlbum = false;
if (revisionBefore != revision) {
updateJukeboxPlaylist();
@@ -2006,6 +1988,49 @@ public class DownloadService extends Service {
float[] rg = BastpUtil.getReplayGainValues(downloadFile.getFile().getCanonicalPath()); /* track, album */
float adjust = 0f;
if (prefs.getBoolean(Constants.PREFERENCES_KEY_REPLAY_GAIN, false)) {
+ boolean singleAlbum = false;
+
+ String replayGainType = prefs.getString(Constants.PREFERENCES_KEY_REPLAY_GAIN_TYPE, "1");
+ // 1 => Smart replay gain
+ if("1".equals(replayGainType)) {
+ // Check if part of at least <REQUIRED_ALBUM_MATCHES> consequetive songs of the same album
+
+ int index = downloadList.indexOf(downloadFile);
+ if(index != -1) {
+ String albumName = downloadFile.getSong().getAlbum();
+ int matched = 0;
+
+ // Check forwards
+ for(int i = index + 1; i < downloadList.size() && matched < REQUIRED_ALBUM_MATCHES; i++) {
+ if(albumName.equals(downloadList.get(i).getSong().getAlbum())) {
+ matched++;
+ } else {
+ break;
+ }
+ }
+
+ // Check backwards
+ for(int i = index - 1; i >= 0 && matched < REQUIRED_ALBUM_MATCHES; i--) {
+ if(albumName.equals(downloadList.get(i).getSong().getAlbum())) {
+ matched++;
+ } else {
+ break;
+ }
+ }
+
+ if(matched >= REQUIRED_ALBUM_MATCHES) {
+ singleAlbum = true;
+ }
+ }
+ }
+ // 2 => Use album tags
+ else if("2".equals(replayGainType)) {
+ singleAlbum = true;
+ }
+ // 3 => Use track tags
+ // Already false, no need to do anything here
+
+
// If playing a single album or no track gain, use album gain
if((singleAlbum || rg[0] == 0) && rg[1] != 0) {
adjust = rg[1];
@@ -2019,10 +2044,7 @@ public class DownloadService extends Service {
int untagged = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_REPLAY_GAIN_UNTAGGED, "0"));
adjust = (untagged - 150) / 10f;
} else {
- /* This song has some replay gain info, we are now going to apply the 'bump' value
- ** The preferences stores the raw value of the seekbar, that's 0-150
- ** But we want -15 <-> +15, so 75 shall be zero */
- int bump = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_REPLAY_GAIN_BUMP, "0"));
+ int bump = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_REPLAY_GAIN_BUMP, "150"));
adjust += (bump - 150) / 10f;
}
}
diff --git a/src/github/daneren2005/dsub/service/MusicService.java b/src/github/daneren2005/dsub/service/MusicService.java
index 3f07e9f5..765f498a 100644
--- a/src/github/daneren2005/dsub/service/MusicService.java
+++ b/src/github/daneren2005/dsub/service/MusicService.java
@@ -137,6 +137,8 @@ public interface MusicService {
List<Genre> getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception;
+
+ MusicDirectory getTopTrackSongs(String artist, int size, Context context, ProgressListener progressListener) throws Exception;
List<PodcastChannel> getPodcastChannels(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
diff --git a/src/github/daneren2005/dsub/service/OfflineMusicService.java b/src/github/daneren2005/dsub/service/OfflineMusicService.java
index 7dd2631f..c26a2fc4 100644
--- a/src/github/daneren2005/dsub/service/OfflineMusicService.java
+++ b/src/github/daneren2005/dsub/service/OfflineMusicService.java
@@ -428,12 +428,20 @@ public class OfflineMusicService implements MusicService {
if(!"#EXTM3U".equals(line)) return playlist;
while( (line = buffer.readLine()) != null ){
+ // No matter what, end file can't have .complete in it
+ line = line.replace(".complete", "");
File entryFile = new File(line);
- if(!entryFile.exists()) {
- entryFile = new File(line.replace(".complete", ""));
+
+ // Don't add file to playlist if it doesn't exist as cached or pinned!
+ File checkFile = entryFile;
+ if(!checkFile.exists()) {
+ // If normal file doens't exist, check if .complete version does
+ checkFile = new File(entryFile.getParent(), FileUtil.getBaseName(entryFile.getName())
+ + ".complete." + FileUtil.getExtension(entryFile.getName()));
}
+
String entryName = getName(entryFile);
- if(entryFile.exists() && entryName != null){
+ if(checkFile.exists() && entryName != null){
playlist.addChild(createEntry(context, entryFile, entryName, false));
}
}
@@ -628,7 +636,12 @@ public class OfflineMusicService implements MusicService {
throw new OfflineException(ERRORMSG);
}
- @Override
+ @Override
+ public MusicDirectory getTopTrackSongs(String artist, int size, Context context, ProgressListener progressListener) throws Exception {
+ throw new OfflineException(ERRORMSG);
+ }
+
+ @Override
public MusicDirectory getRandomSongs(int size, String folder, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception {
File root = FileUtil.getMusicDirectory(context);
List<File> children = new LinkedList<File>();
diff --git a/src/github/daneren2005/dsub/service/RESTMusicService.java b/src/github/daneren2005/dsub/service/RESTMusicService.java
index f4571ac1..db1504f0 100644
--- a/src/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/src/github/daneren2005/dsub/service/RESTMusicService.java
@@ -636,6 +636,12 @@ public class RESTMusicService implements MusicService {
}
byte[] bytes = Util.toByteArray(in);
+
+ // Handle case where partial was downloaded before being cancelled
+ if(task != null && task.isCancelled()) {
+ return null;
+ }
+
OutputStream out = null;
try {
out = new FileOutputStream(FileUtil.getAlbumArtFile(context, entry));
@@ -1040,7 +1046,25 @@ public class RESTMusicService implements MusicService {
Util.close(reader);
}
}
-
+
+ @Override
+ public MusicDirectory getTopTrackSongs(String artist, int size, Context context, ProgressListener progressListener) throws Exception {
+ List<String> parameterNames = new ArrayList<String>();
+ List<Object> parameterValues = new ArrayList<Object>();
+
+ parameterNames.add("artist");
+ parameterValues.add(artist);
+ parameterNames.add("size");
+ parameterValues.add(size);
+
+ Reader reader = getReader(context, progressListener, "getTopTrackSongs", null, parameterNames, parameterValues);
+ try {
+ return new RandomSongsParser(context, getInstance(context)).parse(reader, progressListener);
+ } finally {
+ Util.close(reader);
+ }
+ }
+
@Override
public List<PodcastChannel> getPodcastChannels(boolean refresh, Context context, ProgressListener progressListener) throws Exception {
checkServerVersion(context, "1.6", "Podcasts not supported.");
@@ -1333,6 +1357,11 @@ public class RESTMusicService implements MusicService {
}
byte[] bytes = Util.toByteArray(in);
+ if(task != null && task.isCancelled()) {
+ // Handle case where partial is downloaded and cancelled
+ return null;
+ }
+
OutputStream out = null;
try {
out = new FileOutputStream(FileUtil.getAvatarFile(context, username));
@@ -1341,7 +1370,7 @@ public class RESTMusicService implements MusicService {
Util.close(out);
}
- return FileUtil.getSampledBitmap(bytes, size);
+ return FileUtil.getSampledBitmap(bytes, size, false);
}
finally {
Util.close(in);
diff --git a/src/github/daneren2005/dsub/util/Constants.java b/src/github/daneren2005/dsub/util/Constants.java
index 30dc33b4..50651a80 100644
--- a/src/github/daneren2005/dsub/util/Constants.java
+++ b/src/github/daneren2005/dsub/util/Constants.java
@@ -63,6 +63,8 @@ public final class Constants {
public static final String INTENT_EXTRA_FRAGMENT_TYPE = "fragmentType";
public static final String INTENT_EXTRA_REFRESH_LISTINGS = "refreshListings";
public static final String INTENT_EXTRA_SEARCH_SONG = "searchSong";
+ public static final String INTENT_EXTRA_TOP_TRACKS = "topTracks";
+ public static final String INTENT_EXTRA_SHOW_ALL = "showAll";
// Preferences keys.
public static final String PREFERENCES_KEY_SERVER_KEY = "server";
@@ -147,6 +149,7 @@ public final class Constants {
public static final String PREFERENCES_KEY_REPLAY_GAIN = "replayGain";
public static final String PREFERENCES_KEY_REPLAY_GAIN_BUMP = "replayGainBump2";
public static final String PREFERENCES_KEY_REPLAY_GAIN_UNTAGGED = "replayGainUntagged2";
+ public static final String PREFERENCES_KEY_REPLAY_GAIN_TYPE= "replayGainType";
public static final String OFFLINE_SCROBBLE_COUNT = "scrobbleCount";
public static final String OFFLINE_SCROBBLE_ID = "scrobbleID";
diff --git a/src/github/daneren2005/dsub/util/FileUtil.java b/src/github/daneren2005/dsub/util/FileUtil.java
index 9433043c..54888b59 100644
--- a/src/github/daneren2005/dsub/util/FileUtil.java
+++ b/src/github/daneren2005/dsub/util/FileUtil.java
@@ -105,6 +105,14 @@ public class FileUtil {
return null;
}
+
+ public static File getEntryFile(Context context, MusicDirectory.Entry entry) {
+ if(entry.isDirectory()) {
+ return getAlbumDirectory(context, entry);
+ } else {
+ return getSongFile(context, entry);
+ }
+ }
public static File getSongFile(Context context, MusicDirectory.Entry song) {
File dir = getAlbumDirectory(context, song);
@@ -237,12 +245,15 @@ public class FileUtil {
opt.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(avatarFile.getPath(), opt);
- return bitmap == null ? null : getScaledBitmap(bitmap, size);
+ return bitmap == null ? null : getScaledBitmap(bitmap, size, false);
}
return null;
}
public static Bitmap getSampledBitmap(byte[] bytes, int size) {
+ return getSampledBitmap(bytes, size, true);
+ }
+ public static Bitmap getSampledBitmap(byte[] bytes, int size, boolean allowUnscaled) {
final BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt);
@@ -253,13 +264,16 @@ public class FileUtil {
if(bitmap == null) {
return null;
} else {
- return getScaledBitmap(bitmap, size);
+ return getScaledBitmap(bitmap, size, allowUnscaled);
}
}
public static Bitmap getScaledBitmap(Bitmap bitmap, int size) {
+ return getScaledBitmap(bitmap, size, true);
+ }
+ public static Bitmap getScaledBitmap(Bitmap bitmap, int size, boolean allowUnscaled) {
// Don't waste time scaling if the difference is minor
// Large album arts still need to be scaled since displayed as is on now playing!
- if(size < 400 && bitmap.getWidth() < (size * 1.1)) {
+ if(allowUnscaled && size < 400 && bitmap.getWidth() < (size * 1.1)) {
return bitmap;
} else {
return Bitmap.createScaledBitmap(bitmap, size, Util.getScaledHeight(bitmap, size), true);
diff --git a/src/github/daneren2005/dsub/util/tags/BastpUtil.java b/src/github/daneren2005/dsub/util/tags/BastpUtil.java
index a738bbce..7ff517fd 100644
--- a/src/github/daneren2005/dsub/util/tags/BastpUtil.java
+++ b/src/github/daneren2005/dsub/util/tags/BastpUtil.java
@@ -17,7 +17,7 @@
package github.daneren2005.dsub.util.tags;
-import android.util.LruCache;
+import android.support.v4.util.LruCache;
import java.util.HashMap;
import java.util.Vector;
diff --git a/src/github/daneren2005/dsub/view/AlbumCell.java b/src/github/daneren2005/dsub/view/AlbumCell.java
index d6a18205..110456e7 100644
--- a/src/github/daneren2005/dsub/view/AlbumCell.java
+++ b/src/github/daneren2005/dsub/view/AlbumCell.java
@@ -101,4 +101,8 @@ public class AlbumCell extends UpdateView {
public MusicDirectory.Entry getEntry() {
return album;
}
+
+ public File getFile() {
+ return file;
+ }
}
diff --git a/src/github/daneren2005/dsub/view/AlbumView.java b/src/github/daneren2005/dsub/view/AlbumView.java
index 7785a8af..70c1e049 100644
--- a/src/github/daneren2005/dsub/view/AlbumView.java
+++ b/src/github/daneren2005/dsub/view/AlbumView.java
@@ -100,4 +100,8 @@ public class AlbumView extends UpdateView {
public MusicDirectory.Entry getEntry() {
return album;
}
+
+ public File getFile() {
+ return file;
+ }
}
diff --git a/src/github/daneren2005/dsub/view/ArtistEntryView.java b/src/github/daneren2005/dsub/view/ArtistEntryView.java
index 86fe7b1f..157b25a9 100644
--- a/src/github/daneren2005/dsub/view/ArtistEntryView.java
+++ b/src/github/daneren2005/dsub/view/ArtistEntryView.java
@@ -72,4 +72,8 @@ public class ArtistEntryView extends UpdateView {
exists = file.exists();
isStarred = artist.isStarred();
}
+
+ public File getFile() {
+ return file;
+ }
}
diff --git a/src/github/daneren2005/dsub/view/ArtistView.java b/src/github/daneren2005/dsub/view/ArtistView.java
index 23ce4f9d..b8a87c20 100644
--- a/src/github/daneren2005/dsub/view/ArtistView.java
+++ b/src/github/daneren2005/dsub/view/ArtistView.java
@@ -71,4 +71,8 @@ public class ArtistView extends UpdateView {
exists = file.exists();
isStarred = artist.isStarred();
}
+
+ public File getFile() {
+ return file;
+ }
}
diff --git a/src/github/daneren2005/dsub/view/SeekBarPreference.java b/src/github/daneren2005/dsub/view/SeekBarPreference.java
index dedea908..e96d76f8 100644
--- a/src/github/daneren2005/dsub/view/SeekBarPreference.java
+++ b/src/github/daneren2005/dsub/view/SeekBarPreference.java
@@ -98,8 +98,12 @@ public class SeekBarPreference extends DialogPreference implements SeekBar.OnSee
* @return A string representation of the threshold.
*/
private String getSummary(String value) {
- int val = Integer.parseInt(value);
- return String.format(mDisplay, (val + mMin) / mStepSize);
+ try {
+ int val = Integer.parseInt(value);
+ return String.format(mDisplay, (val + mMin) / mStepSize);
+ } catch (Exception e) {
+ return "";
+ }
}
@Override
diff --git a/src/github/daneren2005/dsub/view/SongView.java b/src/github/daneren2005/dsub/view/SongView.java
index f795cbce..0fe19944 100644
--- a/src/github/daneren2005/dsub/view/SongView.java
+++ b/src/github/daneren2005/dsub/view/SongView.java
@@ -161,6 +161,10 @@ public class SongView extends UpdateView implements Checkable {
dontChangeDownloadFile = true;
}
+ public DownloadFile getDownloadFile() {
+ return downloadFile;
+ }
+
@Override
protected void updateBackground() {
if (downloadService == null) {