aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/github/daneren2005/dsub/domain/Artist.java67
-rw-r--r--src/github/daneren2005/dsub/domain/Indexes.java15
-rw-r--r--src/github/daneren2005/dsub/domain/MusicDirectory.java9
-rw-r--r--src/github/daneren2005/dsub/fragments/MainFragment.java5
-rw-r--r--src/github/daneren2005/dsub/fragments/NowPlayingFragment.java78
-rw-r--r--src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java145
-rw-r--r--src/github/daneren2005/dsub/fragments/SubsonicFragment.java159
-rw-r--r--src/github/daneren2005/dsub/service/CachedMusicService.java160
-rw-r--r--src/github/daneren2005/dsub/service/DownloadService.java14
-rw-r--r--src/github/daneren2005/dsub/service/MediaStoreService.java9
-rw-r--r--src/github/daneren2005/dsub/service/OfflineMusicService.java37
-rw-r--r--src/github/daneren2005/dsub/service/RESTMusicService.java41
-rw-r--r--src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java2
-rw-r--r--src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java4
-rw-r--r--src/github/daneren2005/dsub/service/sync/MostRecentSyncAdapter.java4
-rw-r--r--src/github/daneren2005/dsub/util/Constants.java4
-rw-r--r--src/github/daneren2005/dsub/util/FileUtil.java43
-rw-r--r--src/github/daneren2005/dsub/util/ImageLoader.java2
-rw-r--r--src/github/daneren2005/dsub/view/AlbumCell.java8
-rw-r--r--src/github/daneren2005/dsub/view/AlbumView.java7
-rw-r--r--src/github/daneren2005/dsub/view/DownloadFileAdapter.java1
-rw-r--r--src/github/daneren2005/dsub/view/SongView.java40
-rw-r--r--src/github/daneren2005/dsub/view/UpdateView.java31
23 files changed, 684 insertions, 201 deletions
diff --git a/src/github/daneren2005/dsub/domain/Artist.java b/src/github/daneren2005/dsub/domain/Artist.java
index e4a9001b..f30147e6 100644
--- a/src/github/daneren2005/dsub/domain/Artist.java
+++ b/src/github/daneren2005/dsub/domain/Artist.java
@@ -18,12 +18,18 @@
*/
package github.daneren2005.dsub.domain;
+import android.util.Log;
+
import java.io.Serializable;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
* @author Sindre Mehus
*/
public class Artist implements Serializable {
+ private static final String TAG = Artist.class.getSimpleName();
private String id;
private String name;
@@ -71,8 +77,69 @@ public class Artist implements Serializable {
this.closeness = closeness;
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Artist entry = (Artist) o;
+ return id.equals(entry.id);
+ }
+
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
@Override
public String toString() {
return name;
}
+
+ public static class ArtistComparator implements Comparator<Artist> {
+ private String[] ignoredArticles;
+
+ public ArtistComparator(String[] ignoredArticles) {
+ this.ignoredArticles = ignoredArticles;
+ }
+
+ public int compare(Artist lhsArtist, Artist rhsArtist) {
+ String lhs = lhsArtist.getName().toLowerCase();
+ String rhs = rhsArtist.getName().toLowerCase();
+
+ char lhs1 = lhs.charAt(0);
+ char rhs1 = rhs.charAt(0);
+
+ if (Character.isDigit(lhs1) && !Character.isDigit(rhs1)) {
+ return 1;
+ } else if (Character.isDigit(rhs1) && !Character.isDigit(lhs1)) {
+ return -1;
+ }
+
+ for (String article : ignoredArticles) {
+ int index = lhs.indexOf(article.toLowerCase() + " ");
+ if (index == 0) {
+ lhs = lhs.substring(article.length() + 1);
+ }
+ index = rhs.indexOf(article.toLowerCase() + " ");
+ if (index == 0) {
+ rhs = rhs.substring(article.length() + 1);
+ }
+ }
+
+ return lhs.compareTo(rhs);
+ }
+ }
+
+ public static void sort(List<Artist> artists, String[] ignoredArticles) {
+ try {
+ Collections.sort(artists, new ArtistComparator(ignoredArticles));
+ } catch (Exception e) {
+ Log.w(TAG, "Failed to sort artists", e);
+ }
+ }
} \ No newline at end of file
diff --git a/src/github/daneren2005/dsub/domain/Indexes.java b/src/github/daneren2005/dsub/domain/Indexes.java
index 63c3a8d4..e15ccf9f 100644
--- a/src/github/daneren2005/dsub/domain/Indexes.java
+++ b/src/github/daneren2005/dsub/domain/Indexes.java
@@ -18,10 +18,16 @@
*/
package github.daneren2005.dsub.domain;
+import android.content.Context;
+import android.content.SharedPreferences;
+
import java.util.ArrayList;
import java.util.List;
import java.io.Serializable;
+import github.daneren2005.dsub.util.Constants;
+import github.daneren2005.dsub.util.Util;
+
/**
* @author Sindre Mehus
*/
@@ -76,4 +82,13 @@ public class Indexes implements Serializable {
public List<MusicDirectory.Entry> getEntries() {
return entries;
}
+
+ public void sortChildren(Context context) {
+ SharedPreferences prefs = Util.getPreferences(context);
+ String ignoredArticlesString = prefs.getString(Constants.CACHE_KEY_IGNORE, "The El La Los Las Le Les");
+ final String[] ignoredArticles = ignoredArticlesString.split(" ");
+
+ Artist.sort(shortcuts, ignoredArticles);
+ Artist.sort(artists, ignoredArticles);
+ }
} \ No newline at end of file
diff --git a/src/github/daneren2005/dsub/domain/MusicDirectory.java b/src/github/daneren2005/dsub/domain/MusicDirectory.java
index edcbe77d..c7e00719 100644
--- a/src/github/daneren2005/dsub/domain/MusicDirectory.java
+++ b/src/github/daneren2005/dsub/domain/MusicDirectory.java
@@ -18,6 +18,7 @@
*/
package github.daneren2005.dsub.domain;
+import android.content.Context;
import android.media.MediaMetadataRetriever;
import android.util.Log;
import java.util.ArrayList;
@@ -27,6 +28,9 @@ import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
+import github.daneren2005.dsub.util.Constants;
+import github.daneren2005.dsub.util.Util;
+
/**
* @author Sindre Mehus
*/
@@ -102,6 +106,11 @@ public class MusicDirectory implements Serializable {
return children.size();
}
+ public void sortChildren(Context context, int instance) {
+ if(ServerInfo.checkServerVersion(context, "1.8", instance)) {
+ sortChildren(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_CUSTOM_SORT_ENABLED, true));
+ }
+ }
public void sortChildren(boolean byYear) {
EntryComparator.sort(children, byYear);
}
diff --git a/src/github/daneren2005/dsub/fragments/MainFragment.java b/src/github/daneren2005/dsub/fragments/MainFragment.java
index b1320f3f..bbdc4de6 100644
--- a/src/github/daneren2005/dsub/fragments/MainFragment.java
+++ b/src/github/daneren2005/dsub/fragments/MainFragment.java
@@ -493,6 +493,11 @@ public class MainFragment extends SubsonicFragment {
count++;
}
}
+
+ // Keep recents list from growing infinitely
+ while(recents.size() > 40) {
+ recents.remove(0);
+ }
FileUtil.serialize(context, recents, recentAddedFile);
if(firstRun) {
diff --git a/src/github/daneren2005/dsub/fragments/NowPlayingFragment.java b/src/github/daneren2005/dsub/fragments/NowPlayingFragment.java
index 6c2ad126..a957c7f3 100644
--- a/src/github/daneren2005/dsub/fragments/NowPlayingFragment.java
+++ b/src/github/daneren2005/dsub/fragments/NowPlayingFragment.java
@@ -31,6 +31,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.MediaRouteButton;
+import android.util.Log;
import android.view.ContextMenu;
import android.view.Display;
import android.view.GestureDetector;
@@ -61,6 +62,8 @@ import github.daneren2005.dsub.service.DownloadFile;
import github.daneren2005.dsub.service.DownloadService;
import github.daneren2005.dsub.service.MusicService;
import github.daneren2005.dsub.service.MusicServiceFactory;
+import github.daneren2005.dsub.service.OfflineException;
+import github.daneren2005.dsub.service.ServerTooOldException;
import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.view.DownloadFileAdapter;
@@ -191,9 +194,13 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
public void onClick(View v) {
DownloadFile currentDownload = getDownloadService().getCurrentPlaying();
if (currentDownload != null) {
- Entry currentSong = currentDownload.getSong();
- toggleStarred(currentSong);
- starButton.setImageResource(currentSong.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
+ final Entry currentSong = currentDownload.getSong();
+ toggleStarred(currentSong, new OnStarChange() {
+ @Override
+ void starChange(boolean starred) {
+ starButton.setImageResource(currentSong.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
+ }
+ });
}
}
});
@@ -374,14 +381,18 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if(downloadService == null) {
return;
}
-
- Entry entry = downloadService.getCurrentPlaying().getSong();
+
+ DownloadFile downloadFile = downloadService.getCurrentPlaying();
+ if(downloadFile == null) {
+ return;
+ }
+ Entry entry = downloadFile.getSong();
// If rating == 1, already set so unset
if(entry.getRating() == 1) {
setRating(entry, 0);
- if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
rateBadButton.setImageResource(R.drawable.ic_action_rating_bad_dark);
} else {
rateBadButton.setImageResource(Util.getAttribute(context, R.attr.rating_bad));
@@ -395,7 +406,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
rateBadButton.setImageResource(R.drawable.ic_action_rating_bad_selected);
// Make sure good rating is blank
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
rateGoodButton.setImageResource(R.drawable.ic_action_rating_good_dark);
} else {
rateGoodButton.setImageResource(Util.getAttribute(context, R.attr.rating_good));
@@ -406,13 +417,22 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
rateGoodButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- Entry entry = getDownloadService().getCurrentPlaying().getSong();
+ DownloadService downloadService = getDownloadService();
+ if(downloadService == null) {
+ return;
+ }
+
+ DownloadFile downloadFile = downloadService.getCurrentPlaying();
+ if(downloadFile == null) {
+ return;
+ }
+ Entry entry = downloadFile.getSong();
// If rating == 5, already set so unset
if(entry.getRating() == 5) {
setRating(entry, 0);
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
rateGoodButton.setImageResource(R.drawable.ic_action_rating_good_dark);
} else {
rateGoodButton.setImageResource(Util.getAttribute(context, R.attr.rating_good));
@@ -423,7 +443,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
rateGoodButton.setImageResource(R.drawable.ic_action_rating_good_selected);
// Make sure bad rating is blank
- if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
rateBadButton.setImageResource(R.drawable.ic_action_rating_bad_dark);
} else {
rateBadButton.setImageResource(Util.getAttribute(context, R.attr.rating_bad));
@@ -768,6 +788,9 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
case R.id.menu_star:
toggleStarred(song.getSong());
return true;
+ case R.id.menu_rate:
+ setRating(song.getSong());
+ return true;
case R.id.menu_toggle_timer:
if(getDownloadService().getSleepTimer()) {
getDownloadService().stopSleepTimer();
@@ -1165,7 +1188,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
int badRating, goodRating, bookmark;
if(song.getRating() == 1) {
badRating = R.drawable.ic_action_rating_bad_selected;
- } else if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ } else if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
badRating = R.drawable.ic_action_rating_bad_dark;
} else {
badRating = Util.getAttribute(context, R.attr.rating_bad);
@@ -1174,7 +1197,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if(song.getRating() == 5) {
goodRating = R.drawable.ic_action_rating_good_selected;
- } else if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ } else if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
goodRating = R.drawable.ic_action_rating_good_dark;
} else {
goodRating = Util.getAttribute(context, R.attr.rating_good);
@@ -1183,7 +1206,7 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
if(song.getBookmark() != null) {
bookmark = R.drawable.ic_menu_bookmark_selected;
- } else if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+ } else if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
bookmark = R.drawable.ic_menu_bookmark_dark;
} else {
bookmark = Util.getAttribute(context, R.attr.bookmark);
@@ -1368,14 +1391,20 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis
dialog.show();
}
private void createBookmark(final DownloadFile currentDownload, final String comment) {
+ DownloadService downloadService = getDownloadService();
+ if(downloadService == null) {
+ return;
+ }
+
+ final Entry currentSong = currentDownload.getSong();
+ final int position = downloadService.getPlayerPosition();
+ final Bookmark oldBookmark = currentSong.getBookmark();
+ currentSong.setBookmark(new Bookmark(position));
+
new SilentBackgroundTask<Void>(context) {
@Override
protected Void doInBackground() throws Throwable {
- Entry currentSong = currentDownload.getSong();
MusicService musicService = MusicServiceFactory.getMusicService(context);
- int position = getDownloadService().getPlayerPosition();
-
- currentSong.setBookmark(new Bookmark(position));
musicService.createBookmark(currentSong, position, comment, context, null);
Entry find = UpdateView.findEntry(currentSong);
@@ -1391,6 +1420,21 @@ 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);
+
+ 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/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java b/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
index 9ea84d41..4acccad2 100644
--- a/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
+++ b/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
@@ -17,9 +17,11 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
+import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
+import android.widget.RatingBar;
import android.widget.TextView;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.domain.MusicDirectory;
@@ -51,6 +53,8 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+import static github.daneren2005.dsub.domain.MusicDirectory.Entry;
+
public class SelectDirectoryFragment extends SubsonicFragment implements AdapterView.OnItemClickListener {
private static final String TAG = SelectDirectoryFragment.class.getSimpleName();
@@ -60,14 +64,16 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
private Boolean licenseValid;
private boolean showHeader = true;
private EntryAdapter entryAdapter;
- private List<MusicDirectory.Entry> albums;
- private List<MusicDirectory.Entry> entries;
+ private List<Entry> albums;
+ private List<Entry> entries;
private boolean albumContext = false;
private boolean addAlbumHeader = false;
private LoadTask currentTask;
String id;
String name;
+ boolean starred;
+ int rating;
String playlistId;
String playlistName;
boolean playlistOwner;
@@ -92,8 +98,8 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
if(bundle != null) {
- entries = (List<MusicDirectory.Entry>) bundle.getSerializable(Constants.FRAGMENT_LIST);
- albums = (List<MusicDirectory.Entry>) bundle.getSerializable(Constants.FRAGMENT_LIST2);
+ entries = (List<Entry>) bundle.getSerializable(Constants.FRAGMENT_LIST);
+ albums = (List<Entry>) bundle.getSerializable(Constants.FRAGMENT_LIST2);
restoredInstance = true;
}
}
@@ -111,6 +117,8 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
if(args != null) {
id = args.getString(Constants.INTENT_EXTRA_NAME_ID);
name = args.getString(Constants.INTENT_EXTRA_NAME_NAME);
+ starred = args.getBoolean(Constants.INTENT_EXTRA_NAME_STARRED, false);
+ rating = args.getInt(Constants.INTENT_EXTRA_NAME_RATING, 0);
playlistId = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID);
playlistName = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME);
playlistOwner = args.getBoolean(Constants.INTENT_EXTRA_NAME_PLAYLIST_OWNER, false);
@@ -132,11 +140,11 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
lookupParent = true;
}
if(entries == null) {
- entries = (List<MusicDirectory.Entry>) args.getSerializable(Constants.FRAGMENT_LIST);
- albums = (List<MusicDirectory.Entry>) args.getSerializable(Constants.FRAGMENT_LIST2);
+ entries = (List<Entry>) args.getSerializable(Constants.FRAGMENT_LIST);
+ albums = (List<Entry>) args.getSerializable(Constants.FRAGMENT_LIST2);
if(albums == null) {
- albums = new ArrayList<MusicDirectory.Entry>();
+ albums = new ArrayList<Entry>();
}
}
}
@@ -298,15 +306,15 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
- MusicDirectory.Entry entry;
+ Entry entry;
if(view.getId() == R.id.select_album_entries) {
if(info.position == 0) {
return;
}
- entry = (MusicDirectory.Entry) entryList.getItemAtPosition(info.position);
+ entry = (Entry) entryList.getItemAtPosition(info.position);
albumContext = false;
} else {
- entry = (MusicDirectory.Entry) albumList.getItemAtPosition(info.position);
+ entry = (Entry) albumList.getItemAtPosition(info.position);
albumContext = true;
}
@@ -352,10 +360,10 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_PLAY_NOW_AFTER, false) && menuItem.getItemId() == R.id.song_menu_play_now) {
- List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>();
+ List<Entry> songs = new ArrayList<Entry>();
Iterator it = entries.listIterator(info.position - headers);
while(it.hasNext()) {
- songs.add((MusicDirectory.Entry) it.next());
+ songs.add((Entry) it.next());
}
playNow(songs);
@@ -384,12 +392,14 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position >= 0) {
- MusicDirectory.Entry entry = (MusicDirectory.Entry) parent.getItemAtPosition(position);
+ Entry entry = (Entry) parent.getItemAtPosition(position);
if (entry.isDirectory()) {
SubsonicFragment fragment = new SelectDirectoryFragment();
Bundle args = new Bundle();
args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getId());
args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getTitle());
+ args.putBoolean(Constants.INTENT_EXTRA_NAME_STARRED, entry.isStarred());
+ args.putInt(Constants.INTENT_EXTRA_NAME_RATING, entry.getRating());
if ("newest".equals(albumListType)) {
args.putBoolean(Constants.INTENT_EXTRA_REFRESH_LISTINGS, true);
}
@@ -490,15 +500,15 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
} else {
root = share.getMusicDirectory();
}
- List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>();
+ List<Entry> songs = new ArrayList<Entry>();
getSongsRecursively(root, songs);
root.replaceChildren(songs);
return root;
}
- private void getSongsRecursively(MusicDirectory parent, List<MusicDirectory.Entry> songs) throws Exception {
+ private void getSongsRecursively(MusicDirectory parent, List<Entry> songs) throws Exception {
songs.addAll(parent.getChildren(false, true));
- for (MusicDirectory.Entry dir : parent.getChildren(true, false)) {
+ for (Entry dir : parent.getChildren(true, false)) {
MusicService musicService = MusicServiceFactory.getMusicService(context);
MusicDirectory musicDirectory;
@@ -715,11 +725,13 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
albumList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- MusicDirectory.Entry entry = (MusicDirectory.Entry) parent.getItemAtPosition(position);
+ Entry entry = (Entry) parent.getItemAtPosition(position);
SubsonicFragment fragment = new SelectDirectoryFragment();
Bundle args = new Bundle();
args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getId());
args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getTitle());
+ args.putBoolean(Constants.INTENT_EXTRA_NAME_STARRED, entry.isStarred());
+ args.putInt(Constants.INTENT_EXTRA_NAME_RATING, entry.getRating());
if ("newest".equals(albumListType)) {
args.putBoolean(Constants.INTENT_EXTRA_REFRESH_LISTINGS, true);
}
@@ -751,7 +763,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
private void playAll(final boolean shuffle, final boolean append) {
boolean hasSubFolders = false;
for (int i = 0; i < entryList.getCount(); i++) {
- MusicDirectory.Entry entry = (MusicDirectory.Entry) entryList.getItemAtPosition(i);
+ Entry entry = (Entry) entryList.getItemAtPosition(i);
if (entry != null && entry.isDirectory()) {
hasSubFolders = true;
break;
@@ -774,7 +786,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
boolean someUnselected = false;
int count = entryList.getCount();
for (int i = 0; i < count; i++) {
- if (!entryList.isItemChecked(i) && entryList.getItemAtPosition(i) instanceof MusicDirectory.Entry) {
+ if (!entryList.isItemChecked(i) && entryList.getItemAtPosition(i) instanceof Entry) {
someUnselected = true;
break;
}
@@ -786,7 +798,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
int count = entryList.getCount();
int selectedCount = 0;
for (int i = 0; i < count; i++) {
- MusicDirectory.Entry entry = (MusicDirectory.Entry) entryList.getItemAtPosition(i);
+ Entry entry = (Entry) entryList.getItemAtPosition(i);
if (entry != null && !entry.isDirectory() && !entry.isVideo()) {
entryList.setItemChecked(i, selected);
selectedCount++;
@@ -801,12 +813,12 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
}
- private List<MusicDirectory.Entry> getSelectedSongs() {
- List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>(10);
+ private List<Entry> getSelectedSongs() {
+ List<Entry> songs = new ArrayList<Entry>(10);
int count = entryList.getCount();
for (int i = 0; i < count; i++) {
if (entryList.isItemChecked(i)) {
- MusicDirectory.Entry entry = (MusicDirectory.Entry) entryList.getItemAtPosition(i);
+ Entry entry = (Entry) entryList.getItemAtPosition(i);
// Don't try to add directories or 1-starred songs
if(!entry.isDirectory() && entry.getRating() != 1) {
songs.add(entry);
@@ -835,13 +847,13 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
return;
}
- final List<MusicDirectory.Entry> songs = getSelectedSongs();
+ final List<Entry> songs = getSelectedSongs();
warnIfNetworkOrStorageUnavailable();
// Conditions for using play now button
if(!append && !save && autoplay && !playNext && !shuffle) {
// Call playNow which goes through and tries to use bookmark information
- playNow(songs);
+ playNow(songs, playlistName, playlistId);
return;
}
@@ -878,14 +890,14 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
checkLicenseAndTrialPeriod(onValid);
}
private void downloadBackground(final boolean save) {
- List<MusicDirectory.Entry> songs = getSelectedSongs();
+ List<Entry> songs = getSelectedSongs();
if(songs.isEmpty()) {
selectAll(true, false);
songs = getSelectedSongs();
}
downloadBackground(save, songs);
}
- private void downloadBackground(final boolean save, final List<MusicDirectory.Entry> songs) {
+ private void downloadBackground(final boolean save, final List<Entry> songs) {
if (getDownloadService() == null) {
return;
}
@@ -908,7 +920,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
private void delete() {
- List<MusicDirectory.Entry> songs = getSelectedSongs();
+ List<Entry> songs = getSelectedSongs();
if(songs.isEmpty()) {
selectAll(true, false);
songs = getSelectedSongs();
@@ -1009,7 +1021,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
MusicService musicService = MusicServiceFactory.getMusicService(context);
musicService.deletePodcastEpisode(episode.getEpisodeId(), episode.getParent(), null, context);
if (getDownloadService() != null) {
- List<MusicDirectory.Entry> episodeList = new ArrayList<MusicDirectory.Entry>(1);
+ List<Entry> episodeList = new ArrayList<Entry>(1);
episodeList.add(episode);
getDownloadService().delete(episodeList);
}
@@ -1033,24 +1045,24 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
public void unstarSelected() {
- List<MusicDirectory.Entry> selected = getSelectedSongs();
+ List<Entry> selected = getSelectedSongs();
if(selected.size() == 0) {
selected = entries;
}
if(selected.size() == 0) {
return;
}
- final List<MusicDirectory.Entry> unstar = new ArrayList<MusicDirectory.Entry>();
+ final List<Entry> unstar = new ArrayList<Entry>();
unstar.addAll(selected);
new LoadingTask<Void>(context, true) {
@Override
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
- List<MusicDirectory.Entry> entries = new ArrayList<MusicDirectory.Entry>();
- List<MusicDirectory.Entry> artists = new ArrayList<MusicDirectory.Entry>();
- List<MusicDirectory.Entry> albums = new ArrayList<MusicDirectory.Entry>();
- for(MusicDirectory.Entry entry: unstar) {
+ List<Entry> entries = new ArrayList<Entry>();
+ List<Entry> artists = new ArrayList<Entry>();
+ List<Entry> albums = new ArrayList<Entry>();
+ for(Entry entry: unstar) {
if(entry.isDirectory()) {
if(entry.isAlbum()) {
albums.add(entry);
@@ -1063,8 +1075,13 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
musicService.setStarred(entries, artists, albums, false, this, context);
- for(MusicDirectory.Entry entry: unstar) {
- setEntryStarred(entry, false);
+ for(Entry entry: unstar) {
+ new EntryInstanceUpdater(entry) {
+ @Override
+ public void update(Entry found) {
+ found.setStarred(false);
+ }
+ }.execute();
}
return null;
@@ -1074,7 +1091,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
protected void done(Void result) {
Util.toast(context, context.getResources().getString(R.string.starring_content_unstarred, Integer.toString(unstar.size())));
- for(MusicDirectory.Entry entry: unstar) {
+ for(Entry entry: unstar) {
entries.remove(entry);
}
entryAdapter.notifyDataSetChanged();
@@ -1149,7 +1166,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
builder.create().show();
}
- private View createHeader(List<MusicDirectory.Entry> entries) {
+ private View createHeader(List<Entry> entries) {
View header = entryList.findViewById(R.id.select_album_header);
boolean add = false;
if(header == null) {
@@ -1160,12 +1177,12 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
final ImageLoader imageLoader = getImageLoader();
// Try a few times to get a random cover art
- MusicDirectory.Entry coverArt = null;
+ Entry coverArt = null;
for(int i = 0; (i < 3) && (coverArt == null || coverArt.getCoverArt() == null); i++) {
coverArt = entries.get(random.nextInt(entries.size()));
}
- final MusicDirectory.Entry albumRep = coverArt;
+ final Entry albumRep = coverArt;
View coverArtView = header.findViewById(R.id.select_album_art);
coverArtView.setOnClickListener(new View.OnClickListener() {
@Override
@@ -1202,7 +1219,7 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
Set<String> artists = new HashSet<String>();
Set<Integer> years = new HashSet<Integer>();
Integer totalDuration = 0;
- for (MusicDirectory.Entry entry : entries) {
+ for (Entry entry : entries) {
if (!entry.isDirectory()) {
songCount++;
if (entry.getArtist() != null) {
@@ -1274,6 +1291,50 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter
}
});
}
+
+ final Entry album = new Entry();
+ album.setId(id);
+ album.setTitle(name);
+ album.setDirectory(true);
+ album.setStarred(starred);
+ album.setRating(rating);
+
+ final ImageButton starButton = (ImageButton) header.findViewById(R.id.select_album_star);
+ if(id != null && Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_MENU_STAR, true)) {
+ starButton.setImageResource(album.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
+ starButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ toggleStarred(album, new OnStarChange() {
+ @Override
+ void starChange(boolean starred) {
+ starButton.setImageResource(album.isStarred() ? android.R.drawable.btn_star_big_on : android.R.drawable.btn_star_big_off);
+ }
+ });
+ }
+ });
+ } else {
+ starButton.setVisibility(View.GONE);
+ }
+
+ View ratingBarWrapper = header.findViewById(R.id.select_album_rate_wrapper);
+ final RatingBar ratingBar = (RatingBar) header.findViewById(R.id.select_album_rate);
+ if(id != null && Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_MENU_RATING, true) && !Util.isOffline(context)) {
+ ratingBar.setRating(album.getRating());
+ ratingBarWrapper.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ setRating(album, new OnRatingChange() {
+ @Override
+ void ratingChange(int rating) {
+ ratingBar.setRating(album.getRating());
+ }
+ });
+ }
+ });
+ } else {
+ ratingBar.setVisibility(View.GONE);
+ }
}
if(add) {
diff --git a/src/github/daneren2005/dsub/fragments/SubsonicFragment.java b/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
index fcef44fb..7ff25d2d 100644
--- a/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
+++ b/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
@@ -51,6 +51,7 @@ import github.daneren2005.dsub.activity.DownloadActivity;
import github.daneren2005.dsub.activity.SubsonicActivity;
import github.daneren2005.dsub.activity.SubsonicFragmentActivity;
import github.daneren2005.dsub.domain.Artist;
+import github.daneren2005.dsub.domain.Bookmark;
import github.daneren2005.dsub.domain.Genre;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.Playlist;
@@ -670,9 +671,15 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
dialog.show();
}
- public void toggleStarred(final Entry entry) {
+ public void toggleStarred(Entry entry) {
+ toggleStarred(entry, null);
+ }
+ public void toggleStarred(final Entry entry, final OnStarChange onStarChange) {
final boolean starred = !entry.isStarred();
entry.setStarred(starred);
+ if(onStarChange != null) {
+ onStarChange.starChange(starred);
+ }
new SilentBackgroundTask<Void>(context) {
@Override
@@ -688,7 +695,12 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
musicService.setStarred(Arrays.asList(entry), null, null, starred, null, context);
}
- setEntryStarred(entry, starred);
+ new EntryInstanceUpdater(entry) {
+ @Override
+ public void update(Entry found) {
+ found.setStarred(starred);
+ }
+ }.execute();
return null;
}
@@ -703,6 +715,9 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
protected void error(Throwable error) {
Log.w(TAG, "Failed to star", error);
entry.setStarred(!starred);
+ if(onStarChange != null) {
+ onStarChange.starChange(!starred);
+ }
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
@@ -715,25 +730,6 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
}.execute();
}
- protected void setEntryStarred(Entry entry, boolean starred) {
- DownloadService downloadService = DownloadService.getInstance();
- if(downloadService != null && !entry.isDirectory()) {
- List<DownloadFile> files = downloadService.getDownloads();
- for(DownloadFile file: files) {
- Entry check = file.getSong();
- if(entry.getId().equals(check.getId())) {
- check.setStarred(starred);
- downloadService.serializeQueue();
- break;
- }
- }
- }
-
- Entry find = UpdateView.findEntry(entry);
- if(find != null) {
- find.setStarred(starred);
- }
- }
public void toggleStarred(final Artist entry) {
final boolean starred = !entry.isStarred();
@@ -1388,7 +1384,10 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
return gestureScanner;
}
- protected void playBookmark(final List<Entry> songs, final Entry song) {
+ protected void playBookmark(List<Entry> songs, Entry song) {
+ playBookmark(songs, song, null, null);
+ }
+ protected void playBookmark(final List<Entry> songs, final Entry song, final String playlistName, final String playlistId) {
final Integer position = song.getBookmark().getPosition();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
@@ -1403,18 +1402,22 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
.setNegativeButton(R.string.bookmark_action_start_over, new DialogInterface.OnClickListener() {
@Override
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 {
MusicService musicService = MusicServiceFactory.getMusicService(context);
musicService.deleteBookmark(song, context, null);
- song.setBookmark(null);
return null;
}
@Override
protected void error(Throwable error) {
+ song.setBookmark(oldBookmark);
+
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
@@ -1434,6 +1437,9 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
protected void playNow(List<Entry> entries) {
+ playNow(entries, null, null);
+ }
+ protected void playNow(List<Entry> entries, String playlistName, String playlistId) {
Entry bookmark = null;
for(Entry entry: entries) {
if(entry.getBookmark() != null) {
@@ -1444,17 +1450,23 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
// If no bookmark found, just play from start
if(bookmark == null) {
- playNow(entries, 0);
+ playNow(entries, 0, playlistName, playlistId);
} else {
// If bookmark found, then give user choice to start from there or to start over
- playBookmark(entries, bookmark);
+ playBookmark(entries, bookmark, playlistName, playlistId);
}
}
protected void playNow(List<Entry> entries, int position) {
+ playNow(entries, position, null, null);
+ }
+ protected void playNow(List<Entry> entries, int position, String playlistName, String playlistId) {
Entry selected = entries.isEmpty() ? null : entries.get(0);
- playNow(entries, selected, position);
+ playNow(entries, selected, position, playlistName, playlistId);
+ }
+ protected void playNow(List<Entry> entries, Entry song, int position) {
+ playNow(entries, song, position, null, null);
}
- protected void playNow(final List<Entry> entries, final Entry song, final int position) {
+ protected void playNow(final List<Entry> entries, final Entry song, final int position, final String playlistName, final String playlistId) {
new LoadingTask<Void>(context) {
@Override
protected Void doInBackground() throws Throwable {
@@ -1465,6 +1477,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
downloadService.clear();
downloadService.download(entries, false, true, true, false, entries.indexOf(song), position);
+ downloadService.setSuggestedPlaylistName(playlistName, playlistId);
return null;
}
@@ -1480,12 +1493,21 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
Util.confirmDialog(context, R.string.bookmark_delete_title, entry.getTitle(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
+ final Bookmark oldBookmark = entry.getBookmark();
+ entry.setBookmark(null);
+
new LoadingTask<Void>(context, false) {
@Override
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
- entry.setBookmark(null);
musicService.deleteBookmark(entry, context, null);
+
+ new EntryInstanceUpdater(entry) {
+ @Override
+ public void update(Entry found) {
+ found.setBookmark(null);
+ }
+ }.execute();
return null;
}
@@ -1501,6 +1523,8 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
@Override
protected void error(Throwable error) {
+ entry.setBookmark(oldBookmark);
+
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
@@ -1514,8 +1538,11 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
});
}
-
- protected void setRating(final Entry entry) {
+
+ protected void setRating(Entry entry) {
+ setRating(entry, null);
+ }
+ protected void setRating(final Entry entry, final OnRatingChange onRatingChange) {
View layout = context.getLayoutInflater().inflate(R.layout.rating, null);
final RatingBar ratingBar = (RatingBar) layout.findViewById(R.id.rating_bar);
ratingBar.setRating((float) entry.getRating());
@@ -1527,7 +1554,7 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
@Override
public void onClick(DialogInterface dialog, int id) {
int rating = (int) ratingBar.getRating();
- setRating(entry, rating);
+ setRating(entry, rating, onRatingChange);
}
})
.setNegativeButton(R.string.common_cancel, null);
@@ -1536,19 +1563,29 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
dialog.show();
}
- protected void setRating(final Entry entry, final int rating) {
+ protected void setRating(Entry entry, int rating) {
+ setRating(entry, rating, null);
+ }
+ protected void setRating(final Entry entry, final int rating, final OnRatingChange onRatingChange) {
+ final int oldRating = entry.getRating();
+ entry.setRating(rating);
+
+ if(onRatingChange != null) {
+ onRatingChange.ratingChange(rating);
+ }
+
new SilentBackgroundTask<Void>(context) {
@Override
protected Void doInBackground() throws Throwable {
MusicService musicService = MusicServiceFactory.getMusicService(context);
musicService.setRating(entry, rating, context, null);
- entry.setRating(rating);
-
- Entry findEntry = UpdateView.findEntry(entry);
- if(findEntry != null) {
- findEntry.setRating(rating);
- }
+ new EntryInstanceUpdater(entry) {
+ @Override
+ public void update(Entry found) {
+ found.setRating(rating);
+ }
+ }.execute();
return null;
}
@@ -1559,6 +1596,11 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
@Override
protected void error(Throwable error) {
+ entry.setRating(oldRating);
+ if(onRatingChange != null) {
+ onRatingChange.ratingChange(oldRating);
+ }
+
String msg;
if (error instanceof OfflineException || error instanceof ServerTooOldException) {
msg = getErrorMessage(error);
@@ -1570,4 +1612,45 @@ 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()) {
+ boolean serializeChanges = false;
+ List<DownloadFile> downloadFiles = downloadService.getDownloads();
+ for(DownloadFile file: downloadFiles) {
+ Entry check = file.getSong();
+ if(entry.getId().equals(check.getId())) {
+ update(entry);
+ serializeChanges = true;
+ }
+ }
+
+ if(serializeChanges) {
+ downloadService.serializeQueue();
+ }
+ }
+
+ Entry find = UpdateView.findEntry(entry);
+ if(find != null) {
+ update(find);
+ }
+ }
+ }
+
+ public abstract class OnRatingChange {
+ abstract void ratingChange(int rating);
+ }
+ public abstract class OnStarChange {
+ abstract void starChange(boolean starred);
+ }
}
diff --git a/src/github/daneren2005/dsub/service/CachedMusicService.java b/src/github/daneren2005/dsub/service/CachedMusicService.java
index 7c0f9e09..1e553ca2 100644
--- a/src/github/daneren2005/dsub/service/CachedMusicService.java
+++ b/src/github/daneren2005/dsub/service/CachedMusicService.java
@@ -345,10 +345,110 @@ public class CachedMusicService implements MusicService {
musicService.scrobble(id, submission, context, progressListener);
}
- @Override
- public MusicDirectory getAlbumList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception {
- return musicService.getAlbumList(type, size, offset, context, progressListener);
- }
+ @Override
+ public MusicDirectory getAlbumList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception {
+ MusicDirectory dir = musicService.getAlbumList(type, size, offset, context, progressListener);
+
+ // Do some serialization updates for changes to recently added
+ if("newest".equals(type) && offset == 0) {
+ String recentlyAddedFile = getCacheName(context, type);
+ ArrayList<String> recents = FileUtil.deserialize(context, recentlyAddedFile, ArrayList.class);
+ if(recents == null) {
+ recents = new ArrayList<String>();
+ }
+
+ // Add any new items
+ final int instance = musicService.getInstance(context);
+ isTagBrowsing = Util.isTagBrowsing(context, instance);
+ for(final Entry album: dir.getChildren()) {
+ if(!recents.contains(album.getId())) {
+ recents.add(album.getId());
+
+ String cacheName, parent;
+ if(isTagBrowsing) {
+ cacheName = "artist";
+ parent = album.getArtistId();
+ } else {
+ cacheName = "directory";
+ parent = album.getParent();
+ }
+
+ // Add album to artist
+ if(parent != null) {
+ new MusicDirectoryUpdater(context, cacheName, parent) {
+ private boolean changed = false;
+
+ @Override
+ public boolean checkResult(Entry check) {
+ return true;
+ }
+
+ @Override
+ public void updateResult(List<Entry> objects, Entry result) {
+ // Only add if it doesn't already exist in it!
+ if(!objects.contains(album)) {
+ objects.add(album);
+ changed = true;
+ }
+ }
+
+ @Override
+ public void save(ArrayList<Entry> objects) {
+ // Only save if actually added to artist
+ if(changed) {
+ musicDirectory.replaceChildren(objects);
+ // Reapply sort after addition
+ musicDirectory.sortChildren(context, instance);
+ FileUtil.serialize(context, musicDirectory, cacheName);
+ }
+ }
+ }.execute();
+ } else {
+ // If parent is null, then this is a root level album
+ final Artist artist = new Artist();
+ artist.setId(album.getId());
+ artist.setName(album.getTitle());
+
+ new IndexesUpdater(context, isTagBrowsing ? "artists" : "indexes") {
+ private boolean changed = false;
+
+ @Override
+ public boolean checkResult(Artist check) {
+ return true;
+ }
+
+ @Override
+ public void updateResult(List<Artist> objects, Artist result) {
+ if(!objects.contains(artist)) {
+ objects.add(artist);
+ changed = true;
+ }
+ }
+
+ @Override
+ public void save(ArrayList<Artist> objects) {
+ if(changed) {
+ indexes.setArtists(objects);
+ // Reapply sort after addition
+ indexes.sortChildren(context);
+ FileUtil.serialize(context, indexes, cacheName);
+ cachedIndexes.set(indexes);
+ }
+ }
+ }.execute();
+ }
+ }
+ }
+
+ // Keep list from growing into infinity
+ while(recents.size() > 0) {
+ recents.remove(0);
+ }
+ FileUtil.serialize(context, recents, recentlyAddedFile);
+ }
+
+ return dir;
+ }
@Override
public MusicDirectory getAlbumList(String type, String extra, int size, int offset, Context context, ProgressListener progressListener) throws Exception {
@@ -381,24 +481,7 @@ public class CachedMusicService implements MusicService {
totalList.addAll(oldList);
totalList.addAll(newList);
- new GenericEntryUpdater(context, totalList) {
- @Override
- public boolean checkResult(Entry entry, Entry check) {
- if (entry.getId().equals(check.getId())) {
- if(entry.isStarred() != check.isStarred()) {
- check.setStarred(entry.isStarred());
- return true;
- }
- }
-
- return false;
- }
-
- @Override
- public void updateResult(Entry result) {
-
- }
- }.execute();
+ new StarUpdater(context, totalList).execute();
}
FileUtil.serialize(context, dir, "starred");
@@ -491,12 +574,7 @@ public class CachedMusicService implements MusicService {
allEntries.addAll(entries);
}
- new GenericEntryUpdater(context, allEntries) {
- @Override
- public void updateResult(Entry result) {
- result.setStarred(starred);
- }
- }.execute();
+ new StarUpdater(context, allEntries).execute();
}
@Override
@@ -903,7 +981,7 @@ public class CachedMusicService implements MusicService {
}
}
private abstract class MusicDirectoryUpdater extends SerializeUpdater<Entry> {
- private MusicDirectory musicDirectory;
+ protected MusicDirectory musicDirectory;
public MusicDirectoryUpdater(Context context, String cacheName, String id) {
super(context, cacheName, id, true);
@@ -1018,7 +1096,7 @@ public class CachedMusicService implements MusicService {
@Override
public void updateResult(List<Artist> objects, Artist result) {
- GenericEntryUpdater.this.updateResult(new Entry(result));
+ // Don't try to put anything here, as the Entry update method will not be called since it's a artist!
}
}.execute();
} else {
@@ -1118,6 +1196,28 @@ public class CachedMusicService implements MusicService {
}
}
+ private class StarUpdater extends GenericEntryUpdater {
+ public StarUpdater(Context context, List<Entry> entries) {
+ super(context, entries);
+ }
+
+ @Override
+ public boolean checkResult(Entry entry, Entry check) {
+ if (entry.getId().equals(check.getId())) {
+ if(entry.isStarred() != check.isStarred()) {
+ check.setStarred(entry.isStarred());
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public void updateResult(Entry result) {
+
+ }
+ };
private abstract class IndexesUpdater extends SerializeUpdater<Artist> {
Indexes indexes;
diff --git a/src/github/daneren2005/dsub/service/DownloadService.java b/src/github/daneren2005/dsub/service/DownloadService.java
index 43eac93d..7ff1d5eb 100644
--- a/src/github/daneren2005/dsub/service/DownloadService.java
+++ b/src/github/daneren2005/dsub/service/DownloadService.java
@@ -1880,6 +1880,20 @@ public class DownloadService extends Service {
return null;
}
+
+ @Override
+ public void error(Throwable error) {
+ Log.w(TAG, "Failed to create automatic bookmark", error);
+
+ 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/src/github/daneren2005/dsub/service/MediaStoreService.java b/src/github/daneren2005/dsub/service/MediaStoreService.java
index b641a54f..0aa3269f 100644
--- a/src/github/daneren2005/dsub/service/MediaStoreService.java
+++ b/src/github/daneren2005/dsub/service/MediaStoreService.java
@@ -135,7 +135,14 @@ public class MediaStoreService {
public void deleteFromMediaStore(File file) {
ContentResolver contentResolver = context.getContentResolver();
- int n = contentResolver.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
+ Uri uri;
+ if(FileUtil.isVideoFile(file)) {
+ uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
+ } else {
+ uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
+ }
+
+ int n = contentResolver.delete(uri,
MediaStore.MediaColumns.DATA + "=?",
new String[]{file.getAbsolutePath()});
if (n > 0) {
diff --git a/src/github/daneren2005/dsub/service/OfflineMusicService.java b/src/github/daneren2005/dsub/service/OfflineMusicService.java
index 41489ee6..b62d04a1 100644
--- a/src/github/daneren2005/dsub/service/OfflineMusicService.java
+++ b/src/github/daneren2005/dsub/service/OfflineMusicService.java
@@ -92,40 +92,9 @@ public class OfflineMusicService implements MusicService {
}
}
- SharedPreferences prefs = Util.getPreferences(context);
- String ignoredArticlesString = prefs.getString(Constants.CACHE_KEY_IGNORE, "The El La Los Las Le Les");
- final String[] ignoredArticles = ignoredArticlesString.split(" ");
-
- Collections.sort(artists, new Comparator<Artist>() {
- public int compare(Artist lhsArtist, Artist rhsArtist) {
- String lhs = lhsArtist.getName().toLowerCase();
- String rhs = rhsArtist.getName().toLowerCase();
-
- char lhs1 = lhs.charAt(0);
- char rhs1 = rhs.charAt(0);
-
- if(Character.isDigit(lhs1) && !Character.isDigit(rhs1)) {
- return 1;
- } else if(Character.isDigit(rhs1) && !Character.isDigit(lhs1)) {
- return -1;
- }
-
- for(String article: ignoredArticles) {
- int index = lhs.indexOf(article.toLowerCase() + " ");
- if(index == 0) {
- lhs = lhs.substring(article.length() + 1);
- }
- index = rhs.indexOf(article.toLowerCase() + " ");
- if(index == 0) {
- rhs = rhs.substring(article.length() + 1);
- }
- }
-
- return lhs.compareTo(rhs);
- }
- });
-
- return new Indexes(0L, Collections.<Artist>emptyList(), artists);
+ Indexes indexes = new Indexes(0L, Collections.<Artist>emptyList(), artists);
+ indexes.sortChildren(context);
+ return indexes;
}
@Override
diff --git a/src/github/daneren2005/dsub/service/RESTMusicService.java b/src/github/daneren2005/dsub/service/RESTMusicService.java
index 3e59abe3..53b20634 100644
--- a/src/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/src/github/daneren2005/dsub/service/RESTMusicService.java
@@ -620,7 +620,12 @@ public class RESTMusicService implements MusicService {
List<String> parameterNames = Arrays.asList("id");
List<Object> parameterValues = Arrays.<Object>asList(entry.getCoverArt());
HttpEntity entity = getEntityForURL(context, url, null, parameterNames, parameterValues, progressListener);
- in = entity.getContent();
+
+ in = entity.getContent();
+ Header contentEncoding = entity.getContentEncoding();
+ if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
+ in = new GZIPInputStream(in);
+ }
// If content type is XML, an error occured. Get it.
String contentType = Util.getContentType(entity);
@@ -698,6 +703,10 @@ public class RESTMusicService implements MusicService {
String contentType = Util.getContentType(response.getEntity());
if (contentType != null && contentType.startsWith("text/xml")) {
InputStream in = response.getEntity().getContent();
+ Header contentEncoding = response.getEntity().getContentEncoding();
+ if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
+ in = new GZIPInputStream(in);
+ }
try {
new ErrorParser(context, getInstance(context)).parse(new InputStreamReader(in, Constants.UTF_8));
} finally {
@@ -1309,6 +1318,10 @@ public class RESTMusicService implements MusicService {
HttpEntity entity = getEntityForURL(context, url, null, parameterNames, parameterValues, progressListener);
in = entity.getContent();
+ Header contentEncoding = entity.getContentEncoding();
+ if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
+ in = new GZIPInputStream(in);
+ }
// If content type is XML, an error occurred. Get it.
String contentType = Util.getContentType(entity);
@@ -1392,18 +1405,24 @@ public class RESTMusicService implements MusicService {
try{
SearchCritera critera = new SearchCritera(search, 0, 1, 1);
SearchResult result = searchNew(critera, context, progressListener);
- if(result.getSongs().size() == 1){
- Log.i(TAG, "Query '" + search + "' returned song " + result.getSongs().get(0).getTitle() + " by " + result.getSongs().get(0).getArtist() + " with id " + result.getSongs().get(0).getId());
- setStarred(Arrays.asList(result.getSongs().get(0)), null, null, starred, progressListener, context);
- } else if(result.getAlbums().size() == 1){
- Log.i(TAG, "Query '" + search + "' returned song " + result.getAlbums().get(0).getTitle() + " by " + result.getAlbums().get(0).getArtist() + " with id " + result.getAlbums().get(0).getId());
- setStarred(Arrays.asList(result.getAlbums().get(0)), null, null, starred, progressListener, context);
+ if(result.getSongs().size() == 1) {
+ MusicDirectory.Entry song = result.getSongs().get(0);
+ Log.i(TAG, "Query '" + search + "' returned song " + song.getTitle() + " by " + song.getArtist() + " with id " + song.getId());
+ setStarred(Arrays.asList(song), null, null, starred, progressListener, context);
+ } else if(result.getAlbums().size() == 1) {
+ MusicDirectory.Entry album = result.getAlbums().get(0);
+ Log.i(TAG, "Query '" + search + "' returned album " + album.getTitle() + " by " + album.getArtist() + " with id " + album.getId());
+ if(Util.isTagBrowsing(context, getInstance(context))) {
+ setStarred(null, null, Arrays.asList(album), starred, progressListener, context);
+ } else {
+ setStarred(Arrays.asList(album), null, null, starred, progressListener, context);
+ }
}
- else{
+ else {
throw new Exception("Song not found on server");
}
}
- catch(Exception e){
+ catch(Exception e) {
Log.e(TAG, e.toString());
retry++;
}
@@ -1550,7 +1569,9 @@ public class RESTMusicService implements MusicService {
request.addHeader(header);
}
}
- request.addHeader("Accept-Encoding", "gzip");
+ if(url.indexOf("getCoverArt") == -1 && url.indexOf("stream") == -1 && url.indexOf("getAvatar") == -1) {
+ request.addHeader("Accept-Encoding", "gzip");
+ }
// Set credentials to get through apache proxies that require authentication.
int instance = prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1);
diff --git a/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java b/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java
index c5d5ec51..9542324e 100644
--- a/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java
+++ b/src/github/daneren2005/dsub/service/parser/MusicDirectoryEntryParser.java
@@ -71,7 +71,7 @@ public class MusicDirectoryEntryParser extends AbstractParser {
String type = get("type");
if("podcast".equals(type)) {
entry.setType(MusicDirectory.Entry.TYPE_PODCAST);
- } else if("audiobook".equals(type)) {
+ } else if("audiobook".equals(type) || (entry.getGenre() != null && "audiobook".equals(entry.getGenre().toLowerCase()))) {
entry.setType(MusicDirectory.Entry.TYPE_AUDIO_BOOK);
}
} else if(!"".equals(artist)) {
diff --git a/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java b/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java
index 05e8b274..a5500505 100644
--- a/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java
+++ b/src/github/daneren2005/dsub/service/parser/MusicDirectoryParser.java
@@ -96,9 +96,7 @@ public class MusicDirectoryParser extends MusicDirectoryEntryParser {
validate();
// Only apply sorting on server version 4.7 and greater, where disc is supported
- if(ServerInfo.checkServerVersion(context, "1.8.0", instance)) {
- dir.sortChildren(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_CUSTOM_SORT_ENABLED, true));
- }
+ dir.sortChildren(context, instance);
return dir;
}
diff --git a/src/github/daneren2005/dsub/service/sync/MostRecentSyncAdapter.java b/src/github/daneren2005/dsub/service/sync/MostRecentSyncAdapter.java
index 6dfbbbe4..a0727201 100644
--- a/src/github/daneren2005/dsub/service/sync/MostRecentSyncAdapter.java
+++ b/src/github/daneren2005/dsub/service/sync/MostRecentSyncAdapter.java
@@ -83,6 +83,10 @@ public class MostRecentSyncAdapter extends SubsonicSyncAdapter {
}
if(updated.size() > 0) {
+ while(syncedList.size() > 40) {
+ syncedList.remove(0);
+ }
+
FileUtil.serialize(context, syncedList, SyncUtil.getMostRecentSyncFile(context, instance));
// If there is a new album on the active server, chances are artists need to be refreshed
diff --git a/src/github/daneren2005/dsub/util/Constants.java b/src/github/daneren2005/dsub/util/Constants.java
index ac21df4c..f22fd3f0 100644
--- a/src/github/daneren2005/dsub/util/Constants.java
+++ b/src/github/daneren2005/dsub/util/Constants.java
@@ -37,6 +37,8 @@ public final class Constants {
// Names for intent extras.
public static final String INTENT_EXTRA_NAME_ID = "subsonic.id";
public static final String INTENT_EXTRA_NAME_NAME = "subsonic.name";
+ public static final String INTENT_EXTRA_NAME_STARRED = "subsonic.starred";
+ public static final String INTENT_EXTRA_NAME_RATING = "subsonic.rating";
public static final String INTENT_EXTRA_NAME_CHILD_ID = "subsonic.child.id";
public static final String INTENT_EXTRA_NAME_ARTIST = "subsonic.artist";
public static final String INTENT_EXTRA_NAME_TITLE = "subsonic.title";
@@ -73,8 +75,6 @@ public final class Constants {
public static final String PREFERENCES_KEY_SERVER_URL = "serverUrl";
public static final String PREFERENCES_KEY_SERVER_INTERNAL_URL = "serverInternalUrl";
public static final String PREFERENCES_KEY_SERVER_LOCAL_NETWORK_SSID = "serverLocalNetworkSSID";
- public static final String PREFERENCES_KEY_SERVER_VERSION = "serverVersion";
- public static final String PREFERENCES_KEY_SERVER_TYPE = "serverType";
public static final String PREFERENCES_KEY_TEST_CONNECTION = "serverTestConnection";
public static final String PREFERENCES_KEY_OPEN_BROWSER = "openBrowser";
public static final String PREFERENCES_KEY_MUSIC_FOLDER_ID = "musicFolderId";
diff --git a/src/github/daneren2005/dsub/util/FileUtil.java b/src/github/daneren2005/dsub/util/FileUtil.java
index 5aafe213..60fc6031 100644
--- a/src/github/daneren2005/dsub/util/FileUtil.java
+++ b/src/github/daneren2005/dsub/util/FileUtil.java
@@ -30,6 +30,7 @@ import java.io.RandomAccessFile;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
+import java.util.HashMap;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.Iterator;
@@ -74,6 +75,7 @@ public class FileUtil {
private static final List<String> PLAYLIST_FILE_EXTENSIONS = Arrays.asList("m3u");
private static File DEFAULT_MUSIC_DIR;
private static final Kryo kryo = new Kryo();
+ private static HashMap<String, MusicDirectory.Entry> entryLookup;
static {
kryo.register(MusicDirectory.Entry.class);
@@ -255,7 +257,13 @@ public class FileUtil {
}
}
public static Bitmap getScaledBitmap(Bitmap bitmap, int size) {
- return Bitmap.createScaledBitmap(bitmap, size, Util.getScaledHeight(bitmap, size), true);
+ // 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)) {
+ return bitmap;
+ } else {
+ return Bitmap.createScaledBitmap(bitmap, size, Util.getScaledHeight(bitmap, size), true);
+ }
}
public static File getAlbumArtDirectory(Context context) {
@@ -280,10 +288,13 @@ public class FileUtil {
File f = new File(fileSystemSafeDir(entry.getPath()));
dir = new File(getMusicDirectory(context).getPath() + "/" + (entry.isDirectory() ? f.getPath() : f.getParent()));
} else {
- MusicDirectory.Entry firstSong = lookupChild(context, entry, false);
- if(firstSong != null) {
- File songFile = FileUtil.getSongFile(context, firstSong);
- dir = songFile.getParentFile();
+ MusicDirectory.Entry firstSong;
+ if(!Util.isOffline(context)) {
+ firstSong = lookupChild(context, entry, false);
+ if(firstSong != null) {
+ File songFile = FileUtil.getSongFile(context, firstSong);
+ dir = songFile.getParentFile();
+ }
}
if(dir == null) {
@@ -299,6 +310,23 @@ public class FileUtil {
}
public static MusicDirectory.Entry lookupChild(Context context, MusicDirectory.Entry entry, boolean allowDir) {
+ // Initialize lookupMap if first time called
+ String lookupName = Util.getCacheName(context, "entryLookup");
+ if(entryLookup == null) {
+ entryLookup = deserialize(context, lookupName, HashMap.class);
+
+ // Create it if
+ if(entryLookup == null) {
+ entryLookup = new HashMap<String, MusicDirectory.Entry>();
+ }
+ }
+
+ // Check if this lookup has already been done before
+ MusicDirectory.Entry child = entryLookup.get(entry.getId());
+ if(child != null) {
+ return child;
+ }
+
// Do a special lookup since 4.7+ doesn't match artist/album to entry.getPath
String s = Util.getRestUrl(context, null, false) + entry.getId();
String cacheName = (Util.isTagBrowsing(context) ? "album-" : "directory-") + s.hashCode() + ".ser";
@@ -307,7 +335,10 @@ public class FileUtil {
if(entryDir != null) {
List<MusicDirectory.Entry> songs = entryDir.getChildren(allowDir, true);
if(songs.size() > 0) {
- return songs.get(0);
+ child = songs.get(0);
+ entryLookup.put(entry.getId(), child);
+ serialize(context, entryLookup, lookupName);
+ return child;
}
}
diff --git a/src/github/daneren2005/dsub/util/ImageLoader.java b/src/github/daneren2005/dsub/util/ImageLoader.java
index f62741ec..1b91b778 100644
--- a/src/github/daneren2005/dsub/util/ImageLoader.java
+++ b/src/github/daneren2005/dsub/util/ImageLoader.java
@@ -124,7 +124,7 @@ public class ImageLoader {
createLargeUnknownImage(view.getContext());
}
- if(entry != null && entry.getCoverArt() == null && entry.isDirectory()) {
+ if(entry != null && entry.getCoverArt() == null && entry.isDirectory() && !Util.isOffline(context)) {
// Try to lookup child cover art
MusicDirectory.Entry firstChild = FileUtil.lookupChild(context, entry, true);
if(firstChild != null) {
diff --git a/src/github/daneren2005/dsub/view/AlbumCell.java b/src/github/daneren2005/dsub/view/AlbumCell.java
index 522834d1..d6a18205 100644
--- a/src/github/daneren2005/dsub/view/AlbumCell.java
+++ b/src/github/daneren2005/dsub/view/AlbumCell.java
@@ -20,6 +20,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
+import android.widget.RatingBar;
import android.widget.TextView;
import java.io.File;
@@ -50,6 +51,8 @@ public class AlbumCell extends UpdateView {
titleView = (TextView) findViewById(R.id.album_title);
artistView = (TextView) findViewById(R.id.album_artist);
+ ratingBar = (RatingBar) findViewById(R.id.album_rating);
+ ratingBar.setFocusable(false);
starButton = (ImageButton) findViewById(R.id.album_star);
starButton.setFocusable(false);
moreButton = (ImageView) findViewById(R.id.album_more);
@@ -92,5 +95,10 @@ public class AlbumCell extends UpdateView {
exists = file.exists();
isStarred = album.isStarred();
+ isRated = album.getRating();
+ }
+
+ public MusicDirectory.Entry getEntry() {
+ return album;
}
}
diff --git a/src/github/daneren2005/dsub/view/AlbumView.java b/src/github/daneren2005/dsub/view/AlbumView.java
index e28eeadd..7785a8af 100644
--- a/src/github/daneren2005/dsub/view/AlbumView.java
+++ b/src/github/daneren2005/dsub/view/AlbumView.java
@@ -24,6 +24,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
+import android.widget.RatingBar;
import android.widget.TextView;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.domain.MusicDirectory;
@@ -57,6 +58,7 @@ public class AlbumView extends UpdateView {
titleView = (TextView) findViewById(R.id.album_title);
artistView = (TextView) findViewById(R.id.album_artist);
coverArtView = findViewById(R.id.album_coverart);
+ ratingBar = (RatingBar) findViewById(R.id.album_rating);
starButton = (ImageButton) findViewById(R.id.album_star);
starButton.setFocusable(false);
@@ -92,5 +94,10 @@ public class AlbumView extends UpdateView {
exists = file.exists();
isStarred = album.isStarred();
+ isRated = album.getRating();
+ }
+
+ public MusicDirectory.Entry getEntry() {
+ return album;
}
}
diff --git a/src/github/daneren2005/dsub/view/DownloadFileAdapter.java b/src/github/daneren2005/dsub/view/DownloadFileAdapter.java
index f9676dbd..f535acef 100644
--- a/src/github/daneren2005/dsub/view/DownloadFileAdapter.java
+++ b/src/github/daneren2005/dsub/view/DownloadFileAdapter.java
@@ -42,6 +42,7 @@ public class DownloadFileAdapter extends ArrayAdapter<DownloadFile> {
}
DownloadFile downloadFile = getItem(position);
view.setObject(downloadFile.getSong(), false);
+ view.setDownloadFile(downloadFile);
return view;
}
}
diff --git a/src/github/daneren2005/dsub/view/SongView.java b/src/github/daneren2005/dsub/view/SongView.java
index 8d986090..f795cbce 100644
--- a/src/github/daneren2005/dsub/view/SongView.java
+++ b/src/github/daneren2005/dsub/view/SongView.java
@@ -55,6 +55,7 @@ public class SongView extends UpdateView implements Checkable {
private DownloadService downloadService;
private long revision = -1;
private DownloadFile downloadFile;
+ private boolean dontChangeDownloadFile = false;
private boolean playing = false;
private boolean rightImage = false;
@@ -66,8 +67,6 @@ public class SongView extends UpdateView implements Checkable {
private boolean loaded = false;
private boolean isBookmarked = false;
private boolean bookmarked = false;
- private int isRated = 0;
- private int rating = 0;
public SongView(Context context) {
super(context);
@@ -79,6 +78,7 @@ public class SongView extends UpdateView implements Checkable {
durationTextView = (TextView) findViewById(R.id.song_duration);
statusTextView = (TextView) findViewById(R.id.song_status);
statusImageView = (ImageView) findViewById(R.id.song_status_icon);
+ ratingBar = (RatingBar) findViewById(R.id.song_rating);
starButton = (ImageButton) findViewById(R.id.song_star);
starButton.setFocusable(false);
bookmarkButton = (ImageButton) findViewById(R.id.song_bookmark);
@@ -148,11 +148,18 @@ public class SongView extends UpdateView implements Checkable {
checkedTextView.setVisibility(checkable && !song.isVideo() ? View.VISIBLE : View.GONE);
this.setBackgroundColor(0x00000000);
+ ratingBar.setVisibility(View.GONE);
rating = 0;
revision = -1;
loaded = false;
- }
+ dontChangeDownloadFile = false;
+ }
+
+ public void setDownloadFile(DownloadFile downloadFile) {
+ this.downloadFile = downloadFile;
+ dontChangeDownloadFile = true;
+ }
@Override
protected void updateBackground() {
@@ -164,7 +171,7 @@ public class SongView extends UpdateView implements Checkable {
}
long newRevision = downloadService.getDownloadListUpdateRevision();
- if(revision != newRevision || downloadFile == null) {
+ if((revision != newRevision && dontChangeDownloadFile == false) || downloadFile == null) {
downloadFile = downloadService.forSong(song);
revision = newRevision;
}
@@ -259,15 +266,24 @@ public class SongView extends UpdateView implements Checkable {
}
if(isRated != rating) {
- // Color the entire row based on rating
- if(isRated > 3) {
- this.setBackgroundColor(Color.GREEN);
- this.getBackground().setAlpha(5 * (isRated - 3));
- } else if(isRated < 3 && isRated > 0) {
+ if(isRated > 1) {
+ if(rating <= 1) {
+ ratingBar.setVisibility(View.VISIBLE);
+ }
+
+ ratingBar.setNumStars(isRated);
+ ratingBar.setRating(isRated);
+ } else if(isRated <= 1) {
+ if(rating > 1) {
+ ratingBar.setVisibility(View.GONE);
+ }
+ }
+
+ // Still highlight red if a 1-star
+ if(isRated == 1) {
this.setBackgroundColor(Color.RED);
- // Use darker colors the lower the rating goes
- this.getBackground().setAlpha(10 * (3 - isRated));
- } else {
+ this.getBackground().setAlpha(20);
+ } else if(rating == 1) {
this.setBackgroundColor(0x00000000);
}
diff --git a/src/github/daneren2005/dsub/view/UpdateView.java b/src/github/daneren2005/dsub/view/UpdateView.java
index 5f34a765..c491fc6d 100644
--- a/src/github/daneren2005/dsub/view/UpdateView.java
+++ b/src/github/daneren2005/dsub/view/UpdateView.java
@@ -20,6 +20,7 @@ package github.daneren2005.dsub.view;
import android.content.Context;
import android.content.res.TypedArray;
+import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
@@ -29,6 +30,8 @@ import android.widget.AbsListView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.RatingBar;
+
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
@@ -48,6 +51,7 @@ public class UpdateView extends LinearLayout {
private static int activeActivities = 0;
protected Context context;
+ protected RatingBar ratingBar;
protected ImageButton starButton;
protected ImageView moreButton;
@@ -56,6 +60,8 @@ public class UpdateView extends LinearLayout {
protected boolean shaded = false;
protected boolean starred = false;
protected boolean isStarred = false;
+ protected int isRated = 0;
+ protected int rating = 0;
protected SilentBackgroundTask<Void> imageTask = null;
protected final boolean autoUpdate;
@@ -215,11 +221,17 @@ public class UpdateView extends LinearLayout {
public static MusicDirectory.Entry findEntry(MusicDirectory.Entry entry) {
for(UpdateView view: INSTANCES.keySet()) {
+ MusicDirectory.Entry check = null;
if(view instanceof SongView) {
- MusicDirectory.Entry check = ((SongView) view).getEntry();
- if(check != null && entry != check && check.getId().equals(entry.getId())) {
- return check;
- }
+ check = ((SongView) view).getEntry();
+ } else if(view instanceof AlbumCell) {
+ check = ((AlbumCell) view).getEntry();
+ } else if(view instanceof AlbumView) {
+ check = ((AlbumView) view).getEntry();
+ }
+
+ if(check != null && entry != check && check.getId().equals(entry.getId())) {
+ return check;
}
}
@@ -259,5 +271,16 @@ public class UpdateView extends LinearLayout {
}
}
}
+
+ if(ratingBar != null && isRated != rating) {
+ if(isRated > 0 && rating == 0) {
+ ratingBar.setVisibility(View.VISIBLE);
+ } else if(isRated == 0 && rating > 0) {
+ ratingBar.setVisibility(View.GONE);
+ }
+
+ ratingBar.setRating(isRated);
+ rating = isRated;
+ }
}
}