diff options
Diffstat (limited to 'src')
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;
+ }
}
}
|