aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--subsonic-android/res/values/strings.xml6
-rw-r--r--subsonic-android/res/xml/settings.xml6
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/fragments/SubsonicFragment.java28
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java7
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java4
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java43
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java2
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java5
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/Constants.java2
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java13
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/util/Util.java31
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/view/PlaylistView.java6
-rw-r--r--subsonic-android/src/github/daneren2005/dsub/view/SongView.java8
13 files changed, 125 insertions, 36 deletions
diff --git a/subsonic-android/res/values/strings.xml b/subsonic-android/res/values/strings.xml
index 224247fb..545dcdac 100644
--- a/subsonic-android/res/values/strings.xml
+++ b/subsonic-android/res/values/strings.xml
@@ -75,6 +75,8 @@
<string name="playlist.updated_info">Updated playlist information for %s</string>
<string name="playlist.updated_info_error">Failed to update playlist information for %s</string>
<string name="playlist.overwrite">Overwrite existing playlist</string>
+ <string name="playlist.add_to">Add to Playlist</string>
+ <string name="playlist.create_new">Create New</string>
<string name="help.label">Help</string>
<string name="help.title">Welcome to DSub!</string>
@@ -122,6 +124,7 @@
<string name="offline.scrobbles_error">Failed to scrobble songs</string>
<string name="select_genre.empty">No genres found</string>
+ <string name="select_genre.blank">Blank</string>
<string name="select_playlist.empty">No saved playlists on server</string>
@@ -216,6 +219,8 @@
<string name="settings.theme_dark_fullscreen">Dark Fullscreen</string>
<string name="settings.theme_black_fullscreen">Black Fullscreen</string>
<string name="settings.theme_holo_fullscreen">Holo Fullscreen</string>
+ <string name="settings.track_title">Display Track #</string>
+ <string name="settings.track_summary">Display Track # in front of songs if one exists</string>
<string name="settings.network_title">Network</string>
<string name="settings.max_bitrate_wifi">Max Audio bitrate - Wi-Fi</string>
<string name="settings.max_bitrate_mobile">Max Audio bitrate - Mobile</string>
@@ -294,6 +299,7 @@
<string name="settings.video_transcode">Direct Transcode (Requires video -> mp4 or similar setup on Server)</string>
<string name="settings.video_flash">Flash (Requires Plugin)</string>
+ <string name="shuffle.title">Shuffle By</string>
<string name="shuffle.startYear">Start Year:</string>
<string name="shuffle.endYear">End Year:</string>
<string name="shuffle.genre">Genre:</string>
diff --git a/subsonic-android/res/xml/settings.xml b/subsonic-android/res/xml/settings.xml
index d3618ffa..af2b567a 100644
--- a/subsonic-android/res/xml/settings.xml
+++ b/subsonic-android/res/xml/settings.xml
@@ -23,6 +23,12 @@
android:entryValues="@array/themeValues"
android:entries="@array/themeNames"/>
+ <CheckBoxPreference
+ android:title="@string/settings.track_title"
+ android:summary="@string/settings.track_summary"
+ android:key="displayTrack"
+ android:defaultValue="false"/>
+
</PreferenceCategory>
<PreferenceCategory
diff --git a/subsonic-android/src/github/daneren2005/dsub/fragments/SubsonicFragment.java b/subsonic-android/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
index 77479424..100fcbc6 100644
--- a/subsonic-android/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
+++ b/subsonic-android/src/github/daneren2005/dsub/fragments/SubsonicFragment.java
@@ -403,6 +403,8 @@ public class SubsonicFragment extends SherlockFragment {
@Override
protected void done(final List<Genre> genres) {
List<String> names = new ArrayList<String>();
+ String blank = context.getResources().getString(R.string.select_genre_blank);
+ names.add(blank);
for(Genre genre: genres) {
names.add(genre.getName());
}
@@ -412,7 +414,11 @@ public class SubsonicFragment extends SherlockFragment {
builder.setTitle(R.string.shuffle_pick_genre)
.setItems(names.toArray(new CharSequence[names.size()]), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
- genreCombo.setText(finalNames.get(which));
+ if(which == 0) {
+ genreCombo.setText("");
+ } else {
+ genreCombo.setText(finalNames.get(which));
+ }
}
});
AlertDialog dialog = builder.create();
@@ -445,7 +451,7 @@ public class SubsonicFragment extends SherlockFragment {
genreCombo.setText(oldGenre);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle("Shuffle By")
+ builder.setTitle(R.string.shuffle_title)
.setView(dialogView)
.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
@Override
@@ -624,13 +630,14 @@ public class SubsonicFragment extends SherlockFragment {
@Override
protected void done(final List<Playlist> playlists) {
List<String> names = new ArrayList<String>();
- names.add("Create New");
+ String createNew = context.getResources().getString(R.string.playlist_create_new);
+ names.add(createNew);
for(Playlist playlist: playlists) {
names.add(playlist.getName());
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle("Add to Playlist")
+ builder.setTitle(R.string.playlist_add_to)
.setItems(names.toArray(new CharSequence[names.size()]), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
@@ -853,15 +860,10 @@ public class SubsonicFragment extends SherlockFragment {
}
protected void playVideo(MusicDirectory.Entry entry) {
- String videoPlayerType = Util.getVideoPlayerType(context);
if(entryExists(entry)) {
playExternalPlayer(entry);
} else {
- if("flash".equals(videoPlayerType)) {
- playWebView(entry);
- } else {
- streamExternalPlayer(entry, "raw".equals(videoPlayerType) ? "raw" : entry.getTranscodedSuffix());
- }
+ streamExternalPlayer(entry);
}
}
@@ -891,7 +893,11 @@ public class SubsonicFragment extends SherlockFragment {
}
protected void streamExternalPlayer(MusicDirectory.Entry entry) {
String videoPlayerType = Util.getVideoPlayerType(context);
- streamExternalPlayer(entry, "raw".equals(videoPlayerType) ? "raw" : entry.getTranscodedSuffix());
+ if("flash".equals(videoPlayerType)) {
+ playWebView(entry);
+ } else {
+ streamExternalPlayer(entry, "raw".equals(videoPlayerType) ? "raw" : entry.getTranscodedSuffix());
+ }
}
protected void streamExternalPlayer(MusicDirectory.Entry entry, String format) {
try {
diff --git a/subsonic-android/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java b/subsonic-android/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java
index 321b0f88..7215040c 100644
--- a/subsonic-android/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java
+++ b/subsonic-android/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java
@@ -186,7 +186,12 @@ public class DSubWidgetProvider extends AppWidgetProvider {
// Set the cover art
try {
- int size = context.getResources().getDrawable(R.drawable.appwidget_art_default).getIntrinsicHeight();
+ int size;
+ if(getLayout() != R.layout.appwidget4x1 && getLayout() != R.layout.appwidget4x2) {
+ size = context.getResources().getDrawable(R.drawable.unknown_album_large).getIntrinsicHeight();
+ } else {
+ size = context.getResources().getDrawable(R.drawable.appwidget_art_default).getIntrinsicHeight();
+ }
Bitmap bitmap = currentPlaying == null ? null : FileUtil.getAlbumArtBitmap(context, currentPlaying, size);
if (bitmap == null) {
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
index 664754b1..ba8ea1e4 100644
--- a/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
+++ b/subsonic-android/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
@@ -309,6 +309,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
DownloadFile downloadFile = new DownloadFile(this, song, save);
backgroundDownloadList.add(downloadFile);
}
+ revision++;
checkDownloads();
lifecycleSupport.serializeDownloadQueue();
@@ -1347,7 +1348,8 @@ public class DownloadServiceImpl extends Service implements DownloadService {
DownloadFile downloadFile = backgroundDownloadList.get(i);
if(downloadFile.isWorkDone() && (!downloadFile.shouldSave() || downloadFile.isSaved())) {
// Don't need to keep list like active song list
- backgroundDownloadList.remove(downloadFile);
+ backgroundDownloadList.remove(i);
+ revision++;
i--;
} else {
currentDownloading = downloadFile;
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java
index 1878fecf..0c7dba27 100644
--- a/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java
+++ b/subsonic-android/src/github/daneren2005/dsub/service/OfflineMusicService.java
@@ -342,21 +342,41 @@ public class OfflineMusicService extends RESTMusicService {
public List<Playlist> getPlaylists(boolean refresh, Context context, ProgressListener progressListener) throws Exception {
List<Playlist> playlists = new ArrayList<Playlist>();
File root = FileUtil.getPlaylistDirectory();
- for (File file : FileUtil.listFiles(root)) {
- if(FileUtil.isPlaylistFile(file)) {
- String id = file.getName();
- String filename = FileUtil.getBaseName(id);
- Playlist playlist = new Playlist(id, filename);
- playlists.add(playlist);
+ String lastServer = null;
+ boolean removeServer = true;
+ for (File folder : FileUtil.listFiles(root)) {
+ if(folder.isDirectory()) {
+ String server = folder.getName();
+ for(File file: FileUtil.listFiles(folder)) {
+ if(FileUtil.isPlaylistFile(file)) {
+ String id = file.getName();
+ String filename = server + ": " + FileUtil.getBaseName(id);
+ Playlist playlist = new Playlist(server, filename);
+ playlists.add(playlist);
+ }
+ }
+
+ if(!server.equals(lastServer)) {
+ if(lastServer != null) {
+ removeServer = false;
+ }
+ lastServer = server;
+ }
} else {
// Delete legacy playlist files
try {
- file.delete();
+ folder.delete();
} catch(Exception e) {
- Log.w(TAG, "Failed to delete old playlist file: " + file.getName());
+ Log.w(TAG, "Failed to delete old playlist file: " + folder.getName());
}
}
}
+
+ if(removeServer) {
+ for(Playlist playlist: playlists) {
+ playlist.setName(playlist.getName().substring(playlist.getId().length() + 2));
+ }
+ }
return playlists;
}
@@ -370,7 +390,12 @@ public class OfflineMusicService extends RESTMusicService {
Reader reader = null;
BufferedReader buffer = null;
try {
- File playlistFile = FileUtil.getPlaylistFile(name);
+ int firstIndex = name.indexOf(id);
+ if(firstIndex != -1) {
+ name = name.substring(id.length() + 2);
+ }
+
+ File playlistFile = FileUtil.getPlaylistFile(id, name);
reader = new FileReader(playlistFile);
buffer = new BufferedReader(reader);
diff --git a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java
index 249efc10..0edd1a6d 100644
--- a/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/subsonic-android/src/github/daneren2005/dsub/service/RESTMusicService.java
@@ -332,7 +332,7 @@ public class RESTMusicService implements MusicService {
try {
MusicDirectory playlist = new PlaylistParser(context).parse(reader, progressListener);
- File playlistFile = FileUtil.getPlaylistFile(name);
+ File playlistFile = FileUtil.getPlaylistFile(Util.getServerName(context), name);
FileWriter fw = new FileWriter(playlistFile);
BufferedWriter bw = new BufferedWriter(fw);
try {
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java b/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java
index 44de369f..62204c76 100644
--- a/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java
+++ b/subsonic-android/src/github/daneren2005/dsub/util/CacheCleaner.java
@@ -219,10 +219,11 @@ public class CacheCleaner {
@Override
protected Void doInBackground(List<Playlist>... params) {
try {
- SortedSet<File> playlistFiles = FileUtil.listFiles(FileUtil.getPlaylistDirectory());
+ String server = Util.getServerName(context);
+ SortedSet<File> playlistFiles = FileUtil.listFiles(FileUtil.getPlaylistDirectory(server));
List<Playlist> playlists = params[0];
for (Playlist playlist : playlists) {
- playlistFiles.remove(FileUtil.getPlaylistFile(playlist.getName()));
+ playlistFiles.remove(FileUtil.getPlaylistFile(server, playlist.getName()));
}
for(File playlist : playlistFiles) {
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/Constants.java b/subsonic-android/src/github/daneren2005/dsub/util/Constants.java
index 5714b1f1..a2f43dcd 100644
--- a/subsonic-android/src/github/daneren2005/dsub/util/Constants.java
+++ b/subsonic-android/src/github/daneren2005/dsub/util/Constants.java
@@ -68,6 +68,7 @@ public final class Constants {
public static final String PREFERENCES_KEY_SERVER_INSTANCE = "serverInstanceId";
public static final String PREFERENCES_KEY_SERVER_NAME = "serverName";
public static final String PREFERENCES_KEY_SERVER_URL = "serverUrl";
+ public static final String PREFERENCES_KEY_SERVER_VERSION = "serverVersion";
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";
@@ -75,6 +76,7 @@ public final class Constants {
public static final String PREFERENCES_KEY_PASSWORD = "password";
public static final String PREFERENCES_KEY_INSTALL_TIME = "installTime";
public static final String PREFERENCES_KEY_THEME = "theme";
+ public static final String PREFERENCES_KEY_DISPLAY_TRACK = "displayTrack";
public static final String PREFERENCES_KEY_MAX_BITRATE_WIFI = "maxBitrateWifi";
public static final String PREFERENCES_KEY_MAX_BITRATE_MOBILE = "maxBitrateMobile";
public static final String PREFERENCES_KEY_MAX_VIDEO_BITRATE_WIFI = "maxVideoBitrateWifi";
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java b/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java
index 7ead874c..e63b3d76 100644
--- a/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java
+++ b/subsonic-android/src/github/daneren2005/dsub/util/FileUtil.java
@@ -93,19 +93,20 @@ public class FileUtil {
return new File(dir, fileName.toString());
}
- public static File getPlaylistFile(String name) {
- File playlistDir = getPlaylistDirectory();
+ public static File getPlaylistFile(String server, String name) {
+ File playlistDir = getPlaylistDirectory(server);
return new File(playlistDir, fileSystemSafe(name) + ".m3u");
}
- public static File getOldPlaylistFile(String name) {
- File playlistDir = getPlaylistDirectory();
- return new File(playlistDir, name);
- }
public static File getPlaylistDirectory() {
File playlistDir = new File(getSubsonicDirectory(), "playlists");
ensureDirectoryExistsAndIsReadWritable(playlistDir);
return playlistDir;
}
+ public static File getPlaylistDirectory(String server) {
+ File playlistDir = new File(getPlaylistDirectory(), server);
+ ensureDirectoryExistsAndIsReadWritable(playlistDir);
+ return playlistDir;
+ }
public static File getAlbumArtFile(Context context, MusicDirectory.Entry entry) {
File albumDir = getAlbumDirectory(context, entry);
diff --git a/subsonic-android/src/github/daneren2005/dsub/util/Util.java b/subsonic-android/src/github/daneren2005/dsub/util/Util.java
index 25e7c690..3ad4c623 100644
--- a/subsonic-android/src/github/daneren2005/dsub/util/Util.java
+++ b/subsonic-android/src/github/daneren2005/dsub/util/Util.java
@@ -215,6 +215,11 @@ public final class Util {
}
}
+ public static String getServerName(Context context) {
+ SharedPreferences prefs = getPreferences(context);
+ int instance = prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1);
+ return prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, null);
+ }
public static String getServerName(Context context, int instance) {
SharedPreferences prefs = getPreferences(context);
return prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, null);
@@ -229,11 +234,28 @@ public final class Util {
}
public static void setServerRestVersion(Context context, Version version) {
- SERVER_REST_VERSIONS.put(getActiveServer(context), version);
+ int instance = getActiveServer(context);
+ Version current = SERVER_REST_VERSIONS.get(instance);
+ if(current != version) {
+ SERVER_REST_VERSIONS.put(instance, version);
+ SharedPreferences.Editor editor = getPreferences(context).edit();
+ editor.putString(Constants.PREFERENCES_KEY_SERVER_VERSION + instance, version.getVersion());
+ editor.commit();
+ }
}
public static Version getServerRestVersion(Context context) {
- return SERVER_REST_VERSIONS.get(getActiveServer(context));
+ int instance = getActiveServer(context);
+ Version version = SERVER_REST_VERSIONS.get(instance);
+ if(version == null) {
+ SharedPreferences prefs = getPreferences(context);
+ String versionString = prefs.getString(Constants.PREFERENCES_KEY_SERVER_VERSION + instance, null);
+ if(versionString != null) {
+ version = new Version(versionString);
+ SERVER_REST_VERSIONS.put(instance, version);
+ }
+ }
+ return version;
}
public static void setSelectedMusicFolderId(Context context, String musicFolderId) {
@@ -254,6 +276,11 @@ public final class Util {
SharedPreferences prefs = getPreferences(context);
return prefs.getString(Constants.PREFERENCES_KEY_THEME, null);
}
+
+ public static boolean getDisplayTrack(Context context) {
+ SharedPreferences prefs = getPreferences(context);
+ return prefs.getBoolean(Constants.PREFERENCES_KEY_DISPLAY_TRACK, false);
+ }
public static int getMaxBitrate(Context context) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
diff --git a/subsonic-android/src/github/daneren2005/dsub/view/PlaylistView.java b/subsonic-android/src/github/daneren2005/dsub/view/PlaylistView.java
index effd5a98..876e0691 100644
--- a/subsonic-android/src/github/daneren2005/dsub/view/PlaylistView.java
+++ b/subsonic-android/src/github/daneren2005/dsub/view/PlaylistView.java
@@ -37,6 +37,7 @@ import java.io.File;
public class PlaylistView extends UpdateView {
private static final String TAG = PlaylistView.class.getSimpleName();
+ private Context context;
private Playlist playlist;
private TextView titleView;
@@ -44,6 +45,7 @@ public class PlaylistView extends UpdateView {
public PlaylistView(Context context) {
super(context);
+ this.context = context;
LayoutInflater.from(context).inflate(R.layout.playlist_list_item, this, true);
titleView = (TextView) findViewById(R.id.playlist_name);
@@ -64,8 +66,8 @@ public class PlaylistView extends UpdateView {
@Override
protected void update() {
- File file = FileUtil.getPlaylistFile(playlist.getName());
- if(file.exists()) {
+ File file = FileUtil.getPlaylistFile(Util.getServerName(context), playlist.getName());
+ if(file.exists() || Util.isOffline(context)) {
moreButton.setImageResource(R.drawable.list_item_more_shaded);
} else {
moreButton.setImageResource(R.drawable.list_item_more);
diff --git a/subsonic-android/src/github/daneren2005/dsub/view/SongView.java b/subsonic-android/src/github/daneren2005/dsub/view/SongView.java
index 40bedad6..b4ec2f19 100644
--- a/subsonic-android/src/github/daneren2005/dsub/view/SongView.java
+++ b/subsonic-android/src/github/daneren2005/dsub/view/SongView.java
@@ -93,8 +93,14 @@ public class SongView extends UpdateView implements Checkable {
} else {
artist.append(String.format(getContext().getString(R.string.song_details_all), bitRate == null ? "" : bitRate, fileFormat));
}
+
+ String title = song.getTitle();
+ Integer track = song.getTrack();
+ if(track != null && Util.getDisplayTrack(context)) {
+ title = String.format("%02d", track) + " " + title;
+ }
- titleTextView.setText(song.getTitle());
+ titleTextView.setText(title);
artistTextView.setText(artist);
durationTextView.setText(Util.formatDuration(song.getDuration()));
checkedTextView.setVisibility(checkable && !song.isVideo() ? View.VISIBLE : View.GONE);